/** X3DOM Runtime, http://www.x3dom.org */
if(!Array.forEach){Array.forEach=function(array,fun,thisp){var len=array.length;for(var i=0;i<len;i++){if(i in array){fun.call(thisp,array[i],i,array);}}};}
if(!Array.map){Array.map=function(array,fun,thisp){var len=array.length;var res=[];for(var i=0;i<len;i++){if(i in array){res[i]=fun.call(thisp,array[i],i,array);}}
return res;};}
if(!Array.filter){Array.filter=function(array,fun,thisp){var len=array.length;var res=[];for(var i=0;i<len;i++){if(i in array){var val=array[i];if(fun.call(thisp,val,i,array)){res.push(val);}}}
return res;};}
var x3dom={canvases:[]};x3dom.x3dNS='http://www.web3d.org/specifications/x3d-namespace';x3dom.x3dextNS='http://philip.html5.org/x3d/ext';x3dom.xsltNS='http://www.w3.org/1999/XSL/x3dom.Transform';x3dom.xhtmlNS='http://www.w3.org/1999/xhtml';x3dom.nodeTypes={};x3dom.nodeTypesLC={};x3dom.components={};x3dom.geoCache=[];x3dom.caps={PLATFORM:navigator.platform,AGENT:navigator.userAgent};x3dom.registerNodeType=function(nodeTypeName,componentName,nodeDef){x3dom.debug.logInfo("Registering nodetype ["+nodeTypeName+"] in component ["+componentName+"]");if(x3dom.components[componentName]===undefined){x3dom.debug.logInfo("Adding new component ["+componentName+"]");x3dom.components[componentName]={};}
else{x3dom.debug.logInfo("Using component ["+componentName+"]");}
nodeDef._typeName=nodeTypeName;nodeDef._compName=componentName;x3dom.components[componentName][nodeTypeName]=nodeDef;x3dom.nodeTypes[nodeTypeName]=nodeDef;x3dom.nodeTypesLC[nodeTypeName.toLowerCase()]=nodeDef;};x3dom.isX3DElement=function(node){return(node.nodeType===Node.ELEMENT_NODE&&node.localName&&(x3dom.nodeTypes[node.localName]||x3dom.nodeTypesLC[node.localName.toLowerCase()]||node.localName.toLowerCase()==="x3d"||node.localName.toLowerCase()==="websg"||node.localName.toLowerCase()==="scene"||node.localName.toLowerCase()==="route"));};x3dom.extend=function(f){function g(){}
g.prototype=f.prototype||f;return new g();};x3dom.getStyle=function(oElm,strCssRule){var strValue;if(window&&window.getComputedStyle&&window.getComputedStyle(oElm,"")){strValue=window.getComputedStyle(oElm,"")[strCssRule];}
else if(oElm.currentStyle){strCssRule=strCssRule.replace(/\-(\w)/g,function(strMatch,p1){return p1.toUpperCase();});strValue=oElm.currentStyle[strCssRule];}
return strValue;};function defineClass(parent,ctor,methods){function inheritance(){}
if(parent){inheritance.prototype=parent.prototype;ctor.prototype=new inheritance();ctor.prototype.constructor=ctor;ctor.superClass=parent;}
if(methods){for(var m in methods){ctor.prototype[m]=methods[m];}}
return ctor;}
x3dom.isa=function(object,clazz){if(!object){return false;}
if(object.constructor===clazz){return true;}
if(object.constructor.superClass===undefined){return false;}
function f(c){if(c===clazz){return true;}
if(c.prototype&&c.prototype.constructor&&c.prototype.constructor.superClass){return f(c.prototype.constructor.superClass);}
return false;}
return f(object.constructor.superClass);};x3dom.getGlobal=function(){return(function(){return this;}).call(null);};x3dom.isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n);};x3dom.loadJS=function(src,path_prefix,blocking){var blocking=(blocking===false)?blocking:true;if(blocking){var req;var url=(path_prefix)?path_prefix.trim()+src:src;if(window.XMLHttpRequest){req=new XMLHttpRequest();}else{req=new ActiveXObject("Microsoft.XMLHTTP");}
if(req){req.open("GET",url,false);req.send(null);eval(req.responseText);}}else{var head=document.getElementsByTagName('HEAD').item(0);var script=document.createElement("script");var loadpath=(path_prefix)?path_prefix.trim()+src:src;if(head){x3dom.debug.logError("Trying to load external JS file: "+loadpath);script.type="text/javascript";script.src=loadpath;head.appendChild(script,head.firstChild);}else{alert("No document object found. Can't load components");}}};function array_to_object(a){var o={};for(var i=0;i<a.length;i++){o[a[i]]='';}
return o;}
window.requestAnimFrame=(function(){return window.requestAnimationFrame||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||window.oRequestAnimationFrame||window.msRequestAnimationFrame||function(callback,element){window.setTimeout(callback,1000/60);};})();x3dom.debug={INFO:"INFO",WARNING:"WARNING",ERROR:"ERROR",EXCEPTION:"EXCEPTION",isActive:false,isFirebugAvailable:false,isSetup:false,isAppend:false,numLinesLogged:0,maxLinesToLog:1000,logContainer:null,setup:function(){if(x3dom.debug.isSetup){return;}
try{if(window.console.firebug!==undefined){x3dom.debug.isFirebugAvailable=true;}}
catch(err){x3dom.debug.isFirebugAvailable=false;}
x3dom.debug.setupLogContainer();x3dom.debug.isSetup=true;},activate:function(visible){x3dom.debug.isActive=true;x3dom.debug.logContainer.style.display=(visible)?"block":"none";if(!x3dom.debug.isAppend){if(navigator.appName=="Microsoft Internet Explorer"){x3dom.debug.logContainer.style.marginLeft="8px";document.documentElement.appendChild(x3dom.debug.logContainer);}else{document.body.appendChild(x3dom.debug.logContainer);}
x3dom.debug.isAppend=true;}},setupLogContainer:function(){x3dom.debug.logContainer=document.createElement("div");x3dom.debug.logContainer.id="x3dom_logdiv";x3dom.debug.logContainer.style.border="2px solid olivedrab";x3dom.debug.logContainer.style.height="200px";x3dom.debug.logContainer.style.padding="4px";x3dom.debug.logContainer.style.overflow="auto";x3dom.debug.logContainer.style.whiteSpace="pre-wrap";x3dom.debug.logContainer.style.fontFamily="sans-serif";x3dom.debug.logContainer.style.fontSize="x-small";x3dom.debug.logContainer.style.color="#00ff00";x3dom.debug.logContainer.style.backgroundColor="black";x3dom.debug.logContainer.style.clear="both";x3dom.debug.logContainer.style.marginRight="10px";},doLog:function(msg,logType){if(!x3dom.debug.isActive){return;}
if(x3dom.debug.numLinesLogged===x3dom.debug.maxLinesToLog){msg="Maximum number of log lines (="+x3dom.debug.maxLinesToLog+") reached. Deactivating logging...";}
if(x3dom.debug.numLinesLogged>x3dom.debug.maxLinesToLog){return;}
var node=document.createElement("p");node.style.margin=0;switch(logType){case x3dom.debug.INFO:node.style.color="#00ff00";break;case x3dom.debug.WARNING:node.style.color="#cd853f";break;case x3dom.debug.ERROR:node.style.color="#ff4500";break;case x3dom.debug.EXCEPTION:node.style.color="#ffff00";break;default:node.style.color="#00ff00";break;}
try{node.innerHTML=logType+": "+msg;x3dom.debug.logContainer.insertBefore(node,x3dom.debug.logContainer.firstChild);}catch(err){if(window.console.firebug!==undefined){window.console.warn(msg);}}
if(x3dom.debug.isFirebugAvailable){switch(logType){case x3dom.debug.INFO:window.console.info(msg);break;case x3dom.debug.WARNING:window.console.warn(msg);break;case x3dom.debug.ERROR:window.console.error(msg);break;case x3dom.debug.EXCEPTION:window.console.debug(msg);break;default:break;}}
x3dom.debug.numLinesLogged++;},logInfo:function(msg){x3dom.debug.doLog(msg,x3dom.debug.INFO);},logWarning:function(msg){x3dom.debug.doLog(msg,x3dom.debug.WARNING);},logError:function(msg){x3dom.debug.doLog(msg,x3dom.debug.ERROR);},logException:function(msg){x3dom.debug.doLog(msg,x3dom.debug.EXCEPTION);},assert:function(c,msg){if(!c){x3dom.debug.doLog("Assertion failed in "+
x3dom.debug.assert.caller.name+': '+
msg,x3dom.debug.ERROR);}},typeOf:function(obj){var type=typeof obj;return type==="object"&&!obj?"null":type;},exists:function(obj,name,type){type=type||"function";return(obj?this.typeOf(obj[name]):"null")===type;},dumpFields:function(node){var str="";for(var fName in node){str+=(fName+", ");}
x3dom.debug.logInfo(str+'\n');}};x3dom.debug.setup();x3dom.ImageLoadManager={heap:[],complete:false,activeDownloads:0,push:function(tex){if(x3dom.caps.BACKEND=='webgl'){if(tex._vf.url[0]!=undefined){x3dom.debug.logInfo("[ImageLoadManager] Push image to queue: URL = "+tex._vf.url[0]+" | Priority = "+tex._vf.priority);x3dom.ImageLoadManager.heapUp(x3dom.ImageLoadManager.heap.push({priority:tex._vf.priority,image:tex._image,url:tex._vf.url[0]})-1);if(x3dom.ImageLoadManager.complete){x3dom.ImageLoadManager.complete=false;x3dom.ImageLoadManager.load();}}}},pop:function(){if(x3dom.ImageLoadManager.isEmpty()){}else{var result=x3dom.ImageLoadManager.heap[0];var tmp=x3dom.ImageLoadManager.heap.pop();if(x3dom.ImageLoadManager.heap.length>0){x3dom.ImageLoadManager.heap[0]=tmp;x3dom.ImageLoadManager.heapDown(0);}
return result;}},load:function(){if(x3dom.caps.BACKEND=='webgl'){x3dom.debug.logInfo("[ImageLoadManager] Start loading...");while(!x3dom.ImageLoadManager.isEmpty()){var item=x3dom.ImageLoadManager.pop();item.image.crossOrigin='';item.image.src=item.url;item.image.onload=x3dom.ImageLoadManager.onLoadFnc;x3dom.ImageLoadManager.activeDownloads++;}
x3dom.ImageLoadManager.complete=true;}},onLoadFnc:function(evt){var event=document.createEvent("HTMLEvents");event.initEvent('ImageLoadManager_Load',true,true);this.dispatchEvent(event);},getLeftChildIndex:function(nodeIndex){return parseInt(2*nodeIndex+1);},getRightChildIndex:function(nodeIndex){return parseInt(2*nodeIndex+2);},getParentIndex:function(nodeIndex){return parseInt((nodeIndex-1)/2);},heapUp:function(nodeIndex){var parentIndex,tmp;if(nodeIndex!=0){parentIndex=x3dom.ImageLoadManager.getParentIndex(nodeIndex);if(x3dom.ImageLoadManager.heap[parentIndex].priority>x3dom.ImageLoadManager.heap[nodeIndex].priority){tmp=x3dom.ImageLoadManager.heap[parentIndex];x3dom.ImageLoadManager.heap[parentIndex]=x3dom.ImageLoadManager.heap[nodeIndex];x3dom.ImageLoadManager.heap[nodeIndex]=tmp;x3dom.ImageLoadManager.heapUp(parentIndex);}}},heapDown:function(nodeIndex){var leftChildIndex,rightChildIndex,minIndex,tmp;leftChildIndex=x3dom.ImageLoadManager.getLeftChildIndex(nodeIndex);rightChildIndex=x3dom.ImageLoadManager.getRightChildIndex(nodeIndex);if(rightChildIndex>=x3dom.ImageLoadManager.heap.length){if(leftChildIndex>=x3dom.ImageLoadManager.heap.length)
return;else
minIndex=leftChildIndex;}else{if(x3dom.ImageLoadManager.heap[leftChildIndex].priority<=x3dom.ImageLoadManager.heap[rightChildIndex].priority)
minIndex=leftChildIndex;else
minIndex=rightChildIndex;}
if(x3dom.ImageLoadManager.heap[nodeIndex].priority>x3dom.ImageLoadManager.heap[minIndex].priority){tmp=x3dom.ImageLoadManager.heap[minIndex];x3dom.ImageLoadManager.heap[minIndex]=x3dom.ImageLoadManager.heap[nodeIndex];x3dom.ImageLoadManager.heap[nodeIndex]=tmp;x3dom.ImageLoadManager.heapDown(minIndex);}},isEmpty:function(){return(x3dom.ImageLoadManager.heap.length==0);},toString:function(){var string="ImageLoadManager("+x3dom.ImageLoadManager.heap.length+") [";for(var i=0;i<x3dom.ImageLoadManager.heap.length;i++){if(i!=0)string+=", ";string+=x3dom.ImageLoadManager.heap[i].priority+" - "+x3dom.ImageLoadManager.heap[i].url;}
string+="]";return string;},length:function(){return x3dom.ImageLoadManager.heap.length;}};x3dom.Properties=function(){this.properties={};};x3dom.Properties.prototype.setProperty=function(name,value){x3dom.debug.logInfo("Properties: Setting property '"+name+"' to value '"+value+"'");this.properties[name]=value;};x3dom.Properties.prototype.getProperty=function(name,def){if(this.properties[name]){return this.properties[name]}else{return def;}};x3dom.Properties.prototype.merge=function(other){for(var attrname in other.properties){this.properties[attrname]=other.properties[attrname];}};x3dom.Properties.prototype.toString=function(){var str="";for(var name in this.properties){str+="Name: "+name+" Value: "+this.properties[name]+"\n";}
return str;};x3dom.DoublyLinkedList=function(){this.length=0;this.first=null;this.last=null;};x3dom.DoublyLinkedList.ListNode=function(point,point_index,normals,colors,texCoords){this.point=point;this.point_index=point_index;this.normals=normals;this.colors=colors;this.texCoords=texCoords;this.next=null;this.prev=null;};x3dom.DoublyLinkedList.prototype.appendNode=function(node){if(this.first===null){node.prev=node;node.next=node;this.first=node;this.last=node;}else{node.prev=this.last;node.next=this.first;this.first.prev=node;this.last.next=node;this.last=node;}
this.length++;};x3dom.DoublyLinkedList.prototype.insertAfterNode=function(node,newNode){newNode.prev=node;newNode.next=node.next;node.next.prev=newNode;node.next=newNode;if(newNode.prev==this.last){this.last=newNode;}
this.length++;};x3dom.DoublyLinkedList.prototype.deleteNode=function(node){if(this.length>1){node.prev.next=node.next;node.next.prev=node.prev;if(node==this.first){this.first=node.next;}
if(node==this.last){this.last=node.prev;}}else{this.first=null;this.last=null;}
node.prev=null;node.next=null;this.length--;};x3dom.DoublyLinkedList.prototype.getNode=function(index){var node=null;if(index>this.length){return node;}
for(var i=0;i<this.length;i++){if(i==0){node=this.first;}else{node=node.next;}
if(i==index){return node;}}};x3dom.DoublyLinkedList.prototype.invert=function(){var node=null;var tmp=null;node=this.first;for(var i=0;i<this.length;i++){tmp=node.prev;node.prev=node.next;node.next=tmp;node=node.prev;}
tmp=this.first;this.first=this.last;this.last=tmp;};x3dom.EarClipping={reversePointDirection:function(linklist,plane){var l,k;var count=0;var z;var nodei,nodel,nodek;if(linklist.length<3){return false;}
for(var i=0;i<linklist.length;i++){l=(i+1)%linklist.length;k=(i+2)%linklist.length;nodei=linklist.getNode(i);nodel=linklist.getNode(l);nodek=linklist.getNode(k);if(plane=='YZ'){z=(nodel.point.y-nodei.point.y)*(nodek.point.z-nodel.point.z);z-=(nodel.point.z-nodei.point.z)*(nodek.point.y-nodel.point.y);}else if(plane=='XZ'){z=(nodel.point.z-nodei.point.z)*(nodek.point.x-nodel.point.x);z-=(nodel.point.x-nodei.point.x)*(nodek.point.z-nodel.point.z);}else{z=(nodel.point.x-nodei.point.x)*(nodek.point.y-nodel.point.y);z-=(nodel.point.y-nodei.point.y)*(nodek.point.x-nodel.point.x);}
if(z<0){count--;}else if(z>0){count++;}}
if(count<0){linklist.invert();return true;}
return false;},getIndexes:function(linklist){var node=linklist.first.next;var plane=this.identifyPlane(node.prev.point,node.point,node.next.point);var invers=this.reversePointDirection(linklist,plane);var indexes=[];node=linklist.first.next;var next=null;var count=0;var isEar=true;while(linklist.length>=3&&count<15){next=node.next;for(var i=0;i<linklist.length;i++){if(this.isNotEar(linklist.getNode(i).point,node.prev.point,node.point,node.next.point,plane)){isEar=false;}}
if(isEar){if(this.isKonvex(node.prev.point,node.point,node.next.point,plane)){indexes.push(node.prev.point_index,node.point_index,node.next.point_index);linklist.deleteNode(node);}else{count++;}}
node=next;isEar=true;}
if(invers){return indexes.reverse();}else{return indexes;}},getMultiIndexes:function(linklist){var node=linklist.first.next;var plane=this.identifyPlane(node.prev.point,node.point,node.next.point);var invers=this.reversePointDirection(linklist,plane);var data=new Object();data.indices=[];data.point=[];data.normals=[];data.colors=[];data.texCoords=[];node=linklist.first.next;var next=null;var count=0;var isEar=true;while(linklist.length>=3&&count<15){next=node.next;for(var i=0;i<linklist.length;i++){if(this.isNotEar(linklist.getNode(i).point,node.prev.point,node.point,node.next.point,plane)){isEar=false;}}
if(isEar){if(this.isKonvex(node.prev.point,node.point,node.next.point,plane)){data.indices.push(node.prev.point_index,node.point_index,node.next.point_index);data.point.push(node.prev.point,node.point,node.next.point);if(node.normals){data.normals.push(node.prev.normals,node.normals,node.next.normals);}
if(node.colors){data.colors.push(node.prev.colors,node.colors,node.next.colors);}
if(node.texCoords){data.texCoords.push(node.prev.texCoords,node.texCoords,node.next.texCoords);}
linklist.deleteNode(node);}else{count++;}}
node=next;isEar=true;}
if(invers){data.indices=data.indices.reverse();data.point=data.point.reverse();data.normals=data.normals.reverse();data.colors=data.colors.reverse();data.texCoords=data.texCoords.reverse();return data;}else{return data;}},isNotEar:function(ap1,tp1,tp2,tp3,plane){var b0,b1,b2,b3;var ap1a,ap1b,tp1a,tp1b,tp2a,tp2b,tp3a,tp3b;if(plane=='YZ'){ap1a=ap1.y,ap1b=ap1.z;tp1a=tp1.y,tp1b=tp1.z;tp2a=tp2.y,tp2b=tp2.z;tp3a=tp3.y,tp3b=tp3.z;}else if(plane=='XZ'){ap1a=ap1.z,ap1b=ap1.x;tp1a=tp1.z,tp1b=tp1.x;tp2a=tp2.z,tp2b=tp2.x;tp3a=tp3.z,tp3b=tp3.x;}else{ap1a=ap1.x,ap1b=ap1.y;tp1a=tp1.x,tp1b=tp1.y;tp2a=tp2.x,tp2b=tp2.y;tp3a=tp3.x,tp3b=tp3.y;}
b0=((tp2a-tp1a)*(tp3b-tp1b)-(tp3a-tp1a)*(tp2b-tp1b));if(b0!=0){b1=(((tp2a-ap1a)*(tp3b-ap1b)-(tp3a-ap1a)*(tp2b-ap1b))/b0);b2=(((tp3a-ap1a)*(tp1b-ap1b)-(tp1a-ap1a)*(tp3b-ap1b))/b0);b3=1-b1-b2;return((b1>0)&&(b2>0)&&(b3>0));}
else{return false;}},isKonvex:function(p,p1,p2,plane){var pa,pb,p1a,p1b,p2a,p2b;if(plane=='YZ'){pa=p.y,pb=p.z;p1a=p1.y,p1b=p1.z;p2a=p2.y,p2b=p2.z;}else if(plane=='XZ'){pa=p.z,pb=p.x;p1a=p1.z,p1b=p1.x;p2a=p2.z,p2b=p2.x;}else{pa=p.x,pb=p.y;p1a=p1.x,p1b=p1.y;p2a=p2.x,p2b=p2.y;}
var l=((p1a-pa)*(p2b-pb)-(p1b-pb)*(p2a-pa));if(l<0){return false;}else{return true;}},identifyPlane:function(p1,p2,p3){var v1x,v1y,v1z;var v2x,v2y,v2z;var v3x,v3y,v3z;v1x=p2.x-p1.x,v1y=p2.y-p1.y,v1z=p2.z-p1.z;v2x=p3.x-p1.x,v2y=p3.y-p1.y,v2z=p3.z-p1.z;v3x=v1y*v2z-v1z*v2y;v3y=v1z*v2x-v1x*v2z;v3z=v1x*v2y-v1y*v2x;var angle=Math.max(Math.abs(v3x),Math.abs(v3y),Math.abs(v3z));if(angle==Math.abs(v3x)){return'YZ';}else if(angle==Math.abs(v3y)){return'XZ';}else if(angle==Math.abs(v3z)){return'XY';}else{return'fehler';}}};x3dom.X3DCanvas=function(x3dElem,canvasIdx){var that=this;this.canvasIdx=canvasIdx;this.initContext=function(canvas){x3dom.debug.logInfo("Initializing X3DCanvas for ["+canvas.id+"]");var gl=x3dom.gfx_webgl(canvas);if(!gl){x3dom.debug.logError("No 3D context found...");this.x3dElem.removeChild(canvas);return null;}
return gl;};this.initFlashContext=function(object){x3dom.debug.logInfo("Initializing X3DObject for ["+object.id+"]");var gl=x3dom.gfx_flash(object);return gl;};this.appendParam=function(node,name,value){var param=document.createElement('param');param.setAttribute('name',name);param.setAttribute('value',value);node.appendChild(param);};this.detectFlash=function(required,max)
{var required_version=required;var max_version=max;var available_version=0;if(typeof(navigator.plugins["Shockwave Flash"])=="object")
{var description=navigator.plugins["Shockwave Flash"].description;available_version=description.substr(16,(description.indexOf(".",16)-16));}
else if(typeof(ActiveXObject)=="function"){for(var i=10;i<(max_version+1);i++){try{if(typeof(new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+i))=="object"){available_version=i+1;}}
catch(error){}}}
return[available_version,required_version];};this.createInitFailedDiv=function(x3dElem){var div=document.createElement('div');div.style.width=x3dElem.getAttribute("width");;div.style.height=x3dElem.getAttribute("height");;div.style.backgroundColor="#C00";div.style.color="#FFF";div.style.fontSize="20px";div.style.fontWidth="bold";div.style.padding="10px 10px 10px 10px";div.style.display="inline-block";div.style.fontFamily="Arial";div.style.textAlign="center";div.appendChild(document.createTextNode('Your Browser does not support X3DOM'));div.appendChild(document.createElement('br'));div.appendChild(document.createTextNode('Read more about X3DOM Browser support on:'));div.appendChild(document.createElement('br'));var link=document.createElement('a');link.setAttribute('href','http://www.x3dom.org/?page_id=9');link.appendChild(document.createTextNode('X3DOM | Browser Support'));div.appendChild(link);x3dElem.appendChild(div);x3dom.debug.logError("Your Browser does not support X3DOM!");}
this.createFlashObject=function(x3dElem){var result=this.detectFlash(11,11);if(!result[0]||result[0]<result[1]){return null;}else{x3dom.debug.logInfo("Creating FlashObject for (X)3D element...");var id=x3dElem.getAttribute("id");if(id!==null){id="x3dom-"+id+"-object";}else{var index=new Date().getTime();id="x3dom-"+index+"-object";}
var swf_path=x3dElem.getAttribute("swfpath");if(swf_path===null){swf_path="x3dom.swf";}
var width=x3dElem.getAttribute("width");if(width==null){width=550;}else{var idx=width.indexOf("px");if(idx!=-1){width=width.substr(0,idx);}}
var height=x3dElem.getAttribute("height");if(height==null){height=400;}else{var idx=height.indexOf("px");if(idx!=-1){height=height.substr(0,idx);}}
var obj=document.createElement('object');obj.setAttribute('width',width);obj.setAttribute('height',height);obj.setAttribute('id',id);this.appendParam(obj,'menu','false');this.appendParam(obj,'quality','high');this.appendParam(obj,'wmode','gpu');this.appendParam(obj,'allowScriptAccess','always');this.appendParam(obj,'flashvars','width='+width+'&height='+height+'&canvasIdx='+this.canvasIdx);this.appendParam(obj,'movie',swf_path);x3dElem.appendChild(obj);if(navigator.appName=="Microsoft Internet Explorer")
obj.setAttribute('classid','clsid:d27cdb6e-ae6d-11cf-96b8-444553540000');else{obj.setAttribute('type','application/x-shockwave-flash');obj.setAttribute('data',swf_path);}
return obj;}};this.createHTMLCanvas=function(x3dElem)
{x3dom.debug.logInfo("Creating canvas for (X)3D element...");var canvas=document.createElement('canvas');canvas.setAttribute("class","x3dom-canvas");var userStyle=x3dElem.getAttribute("style");if(userStyle){x3dom.debug.logInfo("Inline X3D styles detected");}
var evtArr=["onmousedown","onmousemove","onmouseout","onmouseover","onmouseup","onclick","ondblclick","onkeydown","onkeypress","onkeyup","ontouchstart","ontouchmove","ontouchend","ontouchcancel","ontouchleave","ontouchenter","ongesturestart","ongesturechange","ongestureend","MozTouchDown","MozTouchMove","MozTouchUp"];for(var i=0;i<evtArr.length;i++)
{var evtName=evtArr[i];var userEvt=x3dElem.getAttribute(evtName);if(userEvt){x3dom.debug.logInfo(evtName+", "+userEvt);canvas.setAttribute(evtName,userEvt);}}
if(!x3dElem.__addEventListener&&!x3dElem.__removeEventListener)
{x3dElem.__addEventListener=x3dElem.addEventListener;x3dElem.__removeEventListener=x3dElem.removeEventListener;x3dElem.addEventListener=function(type,func,phase){var j,found=false;for(j=0;j<evtArr.length&&!found;j++){if(evtArr[j]===type){found=true;}}
if(found){x3dom.debug.logInfo('addEventListener for div.on'+type);that.canvas.addEventListener(type,func,phase);}else{x3dom.debug.logInfo('addEventListener for X3D.on'+type);this.__addEventListener(type,func,phase);}};x3dElem.removeEventListener=function(type,func,phase){var j,found=false;for(j=0;j<evtArr.length&&!found;j++){if(evtArr[j]===type){found=true;}}
if(found){x3dom.debug.logInfo('removeEventListener for div.on'+type);that.canvas.removeEventListener(type,func,phase);}else{x3dom.debug.logInfo('removeEventListener for X3D.on'+type);this.__removeEventListener(type,func,phase);}};}
x3dElem.appendChild(canvas);var id=x3dElem.getAttribute("id");if(id!==null){canvas.id="x3dom-"+id+"-canvas";}else{var index=new Date().getTime();canvas.id="x3dom-"+index+"-canvas";}
var w=2;var h=2;if((w=x3dElem.getAttribute("width"))!==null){canvas.style.width=w;canvas.setAttribute("width",w);}
if((h=x3dElem.getAttribute("height"))!==null){canvas.style.height=h;canvas.setAttribute("height",h);}
canvas.setAttribute("tabindex","0");canvas.focus();return canvas;};var _old_dim=[0,0];this.watchForResize=function(){var new_dim=[x3dom.getStyle(that.canvas,"width"),x3dom.getStyle(that.canvas,"height")];if((_old_dim[0]!=new_dim[0])||(_old_dim[1]!=new_dim[1])){_old_dim=new_dim;that.x3dElem.setAttribute("width",new_dim[0]);that.x3dElem.setAttribute("height",new_dim[1]);}};this.createStatDiv=function(){var statDiv=document.createElement('div');statDiv.setAttribute("class","x3dom-statdiv");statDiv.innerHTML="0 fps";this.x3dElem.appendChild(statDiv);statDiv.oncontextmenu=statDiv.onmousedown=function(evt){evt.preventDefault();evt.stopPropagation();evt.returnValue=false;return false;};return statDiv;};this.createProgressDiv=function(){var progressDiv=document.createElement('div');progressDiv.setAttribute("class","x3dom-progress");var _text=document.createElement('strong');_text.appendChild(document.createTextNode('Loading...'));progressDiv.appendChild(_text);var _inner=document.createElement('span');_inner.setAttribute('style',"width: 25%;");_inner.appendChild(document.createTextNode(" "));progressDiv.appendChild(_inner);this.x3dElem.appendChild(progressDiv);progressDiv.oncontextmenu=progressDiv.onmousedown=function(evt){evt.preventDefault();evt.stopPropagation();evt.returnValue=false;return false;};return progressDiv;};this.isFlashReady=false;this.x3dElem=x3dElem;this.backend='none';if(this.x3dElem.getAttribute('backend')=='flash'){this.backend='flash';this.canvas=this.createFlashObject(x3dElem);if(this.canvas!=null){this.canvas.parent=this;this.gl=this.initFlashContext(this.canvas);}else{this.createInitFailedDiv(x3dElem);return null;}}else{this.backend='webgl';this.canvas=this.createHTMLCanvas(x3dElem);this.canvas.parent=this;this.gl=this.initContext(this.canvas);if(this.gl==null)
{x3dom.debug.logInfo("Fallback to Flash Renderer");this.backend='flash';this.canvas=this.createFlashObject(x3dElem);if(this.canvas!=null){this.canvas.parent=this;this.gl=this.initFlashContext(this.canvas);}else{this.createInitFailedDiv(x3dElem);return null;}}}
x3dom.caps.BACKEND=this.backend;this.fps_t0=new Date().getTime();this.doc=null;x3dElem.__setAttribute=x3dElem.setAttribute;x3dElem.setAttribute=function(attrName,newVal){this.__setAttribute(attrName,newVal);switch(attrName){case"width":that.canvas.setAttribute("width",newVal);if(that.doc._viewarea){that.doc._viewarea._width=parseInt(that.canvas.getAttribute("width"),0);}
break;case"height":that.canvas.setAttribute("height",newVal);if(that.doc._viewarea){that.doc._viewarea._height=parseInt(that.canvas.getAttribute("height"),0);}
break;default:}
that.doc.needRender=true;};var runtimeEnabled=x3dElem.getAttribute("runtimeEnabled");if(runtimeEnabled!==null){this.hasRuntime=(runtimeEnabled.toLowerCase()=="true");}else{this.hasRuntime=x3dElem.hasRuntime;}
if(this.gl===null){this.hasRuntime=false;}
this.showStat=x3dElem.getAttribute("showStat");this.statDiv=this.createStatDiv();this.statDiv.style.display=(this.showStat!==null&&this.showStat=="true")?"inline":"none";this.showProgress=x3dElem.getAttribute("showProgress");this.progressDiv=this.createProgressDiv();this.progressDiv.style.display='inline';if(this.canvas!==null&&this.gl!==null&&this.hasRuntime&&this.backend!=="flash"){this.canvas.mouse_dragging=false;this.canvas.mouse_button=0;this.canvas.mouse_drag_x=0;this.canvas.mouse_drag_y=0;this.canvas.isMulti=false;this.canvas.oncontextmenu=function(evt){evt.preventDefault();evt.stopPropagation();evt.returnValue=false;return false;};this.canvas.addEventListener('mousedown',function(evt){this.focus();switch(evt.button){case 0:this.mouse_button=1;break;case 1:this.mouse_button=4;break;case 2:this.mouse_button=2;break;default:this.mouse_button=0;break;}
this.mouse_drag_x=(evt.offsetX||evt.layerX||evt.x);this.mouse_drag_y=(evt.offsetY||evt.layerY||evt.y);this.mouse_dragging=true;if(evt.shiftKey){this.mouse_button=1;}
if(evt.ctrlKey){this.mouse_button=4;}
if(evt.altKey){this.mouse_button=2;}
this.parent.doc.onMousePress(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);this.parent.doc.needRender=true;window.status=this.id+' DOWN: '+(evt.offsetX||evt.layerX||evt.x)+", "+(evt.offsetY||evt.layerY||evt.y);evt.returnValue=true;},false);this.canvas.addEventListener('mouseup',function(evt){this.mouse_button=0;this.mouse_dragging=false;this.parent.doc.onMouseRelease(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);this.parent.doc.needRender=true;evt.returnValue=true;},false);this.canvas.addEventListener('mouseover',function(evt){this.mouse_button=0;this.mouse_dragging=false;this.parent.doc.onMouseOver(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);this.parent.doc.needRender=true;evt.returnValue=true;},false);this.canvas.addEventListener('mouseout',function(evt){this.mouse_button=0;this.mouse_dragging=false;this.parent.doc.onMouseOut(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);this.parent.doc.needRender=true;evt.returnValue=true;},false);this.canvas.addEventListener('dblclick',function(evt){this.mouse_button=0;this.mouse_drag_x=(evt.offsetX||evt.layerX||evt.x);this.mouse_drag_y=(evt.offsetY||evt.layerY||evt.y);this.mouse_dragging=false;this.parent.doc.onDoubleClick(that.gl,this.mouse_drag_x,this.mouse_drag_y);this.parent.doc.needRender=true;window.status=this.id+' DBL: '+(evt.offsetX||evt.layerX||evt.x)+", "+(evt.offsetY||evt.layerY||evt.y);evt.returnValue=true;},false);this.canvas.addEventListener('mousemove',function(evt){if(evt.shiftKey){this.mouse_button=1;}
if(evt.ctrlKey){this.mouse_button=4;}
if(evt.altKey){this.mouse_button=2;}
if(!this.isMulti)
{this.mouse_drag_x=(evt.offsetX||evt.layerX||evt.x);this.mouse_drag_y=(evt.offsetY||evt.layerY||evt.y);if(this.mouse_dragging){this.parent.doc.onDrag(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);}
else{this.parent.doc.onMove(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);}}
this.parent.doc.needRender=true;evt.returnValue=true;},false);this.canvas.addEventListener('DOMMouseScroll',function(evt){this.mouse_drag_y+=2*evt.detail;this.parent.doc.onDrag(that.gl,this.mouse_drag_x,this.mouse_drag_y,2);this.parent.doc.needRender=true;window.status=this.id+' SCROLL: '+evt.detail;evt.returnValue=true;},false);this.canvas.addEventListener('mousewheel',function(evt){this.mouse_drag_y-=0.1*evt.wheelDeltaY;this.parent.doc.onDrag(that.gl,this.mouse_drag_x,this.mouse_drag_y,2);this.parent.doc.needRender=true;window.status=this.id+' SCROLL: '+evt.detail;evt.returnValue=true;},false);this.canvas.addEventListener('keypress',function(evt){var keysEnabled=this.parent.x3dElem.getAttribute("keysEnabled");if(!keysEnabled||keysEnabled.toLowerCase()==="true"){this.parent.doc.onKeyPress(evt.charCode);}
this.parent.doc.needRender=true;evt.returnValue=true;},true);this.canvas.addEventListener('keyup',function(evt){var keysEnabled=this.parent.x3dElem.getAttribute("keysEnabled");if(!keysEnabled||keysEnabled.toLowerCase()==="true"){this.parent.doc.onKeyUp(evt.keyCode);}
this.parent.doc.needRender=true;evt.returnValue=true;},true);this.canvas.addEventListener('keydown',function(evt){var keysEnabled=this.parent.x3dElem.getAttribute("keysEnabled");if(!keysEnabled||keysEnabled.toLowerCase()==="true"){this.parent.doc.onKeyDown(evt.keyCode);}
this.parent.doc.needRender=true;evt.returnValue=true;},true);var touches={numTouches:0,lastDrag:new x3dom.fields.SFVec2f(),lastMiddle:new x3dom.fields.SFVec2f(),lastDistance:new x3dom.fields.SFVec2f(),lastSquareDistance:0,lastAngle:0,calcAngle:function(vector)
{var rotation=vector.normalize().dot(new x3dom.fields.SFVec2f(1,0));rotation=Math.acos(rotation);if(vector.y<0)
rotation=Math.PI+(Math.PI-rotation);return rotation;}};var mozilla_ids=[];var mozilla_touches={touches:[],preventDefault:function(){}}
var touchStartHandler=function(evt)
{evt.preventDefault();if(touches.numTouches<1&&evt.touches.length==1)
{touches.numTouches=1;touches.lastDrag=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);}
else if(touches.numTouches<2&&evt.touches.length>=2)
{touches.numTouches=2;var touch0=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);var touch1=new x3dom.fields.SFVec2f(evt.touches[1].screenX,evt.touches[1].screenY);var distance=touch1.subtract(touch0);var middle=distance.multiply(0.5).add(touch0);var squareDistance=distance.dot(distance);touches.lastDistance=distance;touches.lastMiddle=middle;touches.lastSquareDistance=squareDistance;touches.lastAngle=touches.calcAngle(distance);}
var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();if(this.parent.doc._scene.getVolume(min,max,true)){this.parent.doc._scene._lastMin=min;this.parent.doc._scene._lastMax=max;}};var touchStartHandlerMoz=function(evt)
{evt.preventDefault();var new_id=true;for(var i=0;i<mozilla_ids.length;++i)
if(mozilla_ids[i]==evt.streamId)
new_id=false;if(new_id==true)
{evt.identifier=evt.streamId;mozilla_ids.push(evt.streamId);mozilla_touches.touches.push(evt);}
touchStartHandler(mozilla_touches);};var touchMoveHandler=function(evt,doc)
{evt.preventDefault();if(evt.touches.length==1)
{var currentDrag=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);var deltaDrag=currentDrag.subtract(touches.lastDrag);touches.lastDrag=currentDrag;var mx=x3dom.fields.SFMatrix4f.rotationY(deltaDrag.x/100);var my=x3dom.fields.SFMatrix4f.rotationX(deltaDrag.y/100);var rotMatrix=mx.mult(my);doc.onMoveView(that.gl,null,rotMatrix);doc.needRender=true;}
else if(evt.touches.length>=2)
{var touch0=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);var touch1=new x3dom.fields.SFVec2f(evt.touches[1].screenX,evt.touches[1].screenY);var distance=touch1.subtract(touch0);var middle=distance.multiply(0.5).add(touch0);var squareDistance=distance.dot(distance);var deltaMiddle=middle.subtract(touches.lastMiddle);var deltaZoom=squareDistance-touches.lastSquareDistance;var deltaMove=new x3dom.fields.SFVec3f(deltaMiddle.x/screen.width,-deltaMiddle.y/screen.height,deltaZoom/(screen.width*screen.height*0.2));var rotation=touches.calcAngle(distance);var angleDelta=touches.lastAngle-rotation;touches.lastAngle=rotation;var rotMatrix=x3dom.fields.SFMatrix4f.rotationZ(angleDelta);touches.lastMiddle=middle;touches.lastDistance=distance;touches.lastSquareDistance=squareDistance;doc.onMoveView(that.gl,deltaMove,rotMatrix);doc.needRender=true;}};var touchMoveHandlerW3C=function(evt)
{touchMoveHandler(evt,this.parent.doc);};var touchMoveHandlerMoz=function(evt)
{evt.preventDefault();for(var i=0;i<mozilla_ids.length;++i)
if(mozilla_ids[i]==evt.streamId)
mozilla_touches.touches[i]=evt;touchMoveHandler(mozilla_touches,this.parent.doc);};var touchEndHandler=function(evt)
{evt.preventDefault();if(touches.numTouches==2&&evt.touches.length==1)
touches.lastDrag=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);if(evt.touches.length<2)
touches.numTouches=evt.touches.length;};var touchEndHandlerMoz=function(evt)
{evt.preventDefault();var remove_index=-1;for(var i=0;i<mozilla_ids.length;++i)
if(mozilla_ids[i]==evt.streamId)
remove_index=i;if(remove_index!=-1)
{mozilla_ids.splice(remove_index,1);mozilla_touches.touches.splice(remove_index,1);}
touchEndHandler(mozilla_touches);};this.canvas.addEventListener('MozTouchDown',touchStartHandlerMoz,true);this.canvas.addEventListener('MozTouchMove',touchMoveHandlerMoz,true);this.canvas.addEventListener('MozTouchUp',touchEndHandlerMoz,true);this.canvas.addEventListener('touchstart',touchStartHandler,true);this.canvas.addEventListener('touchmove',touchMoveHandlerW3C,true);this.canvas.addEventListener('touchend',touchEndHandler,true);}};x3dom.X3DCanvas.prototype.tick=function()
{var d=new Date().getTime();var fps=1000.0/(d-this.fps_t0);this.fps_t0=d;try{this.doc.advanceTime(d/1000);var animD=new Date().getTime()-d;if(this.doc.needRender){if(this.x3dElem.runtime.isReady==true){this.x3dElem.runtime.enterFrame();}else{this.x3dElem.runtime.ready();this.x3dElem.runtime.isReady=true;this.x3dElem.runtime.enterFrame();}
if(this.statDiv){this.statDiv.textContent=fps.toFixed(2)+' fps';this.statDiv.appendChild(document.createElement("br"));this.statDiv.appendChild(document.createTextNode("anim: "+animD));}
if(this.backend=='flash'){if(this.isFlashReady){this.canvas.setFPS({fps:fps});this.doc.needRender=false;this.doc.render(this.gl);}}else{this.doc.needRender=false;this.doc.render(this.gl);}}
if(this.statDiv||this.progressDiv){if(this.statDiv&&this.doc.downloadCount){if(this.doc.needRender)
{this.statDiv.appendChild(document.createElement("br"));this.statDiv.appendChild(document.createTextNode("#Loading: "+this.doc.downloadCount));}
else{this.statDiv.textContent="#Loading: "+this.doc.downloadCount;}}
if(this.progressDiv){this.progressDiv.childNodes[0].textContent='Loading: '+this.doc.downloadCount;if(this.doc.downloadCount>0){this.progressDiv.style.display='inline';}else{this.progressDiv.style.display='none';}
window.myThat=this;window.myStopProgress=function stopProgress(){window.myThat.doc.downloadCount=0;window.myThat.progressDiv.style.display='none';};window.setTimeout("window.myStopProgress()",1500);}}}catch(e){x3dom.debug.logException(e);throw e;}};x3dom.X3DCanvas.prototype.load=function(uri,sceneElemPos,settings){this.doc=new x3dom.X3DDocument(this.canvas,this.gl,settings);var x3dCanvas=this;this.doc.onload=function(){x3dom.debug.logInfo("loaded '"+uri+"'");if(x3dCanvas.hasRuntime){(function mainloop(){x3dCanvas.watchForResize();x3dCanvas.tick();window.requestAnimFrame(mainloop,x3dCanvas);})();}else{x3dCanvas.tick();}};this.x3dElem.render=function(){if(x3dCanvas.hasRuntime){x3dCanvas.doc.needRender=true;}else{x3dCanvas.doc.render(x3dCanvas.gl);}};this.x3dElem.context=x3dCanvas.gl.ctx3d;this.doc.onerror=function(){alert('Failed to load X3D document');};this.doc.load(uri,sceneElemPos);};x3dom.runtime={};x3dom.Runtime=function(doc,canvas){this.doc=doc;this.canvas=canvas;this.isReady=false;};x3dom.Runtime.prototype.initialize=function(doc,canvas){this.doc=doc;this.canvas=canvas;this.config={};this.isReady=false;};x3dom.Runtime.prototype.ready=function(){x3dom.debug.logInfo('System ready.');};x3dom.Runtime.prototype.enterFrame=function(){},x3dom.Runtime.prototype.getActiveBindable=function(typeName){var stacks;var i,current,result;var type;stacks=this.canvas.doc._bindableBag._stacks;result=[];type=x3dom.nodeTypesLC[typeName.toLowerCase()];if(!type){x3dom.debug.logError('No node of type "'+typeName+'" found');return null;}
for(i=0;i<stacks.length;i++){current=stacks[i].getActive();if(current._xmlNode!==undefined&&x3dom.isa(current,type)){result.push(current);}}
return result[0]?result[0]._xmlNode:null;};x3dom.Runtime.prototype.nextView=function(){var stack=this.canvas.doc._scene.getViewpoint()._stack;if(stack){stack.switchTo('next');}else{x3dom.debug.logError('No valid ViewBindable stack.');}};x3dom.Runtime.prototype.prevView=function(){var stack=this.canvas.doc._scene.getViewpoint()._stack;if(stack){stack.switchTo('prev');}else{x3dom.debug.logError('No valid ViewBindable stack.');}};x3dom.Runtime.prototype.viewpoint=function(){return this.canvas.doc._scene.getViewpoint();};x3dom.Runtime.prototype.projectionMatrix=function(){return this.canvas.doc._viewarea.getProjectionMatrix();};x3dom.Runtime.prototype.lightMatrix=function(){this.canvas.doc._viewarea.getLightMatrix();};x3dom.Runtime.prototype.resetView=function(){this.canvas.doc._viewarea.resetView();};x3dom.Runtime.prototype.lightView=function(){if(this.canvas.doc._nodeBag.lights.length>0){this.canvas.doc._viewarea.animateTo(this.canvas.doc._viewarea.getLightMatrix()[0],this.canvas.doc._scene.getViewpoint());return true;}else{x3dom.debug.logInfo("No lights to navigate to");return false;}};x3dom.Runtime.prototype.uprightView=function(){this.canvas.doc._viewarea.uprightView();};x3dom.Runtime.prototype.showAll=function(){this.canvas.doc._viewarea.showAll();};x3dom.Runtime.prototype.debug=function(show){if(show===true){this.canvas.doc._viewarea._visDbgBuf=true;x3dom.debug.logContainer.style.display="block";this.canvas.doc.needRender=true;}
if(show===false){this.canvas.doc._viewarea._visDbgBuf=false;x3dom.debug.logContainer.style.display="none";this.canvas.doc.needRender=true;}
return this.canvas.doc._viewarea._visDbgBuf;};x3dom.Runtime.prototype.navigationType=function(){return this.canvas.doc._scene.getNavigationInfo().getType();};x3dom.Runtime.prototype.examine=function(){this.canvas.doc._scene.getNavigationInfo().setType("examine");};x3dom.Runtime.prototype.fly=function(){this.canvas.doc._scene.getNavigationInfo().setType("fly");};x3dom.Runtime.prototype.lookAt=function(){this.canvas.doc._scene.getNavigationInfo().setType("lookat");};x3dom.Runtime.prototype.lookAround=function(){this.canvas.doc._scene.getNavigationInfo().setType("lookaround");};x3dom.Runtime.prototype.walk=function(){this.canvas.doc._scene.getNavigationInfo().setType("walk");};x3dom.Runtime.prototype.game=function(){this.canvas.doc._scene.getNavigationInfo().setType("game");};x3dom.Runtime.prototype.resetExamin=function(){this.canvas.doc._viewarea._rotMat=x3dom.fields.SFMatrix4f.identity();this.canvas.doc._viewarea._transMat=x3dom.fields.SFMatrix4f.identity();this.canvas.doc._viewarea._movement=new x3dom.fields.SFVec3f(0,0,0);this.canvas.doc.needRender=true;};x3dom.Runtime.prototype.togglePoints=function(){this.canvas.doc._viewarea._points=!this.canvas.doc._viewarea._points;this.canvas.doc.needRender=true;};x3dom.Runtime.prototype.pickMode=function(options){if(options&&options.internal===true){return this.canvas.doc._scene._vf.pickMode;}
return this.canvas.doc._scene._vf.pickMode.toLowerCase();};x3dom.Runtime.prototype.changePickMode=function(type,options){type=type.toLowerCase();switch(type){case'idbuf':type='idBuf';break;case'textcoord':type='textCoord';break;case'color':type='color';break;case'box':type='box';break;default:x3dom.debug.logWarning("Switch pickMode to "+type+'unknown intersect type');type=undefined;}
if(type!==undefined){this.canvas.doc._scene._vf.pickMode=type;x3dom.debug.logInfo("Switched pickMode to '"+type+"'.");return false;}
return true;};x3dom.Runtime.prototype.speed=function(newSpeed){if(newSpeed){this.canvas.doc._scene.getNavigationInfo()._vf.speed=newSpeed;x3dom.debug.logInfo("Changed navigation speed to "+this.canvas.doc._scene.getNavigationInfo()._vf.speed);}
return this.canvas.doc._scene.getNavigationInfo()._vf.speed;};x3dom.Runtime.prototype.statistics=function(mode){var statDiv=this.canvas.statDiv;if(statDiv){if(mode===true){statDiv.style.display='inline';return true;}
if(mode===false){statDiv.style.display='none';return false;}
return statDiv.style.display!='none'}};x3dom.Runtime.prototype.processIndicator=function(mode){var processDiv=this.canvas.processDiv;if(processDiv){if(mode===true){processDiv.style.display='inline';return true;}
if(mode===false){processDiv.style.display='none';return false;}
return processDiv.style.display!='none'}},x3dom.Runtime.prototype.requirements=function(){return"0000";};x3dom.Runtime.prototype.properties=function(){return this.canvas.doc.properties;};x3dom.Runtime.prototype.backendName=function(){return this.canvas.backend;};x3dom.detectActiveX=function(){var isInstalled=false;if(window.ActiveXObject){var control=null;try{control=new ActiveXObject('AVALONATX.InstantPluginATXCtrl.1');}catch(e){}
if(control){isInstalled=true;}}
return isInstalled;};x3dom.rerouteSetAttribute=function(node,browser){node._setAttribute=node.setAttribute;node.setAttribute=function(name,value){var id=node.getAttribute("_x3domNode");var anode=browser.findNode(id);if(anode)
return anode.parseField(name,value);else
return 0;};for(var i=0;i<node.childNodes.length;i++){var child=node.childNodes[i];x3dom.rerouteSetAttribute(child,browser);}};x3dom.insertActiveX=function(x3d){if(typeof x3dom.atxCtrlCounter=='undefined'){x3dom.atxCtrlCounter=0;}
var height=x3d.getAttribute("height");var width=x3d.getAttribute("width");var parent=x3d.parentNode;var divelem=document.createElement("div");divelem.setAttribute("id","x3dplaceholder");var inserted=parent.insertBefore(divelem,x3d);var hiddenx3d=document.createElement("div");hiddenx3d.style.display="none";parent.appendChild(hiddenx3d);parent.removeChild(x3d);hiddenx3d.appendChild(x3d);var atx=document.createElement("object");var containerName="Avalon"+x3dom.atxCtrlCounter;x3dom.atxCtrlCounter++;atx.setAttribute("id",containerName);atx.setAttribute("classid","CLSID:F3254BA0-99FF-4D14-BD81-EDA9873A471E");atx.setAttribute("width",width?width:"500");atx.setAttribute("height",height?height:"500");inserted.appendChild(atx);var atxctrl=document.getElementById(containerName);var browser=atxctrl.getBrowser();var scene=browser.importDocument(x3d);browser.replaceWorld(scene);x3d.getBrowser=function(){return atxctrl.getBrowser();};x3dom.rerouteSetAttribute(x3d,browser);};x3dom.userAgentFeature={supportsDOMAttrModified:false};(function(){var onload=function(){var i,j;var x3ds=document.getElementsByTagName('X3D');var w3sg=document.getElementsByTagName('webSG');var params;var settings=new x3dom.Properties();var validParams=array_to_object(['showLog','showStat','showProgress','PrimitiveQuality','component','loadpath','disableDoubleClick','maxActiveDownloads']);var components,prefix;var showLoggingConsole=false;for(i=0;i<x3ds.length;i++){settings.setProperty("showLog",x3ds[i].getAttribute("showLog")||'false');settings.setProperty("showStat",x3ds[i].getAttribute("showStat")||'false');settings.setProperty("showProgress",x3ds[i].getAttribute("showProgress")||'true');settings.setProperty("PrimitiveQuality",x3ds[i].getAttribute("PrimitiveQuality")||'High');params=x3ds[i].getElementsByTagName('PARAM');for(j=0;j<params.length;j++){if(params[j].getAttribute('name')in validParams){settings.setProperty(params[j].getAttribute('name'),params[j].getAttribute('value'));}else{}}
if(settings.getProperty('showLog')==='true'){showLoggingConsole=true;}
if(typeof X3DOM_SECURITY_OFF!='undefined'&&X3DOM_SECURITY_OFF===true){components=settings.getProperty('components',x3ds[i].getAttribute("components"));if(components){prefix=settings.getProperty('loadpath',x3ds[i].getAttribute("loadpath"))
components=components.trim().split(',');for(j=0;j<components.length;j++){x3dom.loadJS(components[j]+".js",prefix);}}}
if(typeof X3DOM_SECURITY_OFF!='undefined'&&X3DOM_SECURITY_OFF===true){if(x3ds[i].getAttribute("src")){var _scene=document.createElement("scene");var _inl=document.createElement("Inline");_inl.setAttribute("url",x3ds[i].getAttribute("src"));_scene.appendChild(_inl);x3ds[i].appendChild(_scene);}}}
if(showLoggingConsole==true){x3dom.debug.activate(true);}else{x3dom.debug.activate(false);}
if(window.navigator.userAgent.match(/webkit/i)){x3dom.debug.logInfo("Active DOMAttrModifiedEvent workaround for webkit ");x3dom.userAgentFeature.supportsDOMAttrModified=false;}
x3ds=Array.map(x3ds,function(n){n.runtime=new x3dom.Runtime();n.hasRuntime=true;return n;});w3sg=Array.map(w3sg,function(n){n.hasRuntime=false;return n;});for(i=0;i<w3sg.length;i++){x3ds.push(w3sg[i]);}
if(x3dom.versionInfo!==undefined){x3dom.debug.logInfo("X3Dom Version "+x3dom.versionInfo.version+", "+"Revison "+x3dom.versionInfo.revision+", "+"Date "+x3dom.versionInfo.date);}
x3dom.debug.logInfo("Found "+(x3ds.length-w3sg.length)+" X3D and "+
w3sg.length+" (experimental) WebSG nodes...");var x3d_element;var x3dcanvas;var altDiv,altP,aLnk,altImg,altImgObj;var t0,t1;for(i=0;i<x3ds.length;i++)
{x3d_element=x3ds[i];if(x3dom.detectActiveX()){x3dom.insertActiveX(x3d_element);continue;}
x3dcanvas=new x3dom.X3DCanvas(x3d_element,i);if(x3dcanvas.gl===null){altDiv=document.createElement("div");altDiv.setAttribute("class","x3dom-nox3d");altP=document.createElement("p");altP.appendChild(document.createTextNode("WebGL is not yet supported in your browser. "));aLnk=document.createElement("a");aLnk.setAttribute("href","http://www.x3dom.org/?page_id=9");aLnk.appendChild(document.createTextNode("Follow link for a list of supported browsers... "));altDiv.appendChild(altP);altDiv.appendChild(aLnk);x3dcanvas.x3dElem.appendChild(altDiv);if(x3dcanvas.statDiv){x3d_element.removeChild(x3dcanvas.statDiv);}
altImg=x3ds[i].getAttribute("altImg")||null;if(altImg){altImgObj=new Image();altImgObj.src=altImg;x3d_element.style.backgroundImage="url("+altImg+")";}
continue;}
t0=new Date().getTime();x3ds[i].runtime=new x3dom.Runtime(x3ds[i],x3dcanvas);x3ds[i].runtime.initialize(x3ds[i],x3dcanvas);if(x3dom.runtime.ready){x3ds[i].runtime.ready=x3dom.runtime.ready;}
x3dcanvas.load(x3ds[i],i,settings);if(settings.getProperty('showStat')==='true'){x3ds[i].runtime.statistics(true);}else{x3ds[i].runtime.statistics(false);}
if(settings.getProperty('showProgress')==='true'){if(settings.getProperty('showProgress')==='bar'){x3dcanvas.progressDiv.setAttribute("class","x3dom-progress bar");}
x3ds[i].runtime.processIndicator(true);}else{x3ds[i].runtime.processIndicator(false);}
x3dom.canvases.push(x3dcanvas);t1=new Date().getTime()-t0;x3dom.debug.logInfo("Time for setup and init of GL element no. "+i+": "+t1+" ms.");}
var ready=(function(eventType){var evt=null;if(document.createEvent){evt=document.createEvent("Events");evt.initEvent(eventType,true,true);document.dispatchEvent(evt);}else if(document.createEventObject){evt=document.createEventObject();document.body.fireEvent('on'+eventType,evt);}})('load');};var onunload=function(){for(var i=0;i<x3dom.canvases.length;i++){x3dom.canvases[i].doc.shutdown(x3dom.canvases[i].gl);}};if(window.location.pathname.lastIndexOf(".xhtml")>0){document.__getElementById=document.getElementById;document.getElementById=function(id){var obj=this.__getElementById(id);if(!obj){var elems=this.getElementsByTagName("*");for(var i=0;i<elems.length&&!obj;i++){if(elems[i].getAttribute("id")===id){obj=elems[i];}}}
return obj;};}else if((window.location.pathname.lastIndexOf(".html")>0)&&(navigator.userAgent.indexOf("Firefox")!=-1)){document.getElementById=function(id){var node=travers(document.getElementsByTagName('body')[0],id);return node;};}
if(window.addEventListener){window.addEventListener('load',onload,false);window.addEventListener('unload',onunload,false);window.addEventListener('reload',onunload,false);}else if(window.attachEvent){window.attachEvent('onload',onload);window.attachEvent('onunload',onunload);window.attachEvent('onreload',onunload);}})();function travers(node,id){if(node instanceof Element){if(node.getAttribute('id')==id){return node;}else if(node.hasChildNodes()){for(var i=0;(i<node.childNodes.length);i++){val=travers(node.childNodes[i],id);if(val)return val;}}else{return null;}}else{return null;}};x3dom.gfx_webgl=(function(){function Context(ctx3d,canvas,name){this.ctx3d=ctx3d;this.canvas=canvas;this.name=name;this.cached_shader_programs={};this.cached_shaders={};}
Context.prototype.getName=function(){return this.name;};function setupContext(canvas){var validContextNames=['moz-webgl','webkit-3d','experimental-webgl','webgl'];var ctx=null;var ctxAttribs={alpha:true,depth:true,stencil:true,antialias:true,premultipliedAlpha:false};for(var i=0;i<validContextNames.length;i++){try{ctx=canvas.getContext(validContextNames[i],ctxAttribs);if(ctx){var newCtx=new Context(ctx,canvas,'webgl');try{if(ctx.getString){x3dom.debug.logInfo("\nVendor: "+ctx.getString(ctx.VENDOR)+", "+"Renderer: "+ctx.getString(ctx.RENDERER)+", "+"Version: "+ctx.getString(ctx.VERSION)+", "+"ShadingLangV.: "+ctx.getString(ctx.SHADING_LANGUAGE_VERSION)+", "+"\nExtensions: "+ctx.getString(ctx.EXTENSIONS));}
else{x3dom.debug.logInfo("\nVendor: "+ctx.getParameter(ctx.VENDOR)+", "+"Renderer: "+ctx.getParameter(ctx.RENDERER)+", "+"Version: "+ctx.getParameter(ctx.VERSION)+", "+"ShadingLangV.: "+ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION));x3dom.caps.VENDOR=ctx.getParameter(ctx.VENDOR);x3dom.caps.VERSION=ctx.getParameter(ctx.VERSION);x3dom.caps.RENDERER=ctx.getParameter(ctx.RENDERER);x3dom.caps.SHADING_LANGUAGE_VERSION=ctx.getParameter(ctx.SHADING_LANGUAGE_VERSION);x3dom.caps.RED_BITS=ctx.getParameter(ctx.RED_BITS);x3dom.caps.GREEN_BITS=ctx.getParameter(ctx.GREEN_BITS);x3dom.caps.BLUE_BITS=ctx.getParameter(ctx.BLUE_BITS);x3dom.caps.ALPHA_BITS=ctx.getParameter(ctx.ALPHA_BITS);x3dom.caps.MAX_VERTEX_ATTRIBS=ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS=ctx.getParameter(ctx.MAX_VERTEX_TEXTURE_IMAGE_UNITS);x3dom.caps.MAX_VARYING_VECTORS=ctx.getParameter(ctx.MAX_VARYING_VECTORS);x3dom.caps.MAX_VERTEX_UNIFORM_VECTORS=ctx.getParameter(ctx.MAX_VERTEX_UNIFORM_VECTORS);x3dom.caps.MAX_COMBINED_TEXTURE_IMAGE_UNITS=ctx.getParameter(ctx.MAX_COMBINED_TEXTURE_IMAGE_UNITS);x3dom.caps.MAX_TEXTURE_SIZE=ctx.getParameter(ctx.MAX_TEXTURE_SIZE);x3dom.caps.MAX_CUBE_MAP_TEXTURE_SIZE=ctx.getParameter(ctx.MAX_CUBE_MAP_TEXTURE_SIZE);x3dom.caps.NUM_COMPRESSED_TEXTURE_FORMATS=ctx.getParameter(ctx.NUM_COMPRESSED_TEXTURE_FORMATS);x3dom.caps.MAX_RENDERBUFFER_SIZE=ctx.getParameter(ctx.MAX_RENDERBUFFER_SIZE);x3dom.caps.MAX_VIEWPORT_DIMS=ctx.getParameter(ctx.MAX_VIEWPORT_DIMS);x3dom.caps.ALIASED_LINE_WIDTH_RANGE=ctx.getParameter(ctx.ALIASED_LINE_WIDTH_RANGE);x3dom.caps.ALIASED_POINT_SIZE_RANGE=ctx.getParameter(ctx.ALIASED_POINT_SIZE_RANGE);x3dom.caps.EXTENSIONS=ctx.getSupportedExtensions();x3dom.caps.MOBILE=(function(a){if(/android.+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(a)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|e\-|e\/|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(di|rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|xda(\-|2|g)|yas\-|your|zeto|zte\-/i.test(a.substr(0,4))){return true}else{return false}})(navigator.userAgent||navigator.vendor||window.opera);if(x3dom.caps.MOBILE){x3dom.debug.logWarning("Detect mobile Browser! Using low quality shaders!");}}}
catch(ex){x3dom.debug.logWarning("Your browser probably supports an older WebGL version. "+"Please try the mobile runtime instead:\n"+"http://www.x3dom.org/x3dom/src_mobile/x3dom.js");}
return newCtx;}}
catch(e){}}
return null;}
var g_shaders={};g_shaders['vs-x3d-bg-texture']={type:"vertex",data:"attribute vec3 position;"+"varying vec2 fragTexCoord;"+""+"void main(void) {"+"    vec2 texCoord = (position.xy + 1.0) * 0.5;"+"    fragTexCoord = texCoord;"+"    gl_Position = vec4(position.xy, 0.0, 1.0);"+"}"};g_shaders['vs-x3d-bg-texture-bgnd']={type:"vertex",data:"attribute vec3 position;"+"attribute vec2 texcoord;"+"uniform mat4 modelViewProjectionMatrix;"+"varying vec2 fragTexCoord;"+""+"void main(void) {"+"    fragTexCoord = texcoord;"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"}"};g_shaders['fs-x3d-bg-texture']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"uniform sampler2D tex;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    gl_FragColor = texture2D(tex, fragTexCoord);\n"+"}"};g_shaders['vs-x3d-bg-textureCube']={type:"vertex",data:"attribute vec3 position;"+"uniform mat4 modelViewProjectionMatrix;"+"varying vec3 fragNormal;"+""+"void main(void) {"+"    fragNormal = (vec4(normalize(position), 0.0)).xyz;"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"}"};g_shaders['fs-x3d-bg-textureCube']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"uniform samplerCube tex;"+"varying vec3 fragNormal;"+""+"void main(void) {"+"    vec3 normal = -reflect(normalize(fragNormal), vec3(0.0,0.0,1.0));"+"    if (abs(normal.y) >= abs(normal.x) && abs(normal.y) >= abs(normal.z))"+"        normal.x *= -1.0;"+"    gl_FragColor = textureCube(tex, normal);"+"}"};g_shaders['vs-x3d-vertexcolorUnlit']={type:"vertex",data:"attribute vec3 position;"+"attribute vec3 color;"+"varying vec3 fragColor;"+"uniform mat4 modelViewProjectionMatrix;"+""+"void main(void) {"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"    gl_PointSize = 2.0;"+"    fragColor = color;"+"}"};g_shaders['fs-x3d-vertexcolorUnlit']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"uniform vec3 diffuseColor;"+"uniform float alpha;"+"uniform float lightOn;"+"varying vec3 fragColor;"+""+"void main(void) {"+"    gl_FragColor = vec4(fragColor, alpha);"+"}"};g_shaders['vs-x3d-default']={type:"vertex",data:"attribute vec3 position;"+"uniform mat4 modelViewProjectionMatrix;"+"void main(void) {"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"}"};g_shaders['fs-x3d-default']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"struct Material {"+"   vec3  diffuseColor;"+"   vec3  specularColor;"+"   vec3  emissiveColor;"+"   float shininess;"+"   float transparency;"+"   float ambientIntensity;"+"};"+"uniform Material material;"+"void main(void) {"+"    gl_FragColor = vec4(material.emissiveColor, 1.0);"+"}"};g_shaders['vs-x3d-texcoordUnlit']={type:"vertex",data:"attribute vec3 position;"+"attribute vec2 texcoord;"+"varying vec3 fragColor;"+"uniform mat4 modelViewProjectionMatrix;"+""+"void main(void) {"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"    fragColor = vec3(abs(texcoord.x), abs(texcoord.y), 0.0);"+"}"};g_shaders['fs-x3d-texcoordUnlit']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"uniform float alpha;"+"varying vec3 fragColor;"+""+"void main(void) {"+"    gl_FragColor = vec4(fragColor, alpha);"+"}"};g_shaders['vs-x3d-pick']={type:"vertex",data:"attribute vec3 position;"+"uniform mat4 modelMatrix;"+"uniform mat4 modelViewProjectionMatrix;"+"uniform vec3 wcMin;"+"uniform vec3 wcMax;"+"varying vec3 worldCoord;"+"void main(void) {"+"    worldCoord = (modelMatrix * vec4(position, 1.0)).xyz;"+"    vec3 dia = wcMax - wcMin;"+"    worldCoord = worldCoord - wcMin;"+"    worldCoord.x /= dia.x;"+"    worldCoord.y /= dia.y;"+"    worldCoord.z /= dia.z;"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"}"};g_shaders['vs-x3d-pickIG']={type:"vertex",data:"attribute vec3 position;"+"uniform mat4 modelMatrix;"+"uniform mat4 modelViewProjectionMatrix;"+"uniform vec3 wcMin;"+"uniform vec3 wcMax;"+"varying vec3 worldCoord;"+"uniform float indexed;"+"uniform float imageGeometry;"+"uniform vec3 IG_bboxMin;"+"uniform vec3 IG_bboxMax;"+"uniform float IG_coordTextureWidth;"+"uniform float IG_coordTextureHeight;"+"uniform float IG_indexTextureWidth;"+"uniform float IG_indexTextureHeight;"+"uniform sampler2D IG_indexTexture;"+"uniform sampler2D IG_coordinateTexture;"+"void main(void) {"+"  if(imageGeometry == 1.0) { "+"  vec2 IG_texCoord;"+"  if(indexed == 1.0) {"+"   vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);"+"   IG_texCoord = vec2(position.x*(256.0/IG_indexTextureWidth), position.y*(256.0/IG_indexTextureHeight)) + halfPixel;"+"   vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;"+"   IG_texCoord = IG_index * 0.996108948;"+"  } else { "+"   vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);"+"   IG_texCoord = vec2(position.x*(256.0/IG_coordTextureWidth), position.y*(256.0/IG_coordTextureHeight)) + halfPixel;"+"  }"+"  vec3 pos = texture2D( IG_coordinateTexture, IG_texCoord ).rgb;"+"   pos = pos * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;"+"     worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz;"+"  gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);"+"  } else { "+"     worldCoord = (modelMatrix * vec4(position, 1.0)).xyz;"+"  gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);"+"  }"+"    vec3 dia = wcMax - wcMin;"+"    worldCoord = worldCoord - wcMin;"+"    worldCoord.x /= dia.x;"+"    worldCoord.y /= dia.y;"+"    worldCoord.z /= dia.z;"+"}"};g_shaders['fs-x3d-pick']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"uniform float alpha;"+"varying vec3 worldCoord;"+"void main(void) {"+"    gl_FragColor = vec4(worldCoord, alpha);"+"}"};g_shaders['vs-x3d-shadow']={type:"vertex",data:"attribute vec3 position;"+"uniform mat4 modelViewProjectionMatrix;"+"varying vec4 projCoord;"+"void main(void) {"+"   projCoord = modelViewProjectionMatrix * vec4(position, 1.0);"+"   gl_Position = projCoord;"+"}"};g_shaders['fs-x3d-shadow']={type:"fragment",data:"#ifdef GL_ES             \n"+"  precision highp float; \n"+"#endif                   \n"+"\n"+"varying vec4 projCoord;"+"void main(void) {"+"    vec3 proj = (projCoord.xyz / projCoord.w);"+"    vec4 outVal = vec4(0.0);"+"    float toFixed = 255.0 / 256.0;"+"    outVal.r = fract(proj.z * toFixed);"+"    outVal.g = fract(proj.z * toFixed * 255.0);"+"    outVal.b = fract(proj.z * toFixed * 255.0 * 255.0);"+"    outVal.a = fract(proj.z * toFixed * 255.0 * 255.0 * 255.0);"+"    gl_FragColor = outVal;"+"}"};function getDefaultShaderProgram(gl,suffix)
{var prog=gl.createProgram();var vs=gl.createShader(gl.VERTEX_SHADER);var fs=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(vs,g_shaders['vs-x3d-'+suffix].data);gl.shaderSource(fs,g_shaders['fs-x3d-'+suffix].data);gl.compileShader(vs);if(!gl.getShaderParameter(vs,gl.COMPILE_STATUS)){x3dom.debug.logError("VertexShader "+gl.getShaderInfoLog(vs));}
gl.compileShader(fs);if(!gl.getShaderParameter(fs,gl.COMPILE_STATUS)){x3dom.debug.logError("FragmentShader "+gl.getShaderInfoLog(fs));}
gl.attachShader(prog,vs);gl.attachShader(prog,fs);gl.linkProgram(prog);var msg=gl.getProgramInfoLog(prog);if(msg){x3dom.debug.logError(msg);}
return wrapShaderProgram(gl,prog);}
function scaleImage(image)
{if(!isPowerOfTwo(image.width)||!isPowerOfTwo(image.height)){var canvas=document.createElement("canvas");canvas.width=nextHighestPowerOfTwo(image.width);canvas.height=nextHighestPowerOfTwo(image.height);var ctx=canvas.getContext("2d");ctx.drawImage(image,0,0,image.width,image.height,0,0,canvas.width,canvas.height);image=canvas;}
return image;}
function isPowerOfTwo(x)
{return((x&(x-1))===0);}
function nextHighestPowerOfTwo(x)
{--x;for(var i=1;i<32;i<<=1){x=x|x>>i;}
return(x+1);}
function nextBestPowerOfTwo(x)
{var log2x=Math.log(x)/Math.log(2);return Math.pow(2,Math.round(log2x));}
Context.prototype.getShaderProgram=function(gl,ids)
{var shader=[];var prog=null;var debug=[];if(this.cached_shader_programs[ids[0]+ids[1]]){prog=this.cached_shader_programs[ids[0]+ids[1]];}
else
{for(var id=0;id<2;id++)
{if(!g_shaders[ids[id]]){x3dom.debug.logError('Cannot find shader '+ids[id]);return;}
if(this.cached_shaders[ids[id]]){shader[id]=this.cached_shaders[ids[id]];}else{if(g_shaders[ids[id]].type=='vertex'){shader[id]=gl.createShader(gl.VERTEX_SHADER);}
else if(g_shaders[ids[id]].type=='fragment'){shader[id]=gl.createShader(gl.FRAGMENT_SHADER);}
else{x3dom.debug.logError('Invalid shader type '+g_shaders[id].type);return;}
gl.shaderSource(shader[id],g_shaders[ids[id]].data);gl.compileShader(shader[id]);if(!gl.getShaderParameter(shader[id],gl.COMPILE_STATUS)){if(id==0){x3dom.debug.logError("VertexShader "+gl.getShaderInfoLog(shader[id]));}else{x3dom.debug.logError("FragmentShader "+gl.getShaderInfoLog(shader[id]));}}
this.cached_shaders[ids[id]]=shader[id];}}
prog=gl.createProgram();gl.attachShader(prog,shader[0]);gl.attachShader(prog,shader[1]);gl.linkProgram(prog);var msg=gl.getProgramInfoLog(prog);if(msg){x3dom.debug.logError(msg);}
this.cached_shader_programs[ids[0]+ids[1]]=wrapShaderProgram(gl,prog);prog=this.cached_shader_programs[ids[0]+ids[1]];}
return prog;};function wrapShaderProgram(gl,sp)
{var shader={};shader.bind=function(){gl.useProgram(sp);};var loc=null,obj=null;var i=0;var glErr;var numUniforms=gl.getProgramParameter(sp,gl.ACTIVE_UNIFORMS);for(i=0;i<numUniforms;++i){try{obj=gl.getActiveUniform(sp,i);}
catch(eu){}
glErr=gl.getError();if(glErr!==0){x3dom.debug.logError("GL-Error: "+glErr);}
loc=gl.getUniformLocation(sp,obj.name);var objName=obj.name;if(obj.name.lastIndexOf("[0]")==obj.name.length-3){x3dom.debug.logInfo(obj.name);objName=obj.name.substr(0,obj.name.length-3);}
switch(obj.type){case gl.SAMPLER_2D:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.SAMPLER_CUBE:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.BOOL:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.FLOAT:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform1f(loc,val);};})(loc));break;case gl.FLOAT_VEC2:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform2f(loc,val[0],val[1]);};})(loc));break;case gl.FLOAT_VEC3:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform3f(loc,val[0],val[1],val[2]);};})(loc));break;case gl.FLOAT_VEC4:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform4f(loc,val[0],val[1],val[2],val[3]);};})(loc));break;case gl.FLOAT_MAT2:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniformMatrix2fv(loc,false,new Float32Array(val));};})(loc));break;case gl.FLOAT_MAT3:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniformMatrix3fv(loc,false,new Float32Array(val));};})(loc));break;case gl.FLOAT_MAT4:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniformMatrix4fv(loc,false,new Float32Array(val));};})(loc));break;case gl.INT:shader.__defineSetter__(objName,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;default:x3dom.debug.logWarning('GLSL program variable '+obj.name+' has unknown type '+obj.type);}}
var numAttribs=gl.getProgramParameter(sp,gl.ACTIVE_ATTRIBUTES);for(i=0;i<numAttribs;++i){try{obj=gl.getActiveAttrib(sp,i);}
catch(ea){}
glErr=gl.getError();if(glErr!==0){x3dom.debug.logError("GL-Error: "+glErr);}
loc=gl.getAttribLocation(sp,obj.name);shader[obj.name]=loc;}
return shader;}
function useLightingFunc(viewarea)
{var result=[0,false];var slights=viewarea.getLights();var numLights=slights.length;if(numLights>0){if(numLights>8){result[0]=8;}else{result[0]=numLights;}}
for(var i=0;i<numLights;i++){if(slights[i]._vf.shadowIntensity>0.0){result[1]=true;}}
var nav=viewarea._scene.getNavigationInfo();if(nav._vf.headlight){result[0]+=1;}
return result;}
Context.prototype.generateVSMobile=function(viewarea,shape)
{var texture=(shape._cf.appearance.node._cf.texture.node||x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text))?1:0;var textureTransform=(shape._cf.appearance.node._cf.textureTransform.node!==null)?1:0;var sphereMapping=(shape._cf.geometry.node._cf.texCoord!==undefined&&shape._cf.geometry.node._cf.texCoord.node!==null&&shape._cf.geometry.node._cf.texCoord.node._vf.mode)?(shape._cf.geometry.node._cf.texCoord.node._vf.mode.toLowerCase()=="sphere")?1:0:0;var cubeMap=(shape._cf.appearance.node._cf.texture.node)?x3dom.isa(shape._cf.appearance.node._cf.texture.node,x3dom.nodeTypes.X3DEnvironmentTextureNode)?1:0:0;var blending=(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)||cubeMap||(shape._cf.appearance.node._cf.texture.node&&(shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==1||shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==2)))?1:0;var vertexColor=(shape._cf.geometry.node._mesh._colors[0].length>0||shape._cf.geometry.node.getColorTexture())?shape._cf.geometry.node._mesh._numColComponents:0;var lights=(viewarea.getLights().length)+(viewarea._scene.getNavigationInfo()._vf.headlight);var solid=(shape.isSolid())?1:0;var fog=(viewarea._scene.getFog()._vf.visibilityRange>0)?1:0;var imageGeometry=(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.ImageGeometry))?1:0;var iG_Precision=(imageGeometry)?shape._cf.geometry.node.numCoordinateTextures():0;var iG_Indexed=(imageGeometry&&shape._cf.geometry.node.getIndexTexture()!=null)?1.0:0.0;var shaderIdentifier="vs-x3d-mobil-"+vertexColor+
texture+
textureTransform+
sphereMapping+
blending+
cubeMap+
solid+
fog+
lights+
imageGeometry+
iG_Precision+
iG_Indexed;if(!g_shaders[shaderIdentifier]){var shader="";shader+="attribute vec3 position;\n";shader+="attribute vec3 normal;\n";shader+="uniform mat4 modelViewMatrix;\n";shader+="uniform mat4 normalMatrix;\n";shader+="uniform mat4 modelViewProjectionMatrix;\n";shader+="uniform vec3  diffuseColor;\n";shader+="uniform vec3  specularColor;\n";shader+="uniform vec3  emissiveColor;\n";shader+="uniform float shininess;\n";shader+="uniform float transparency;\n";shader+="uniform float ambientIntensity;\n";shader+="varying vec4 fragColor;\n";if(imageGeometry){shader+="uniform vec3 IG_bboxMin;";shader+="uniform vec3 IG_bboxMax;";shader+="uniform float IG_coordTextureWidth;";shader+="uniform float IG_coordTextureHeight;";shader+="uniform sampler2D IG_normalTexture;";for(var i=0;i<iG_Precision;i++){shader+="uniform sampler2D IG_coordinateTexture"+i+";";}
if(iG_Indexed){shader+="uniform sampler2D IG_indexTexture;";shader+="uniform float IG_indexTextureWidth;";shader+="uniform float IG_indexTextureHeight;";}}
if(fog){shader+="uniform vec3  fogColor;\n"+"uniform float fogType;\n"+"uniform float fogRange;\n"+"float calcFog(in vec3 eye) {\n"+"   float f0 = 0.0;\n"+"   if(fogType == 0.0) {\n"+"       if(length(eye) < fogRange){\n"+"           f0 = (fogRange-length(eye)) / fogRange;\n"+"       }\n"+"   }else{\n"+"       if(length(eye) < fogRange){\n"+"           f0 = exp(-length(eye) / (fogRange-length(eye) ) );\n"+"       }\n"+"   }\n"+"   f0 = clamp(f0, 0.0, 1.0);\n"+"   return f0;\n"+"}";}
if(lights){for(var l=0;l<lights;l++){shader+="uniform float Light"+l+"_On;\n";shader+="uniform float Light"+l+"_Type;\n";shader+="uniform vec3  Light"+l+"_Location;\n";shader+="uniform vec3  Light"+l+"_Direction;\n";shader+="uniform vec3  Light"+l+"_Color;\n";shader+="uniform vec3  Light"+l+"_Attenuation;\n";shader+="uniform float Light"+l+"_Intensity;\n";shader+="uniform float Light"+l+"_AmbientIntensity;\n";shader+="uniform float Light"+l+"_BeamWidth;\n";shader+="uniform float Light"+l+"_CutOffAngle;\n";shader+="uniform float Light"+l+"_ShadowIntensity;\n";}
shader+="void lighting(in float lType, in vec3 lLocation, in vec3 lDirection, in vec3 lColor, in vec3 lAttenuation,"+"       in float lIntensity, in float lAmbientIntensity, in float lBeamWidth, in float lCutOffAngle,"+"       in vec3 N, in vec3 V, inout vec3 ambient, inout vec3 diffuse, inout vec3 specular) {"+"   vec3 L;\n"+"   float spot = 1.0, attentuation = 1.0;\n"+"   if(lType == 0.0) {\n"+"       L = -normalize(lDirection);\n"+"   }else{\n"+"       L = normalize(lLocation - (-V));"+"       float distance = length(L);"+"       L /= distance;\n"+"       attentuation = 1.0 / (lAttenuation.x + lAttenuation.y * distance + lAttenuation.z * (distance * distance));"+"       attentuation *= max(0.0, dot(N, L));"+"       if(lType == 2.0) {"+"           float spotAngle = acos(max(0.0, dot(-L, normalize(lDirection))));"+"           if(spotAngle >= lCutOffAngle) spot = 0.0;"+"           else if(spotAngle <= lBeamWidth) spot = 1.0;"+"           else spot = (spotAngle - lCutOffAngle ) / (lBeamWidth - lCutOffAngle);"+"       }"+"   }"+"   vec3  H = normalize( L + V );\n"+"   float NdotL = max(0.0, dot(N, L));\n"+"   float NdotH = max(0.0, dot(N, H));\n"+"   float ambientFactor  = lAmbientIntensity * ambientIntensity;"+"   float diffuseFactor  = lIntensity * NdotL;"+"   float specularFactor = lIntensity * NdotL * pow(NdotH, shininess*128.0);"+"   ambient  += lColor * ambientFactor * attentuation * spot;"+"   diffuse  += lColor * diffuseFactor * attentuation * spot;"+"   specular += lColor * specularFactor * attentuation * spot;"+"}";}
if(vertexColor){if(imageGeometry){shader+="uniform sampler2D IG_colorTexture;";}else{if(vertexColor==3){shader+="attribute vec3 color;";}else{shader+="attribute vec4 color;";}}}
if(texture){if(imageGeometry){shader+="uniform sampler2D IG_texCoordTexture;";}else{shader+="attribute vec2 texcoord;\n";}
shader+="varying vec2 fragTexcoord;\n";if(textureTransform){shader+="uniform mat4 texTrafoMatrix;\n";}
if(!blending){shader+="varying vec3 fragAmbient;\n";shader+="varying vec3 fragDiffuse;\n";}
if(cubeMap){shader+="varying vec3 fragViewDir;\n";shader+="varying vec3 fragNormal;\n";shader+="uniform mat4 viewMatrix;\n";}}
shader+="void main(void) {\n";if(imageGeometry){if(iG_Indexed){shader+="vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);";shader+="vec2 IG_texCoord = vec2(position.x*(256.0/IG_indexTextureWidth), position.y*(256.0/IG_indexTextureHeight)) + halfPixel;";shader+="vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;";shader+="halfPixel = vec2(0.5/IG_coordTextureWidth,0.5/IG_coordTextureHeight);";shader+="IG_texCoord = (IG_index * 0.996108948) + halfPixel;";}else{shader+="vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);";shader+="vec2 IG_texCoord = vec2(position.x*(256.0/IG_coordTextureWidth), position.y*(256.0/IG_coordTextureHeight)) + halfPixel;";}
shader+="vec3 temp = vec3(0.0, 0.0, 0.0);";shader+="vec3 vertPosition = vec3(0.0, 0.0, 0.0);";for(var i=0;i<iG_Precision;i++){shader+="temp = texture2D( IG_coordinateTexture"+i+", IG_texCoord ).rgb;";if(i)shader+="temp /= ("+i+".0 * 256.0);";shader+="vertPosition += temp;";}
shader+="vertPosition = vertPosition * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;";shader+="vec3 vertNormal = texture2D( IG_normalTexture, IG_texCoord ).rgb;";shader+="vertNormal = vertNormal * 2.0 - 1.0;";if(texture){shader+="vec4 IG_doubleTexCoords = texture2D( IG_texCoordTexture, IG_texCoord );";shader+="vec2 vertTexCoord;";shader+="vertTexCoord.r = (IG_doubleTexCoords.r * 0.996108948) + (IG_doubleTexCoords.b * 0.003891051);";shader+="vertTexCoord.g = (IG_doubleTexCoords.g * 0.996108948) + (IG_doubleTexCoords.a * 0.003891051);";}
if(vertexColor==3){shader+="vec3 vertColor = texture2D( IG_colorTexture, IG_texCoord ).rgb;";}else if(vertexColor==4){shader+="vec4 vertColor = texture2D( IG_colorTexture, IG_texCoord ).rgba;";}}else{shader+="vec3 vertNormal = normal;";shader+="vec3 vertPosition = position;";if(vertexColor==3){shader+="vec3 vertColor = color;";}else if(vertexColor==4){shader+="vec4 vertColor = color;";}
if(texture){shader+="vec2 vertTexCoord = texcoord;";}}
shader+="vec3 positionMV = (modelViewMatrix * vec4(vertPosition, 1.0)).xyz;\n";shader+="vec3 normalMV = normalize( (normalMatrix * vec4(vertNormal, 0.0)).xyz );\n";shader+="vec3 eye = -positionMV;\n";if(texture){if(cubeMap){shader+="fragViewDir = (viewMatrix[3].xyz);\n";shader+="fragNormal = normalMV;\n";}else if(sphereMapping){shader+=" fragTexcoord = 0.5 + normalMV.xy / 2.0;\n";}else if(textureTransform){shader+=" fragTexcoord = (texTrafoMatrix * vec4(vertTexCoord, 1.0, 1.0)).xy;\n";}else{shader+=" fragTexcoord = vertTexCoord;\n";}}
if(lights){shader+="vec3 ambient   = vec3(0.07, 0.07, 0.07);\n";shader+="vec3 diffuse   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 specular  = vec3(0.0, 0.0, 0.0);\n";if(!solid){shader+="if (dot(normalMV, eye) < 0.0) {\n";shader+=" normalMV *= -1.0;\n";shader+="}\n";}
for(var i=0;i<lights;i++){shader+=" lighting(Light"+i+"_Type,"+"Light"+i+"_Location,"+"Light"+i+"_Direction,"+"Light"+i+"_Color,"+"Light"+i+"_Attenuation,"+"Light"+i+"_Intensity,"+"Light"+i+"_AmbientIntensity,"+"Light"+i+"_BeamWidth,"+"Light"+i+"_CutOffAngle,"+"normalMV, eye, ambient, diffuse, specular);\n";}
if(texture&&blending){shader+="fragColor.rgb = (emissiveColor + ambient*diffuseColor + diffuse*diffuseColor + specular*specularColor);\n";shader+="fragColor.a = 1.0 - transparency;\n";}else if(texture&&!blending){shader+="fragAmbient = ambient;\n";shader+="fragDiffuse = diffuse;\n";shader+="fragColor.rgb = (emissiveColor + specular*specularColor);\n";shader+="fragColor.a = 1.0 - transparency;\n";}else if(vertexColor==3){shader+="fragColor.rgb = vertColor;\n";shader+="fragColor.a = 1.0 - transparency;\n";}else if(vertexColor==4){shader+="fragColor.rgba = vertColor;\n";}else{shader+="fragColor.rgb = (emissiveColor + ambient*diffuseColor + diffuse*diffuseColor + specular*specularColor);\n";shader+="fragColor.a = 1.0-transparency;\n";}}else{if(texture&&!blending){shader+="fragAmbient = vec3(1.0);\n";shader+="fragDiffuse = vec3(1.0);\n";shader+="fragColor.rgb = vec3(0.0);\n";shader+="fragColor.a = 1.0 - transparency;\n";}else if(vertexColor==3){shader+="fragColor.rgb = vertColor;\n";shader+="fragColor.a = 1.0 - transparency;\n";}else if(vertexColor==4){shader+="fragColor.rgba = vertColor;\n";}else{shader+="fragColor.rgb = diffuseColor + emissiveColor;\n;\n";shader+="fragColor.a = 1.0-transparency;\n";}}
if(fog){shader+="float f0 = calcFog(-positionMV);\n";shader+="fragColor.rgb = fogColor * (1.0-f0) + f0 * (fragColor.rgb);\n";}
shader+="gl_Position = modelViewProjectionMatrix * vec4(vertPosition, 1.0);\n";shader+="}\n";g_shaders[shaderIdentifier]={};g_shaders[shaderIdentifier].type="vertex";g_shaders[shaderIdentifier].data=shader;}else{}
return shaderIdentifier;};Context.prototype.generateFSMobile=function(viewarea,shape)
{var texture=(shape._cf.appearance.node._cf.texture.node||x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text))?1:0;var cubeMap=(shape._cf.appearance.node._cf.texture.node)?x3dom.isa(shape._cf.appearance.node._cf.texture.node,x3dom.nodeTypes.X3DEnvironmentTextureNode)?1:0:0;var blending=(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)||cubeMap||(shape._cf.appearance.node._cf.texture.node&&(shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==1||shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==2)))?1:0;var shaderIdentifier="fs-x3d-mobil-"+texture+
cubeMap+
blending;if(!g_shaders[shaderIdentifier]){var shader="";shader+="#ifdef GL_ES \n";shader+="  precision highp float;\n";shader+="#endif\n";shader+="\n";if(texture){if(cubeMap){shader+="uniform samplerCube tex;\n";shader+="varying vec3 fragViewDir;\n";shader+="varying vec3 fragNormal;\n";shader+="uniform mat4 modelViewMatrixInverse;\n";}else{shader+="uniform sampler2D tex;           \n";shader+="varying vec2 fragTexcoord;       \n";}
if(!blending){shader+="varying vec3 fragAmbient;\n";shader+="varying vec3 fragDiffuse;\n";}}
shader+="varying vec4 fragColor;\n";shader+="void main(void) {\n";shader+="vec4 color = fragColor;\n";if(texture){if(cubeMap){shader+="vec3 normal = normalize(fragNormal);\n";shader+="vec3 viewDir = normalize(fragViewDir);\n";shader+="vec3 reflected = reflect(viewDir, normal);\n"
shader+="reflected = (modelViewMatrixInverse * vec4(reflected,0.0)).xyz;\n"
shader+="vec4 texColor = textureCube(tex, reflected);\n";}else{shader+="vec4 texColor = texture2D(tex, vec2(fragTexcoord.s, 1.0-fragTexcoord.t));\n";}
if(blending){if(cubeMap){shader+="color.rgb = mix(color.rgb, texColor.rgb, vec3(0.75));\n";shader+="color.a = texColor.a;\n";}else{shader+="color.rgb *= texColor.rgb;\n";shader+="color.a *= texColor.a;\n";}}else{shader+="color.rgb += fragAmbient*texColor.rgb + fragDiffuse*texColor.rgb;\n";shader+="color.a *= texColor.a;\n";}}
shader+="if (color.a <= 0.1) discard;\n";shader+="gl_FragColor = color;\n";shader+="}\n";g_shaders[shaderIdentifier]={};g_shaders[shaderIdentifier].type="fragment";g_shaders[shaderIdentifier].data=shader;}else{}
return shaderIdentifier;};Context.prototype.generateVS=function(viewarea,shape)
{var shader=(shape._cf.appearance.node._shader&&x3dom.isa(shape._cf.appearance.node._shader,x3dom.nodeTypes.CommonSurfaceShader))?1:0;var texture=(shape._cf.appearance.node._cf.texture.node||shader||x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text))?1:0;var normalMap=(shader&&shape._cf.appearance.node._shader.getNormalMap())?1:0;var textureTransform=(shape._cf.appearance.node._cf.textureTransform.node!==null)?1:0;var sphereMapping=(shape._cf.geometry.node._cf.texCoord!==undefined&&shape._cf.geometry.node._cf.texCoord.node!==null&&shape._cf.geometry.node._cf.texCoord.node._vf.mode)?(shape._cf.geometry.node._cf.texCoord.node._vf.mode.toLowerCase()=="sphere")?1:0:0;var cubeMap=(shape._cf.appearance.node._cf.texture.node)?x3dom.isa(shape._cf.appearance.node._cf.texture.node,x3dom.nodeTypes.X3DEnvironmentTextureNode)?1:0:0;var vertexColor=(shape._cf.geometry.node._mesh._colors[0].length>0||shape._cf.geometry.node.getColorTexture())?shape._cf.geometry.node._mesh._numColComponents:0;var lights=(viewarea.getLights().length)+(viewarea._scene.getNavigationInfo()._vf.headlight);var shadow=(viewarea.getLightsShadow())?1:0;var fog=(viewarea._scene.getFog()._vf.visibilityRange>0)?1:0;var imageGeometry=(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.ImageGeometry))?1:0;var iG_Precision=(imageGeometry)?shape._cf.geometry.node.numCoordinateTextures():0;var iG_Indexed=(imageGeometry&&shape._cf.geometry.node.getIndexTexture()!=null)?1:0;var shaderIdentifier="vs-x3d-"+vertexColor+
texture+
normalMap+
textureTransform+
sphereMapping+
cubeMap+
fog+
lights+
shadow+
imageGeometry+
iG_Precision+
iG_Indexed;if(!g_shaders[shaderIdentifier]){var shader="";shader+="attribute vec3 position;";shader+="attribute vec3 normal;";shader+="uniform mat4 modelViewMatrix;";shader+="uniform mat4 normalMatrix;";shader+="uniform mat4 modelViewProjectionMatrix;";shader+="varying vec3 fragNormal;";if(imageGeometry){shader+="uniform vec3 IG_bboxMin;";shader+="uniform vec3 IG_bboxMax;";shader+="uniform float IG_coordTextureWidth;";shader+="uniform float IG_coordTextureHeight;";if(iG_Indexed){shader+="uniform sampler2D IG_indexTexture;";shader+="uniform float IG_indexTextureWidth;";shader+="uniform float IG_indexTextureHeight;";}
for(var i=0;i<iG_Precision;i++){shader+="uniform sampler2D IG_coordinateTexture"+i+";";}
shader+="uniform sampler2D IG_normalTexture;";shader+="uniform sampler2D IG_texCoordTexture;";shader+="uniform sampler2D IG_colorTexture;";}
if(vertexColor){if(vertexColor==3.0){shader+="attribute vec3 color;";shader+="varying vec3 fragColor;";}else{shader+="attribute vec4 color;";shader+="varying vec4 fragColor;";}}
if(texture){shader+="attribute vec2 texcoord;";shader+="varying vec2 fragTexcoord;";if(textureTransform){shader+="uniform mat4 texTrafoMatrix;";}
if(normalMap){shader+="attribute vec3 tangent;";shader+="attribute vec3 binormal;";shader+="varying vec3 fragTangent;";shader+="varying vec3 fragBinormal;";}
if(cubeMap){shader+="varying vec3 fragViewDir;\n";shader+="uniform mat4 viewMatrix;\n";}}
if(lights||fog){shader+="uniform vec3 eyePosition;";shader+="varying vec3 fragEyePosition;";shader+="varying vec3 fragPosition;";if(shadow){shader+="uniform mat4 matPV;";shader+="varying vec4 projCoord;";}}
shader+="void main(void) {";if(imageGeometry){if(iG_Indexed){shader+="vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);";shader+="vec2 IG_texCoord = vec2(position.x*(256.0/IG_indexTextureWidth), position.y*(256.0/IG_indexTextureHeight)) + halfPixel;";shader+="vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;";shader+="halfPixel = vec2(0.5/IG_coordTextureWidth,0.5/IG_coordTextureHeight);";shader+="IG_texCoord = (IG_index * 0.996108948) + halfPixel;";}else{shader+="vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);";shader+="vec2 IG_texCoord = vec2(position.x*(256.0/IG_coordTextureWidth), position.y*(256.0/IG_coordTextureHeight)) + halfPixel;";}
shader+="vec3 temp = vec3(0.0, 0.0, 0.0);";shader+="vec3 vertPosition = vec3(0.0, 0.0, 0.0);";for(var i=0;i<iG_Precision;i++)
{shader+="temp = 255.0 * texture2D( IG_coordinateTexture"+i+", IG_texCoord ).rgb;";shader+="vertPosition *= 256.0;";shader+="vertPosition += temp;";}
shader+="vertPosition /= (pow(2.0, 8.0 * "+iG_Precision+".0) - 1.0);";shader+="vertPosition = vertPosition * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;";shader+="vec3 vertNormal = texture2D( IG_normalTexture, IG_texCoord ).rgb;";shader+="vertNormal = vertNormal * 2.0 - 1.0;";if(texture){shader+="vec4 IG_doubleTexCoords = texture2D( IG_texCoordTexture, IG_texCoord );";shader+="vec2 vertTexCoord;";shader+="vertTexCoord.r = (IG_doubleTexCoords.r * 0.996108948) + (IG_doubleTexCoords.b * 0.003891051);";shader+="vertTexCoord.g = (IG_doubleTexCoords.g * 0.996108948) + (IG_doubleTexCoords.a * 0.003891051);";}
if(vertexColor){shader+="fragColor = texture2D( IG_colorTexture, IG_texCoord ).rgb;";}
shader+="gl_PointSize = 2.0;";}else{shader+="vec3 vertNormal = normal;";if(texture){shader+="vec2 vertTexCoord = texcoord;";}
shader+="vec3 vertPosition = position;";shader+="gl_PointSize = 2.0;";if(vertexColor){shader+="fragColor = color;";}}
shader+="fragNormal = (normalMatrix * vec4(vertNormal, 0.0)).xyz;";if(lights||fog){shader+="fragPosition = (modelViewMatrix * vec4(vertPosition, 1.0)).xyz;";shader+="fragEyePosition = eyePosition - fragPosition;";if(shadow){shader+="projCoord = matPV * vec4(vertPosition+0.5*normalize(vertNormal), 1.0);";}}
if(texture){if(cubeMap){shader+="fragViewDir = (viewMatrix[3].xyz);\n";}else if(sphereMapping){shader+=" fragTexcoord = 0.5 + fragNormal.xy / 2.0;";}else if(textureTransform){shader+=" fragTexcoord = (texTrafoMatrix * vec4(vertTexCoord, 1.0, 1.0)).xy;";}else{shader+=" fragTexcoord = vertTexCoord;";}
if(normalMap){shader+="fragTangent  = (normalMatrix * vec4(tangent, 0.0)).xyz;";shader+="fragBinormal = (normalMatrix * vec4(binormal, 0.0)).xyz;";}}
shader+="gl_Position = modelViewProjectionMatrix * vec4(vertPosition, 1.0);";shader+="}";g_shaders[shaderIdentifier]={};g_shaders[shaderIdentifier].type="vertex";g_shaders[shaderIdentifier].data=shader;}else{}
return shaderIdentifier;};Context.prototype.generateFS=function(viewarea,shape)
{var vertexColor=(shape._cf.geometry.node._mesh._colors[0].length>0||shape._cf.geometry.node.getColorTexture())?shape._cf.geometry.node._mesh._numColComponents:0;var lights=(viewarea.getLights().length)+(viewarea._scene.getNavigationInfo()._vf.headlight);var shadows=(viewarea.getLightsShadow())?1:0;var fogs=(viewarea._scene.getFog()._vf.visibilityRange>0)?1:0;var solid=(shape.isSolid())?1:0;var texture=(shape._cf.appearance.node._cf.texture.node||x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text))?1:0;var cubeMap=(shape._cf.appearance.node._cf.texture.node)?x3dom.isa(shape._cf.appearance.node._cf.texture.node,x3dom.nodeTypes.X3DEnvironmentTextureNode)?1:0:0;var blending=(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)||cubeMap||(shape._cf.appearance.node._cf.texture.node&&(shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==1.0||shape._cf.appearance.node._cf.texture.node._vf.origChannelCount==2.0)))?1:0;var shader=(shape._cf.appearance.node._shader&&x3dom.isa(shape._cf.appearance.node._shader,x3dom.nodeTypes.CommonSurfaceShader))?1:0;var shaderDiffuse=(shader&&shape._cf.appearance.node._shader.getDiffuseMap())?1:0;var shaderNormal=(shader&&shape._cf.appearance.node._shader.getNormalMap())?1:0;var shaderSpec=(shader&&shape._cf.appearance.node._shader.getSpecularMap())?1:0;var shaderIdentifier="fs-x3d-"+vertexColor+
texture+
cubeMap+
fogs+
lights+
shadows+
blending+
shader+
shaderDiffuse+
shaderNormal+
shaderSpec;if(!g_shaders[shaderIdentifier]){var fog="struct Fog {"+"   vec3  color;"+"   float fogType;"+"   float visibilityRange;"+"};"+"uniform Fog fog;"+"float calcFog() {"+"   float f0 = 0.0;"+"   if(fog.fogType == 0.0) {"+"       if(length(fragEyePosition) < fog.visibilityRange){"+"           f0 = (fog.visibilityRange-length(fragEyePosition)) / fog.visibilityRange;"+"       }"+"   }else{"+"       if(length(fragEyePosition) < fog.visibilityRange){"+"           f0 = exp(-length(fragEyePosition) / (fog.visibilityRange-length(fragEyePosition) ) );"+"       }"+"   }"+"   f0 = clamp(f0, 0.0, 1.0);"+"   return f0;"+"}";var light="struct Light {\n"+"   float on;\n"+"   float type;\n"+"   vec3  location;\n"+"   vec3  direction;\n"+"   vec3  color;\n"+"   vec3  attenuation;\n"+"   float intensity;\n"+"   float ambientIntensity;\n"+"   float beamWidth;\n"+"   float cutOffAngle;\n"+"   float shadowIntensity;\n"+"};\n"+"const int NUMLIGHTS = "+lights+";\n"+"uniform Light light[9];\n"+"void lighting(in Light light, in vec3 N, in vec3 V, inout vec3 ambient, inout vec3 diffuse, inout vec3 specular){"+"   vec3 L;\n"+"   float spot = 1.0, attentuation = 1.0;\n"+"   if(light.type == 0.0) {\n"+"       L = -normalize(light.direction);\n"+"   }else{\n"+"       L = normalize(light.location - fragPosition);"+"       float distance = length(L);"+"       L /= distance;\n"+"       attentuation = 1.0 / (light.attenuation.x + light.attenuation.y * distance + light.attenuation.z * distance * distance);"+"       attentuation *= max(0.0, dot(N, L));"+"       if(light.type == 2.0) {"+"           float spotAngle = acos(max(0.0, dot(-L, normalize(light.direction))));"+"           if(spotAngle >= light.cutOffAngle) spot = 0.0;"+"           else if(spotAngle <= light.beamWidth) spot = 1.0;"+"           else spot = (spotAngle - light.cutOffAngle ) / (light.beamWidth - light.cutOffAngle);"+"       }"+"   }"+"   vec3  H = normalize( L + V );\n"+"   float NdotL = max(0.0, dot(N, L));\n"+"   float NdotH = max(0.0, dot(N, H));\n"+"   float ambientFactor  = light.ambientIntensity * material.ambientIntensity;"+"   float diffuseFactor  = light.intensity * NdotL;"+"   float specularFactor = light.intensity * NdotL * pow(NdotH, material.shininess*128.0);"+"   ambient  += light.color * ambientFactor * attentuation * spot;"+"   diffuse  += light.color * diffuseFactor * attentuation * spot;"+"   specular += light.color * specularFactor * attentuation * spot;"+"}";var shadow="uniform sampler2D sh_tex;"+"varying vec4 projCoord;"+"float PCF_Filter(Light light, vec3 projectiveBiased, float filterWidth)"+"{"+"    float stepSize = 2.0 * filterWidth / 3.0;"+"    float blockerCount = 0.0;"+"    projectiveBiased.x -= filterWidth;"+"    projectiveBiased.y -= filterWidth;"+"    for (float i=0.0; i<3.0; i++)"+"    {"+"        for (float j=0.0; j<3.0; j++)"+"        {"+"            projectiveBiased.x += (j*stepSize);"+"            projectiveBiased.y += (i*stepSize);"+"            vec4 zCol = texture2D(sh_tex, (1.0+projectiveBiased.xy)*0.5);"+"            float fromFixed = 256.0 / 255.0;"+"            float z = zCol.r * fromFixed;"+"            z += zCol.g * fromFixed / (255.0);"+"            z += zCol.b * fromFixed / (255.0 * 255.0);"+"            z += zCol.a * fromFixed / (255.0 * 255.0 * 255.0);"+"            if (z < projectiveBiased.z) blockerCount += 1.0;"+"            projectiveBiased.x -= (j*stepSize);"+"            projectiveBiased.y -= (i*stepSize);"+"        }"+"    }"+"    float result = 1.0 - light.shadowIntensity * blockerCount / 9.0;"+"    return result;"+"}";var material="struct Material {          \n"+"   vec3  diffuseColor;     \n"+"   vec3  specularColor;    \n"+"   vec3  emissiveColor;    \n"+"   float shininess;        \n"+"   float transparency;     \n"+"   float ambientIntensity; \n"+"};                         \n"+"uniform Material material; \n";var shader="";shader+="#ifdef GL_ES             \n";shader+="  precision highp float; \n";shader+="#endif                   \n";shader+="\n";shader+=material;shader+="uniform mat4 modelMatrix;";shader+="uniform mat4 modelViewMatrix;";if(vertexColor){if(vertexColor==3){shader+="varying vec3 fragColor;  \n";}else{shader+="varying vec4 fragColor;  \n";}}
if(texture||shader){shader+="varying vec2 fragTexcoord;       \n";if((texture||shaderDiffuse)&&!cubeMap){shader+="uniform sampler2D tex;           \n";}else if(cubeMap){shader+="uniform samplerCube tex;\n";shader+="varying vec3 fragViewDir;\n";shader+="uniform mat4 modelViewMatrixInverse;\n";}
if(shaderNormal){shader+="uniform sampler2D bump;      \n";shader+="varying vec3 fragTangent;    \n";shader+="varying vec3 fragBinormal;   \n";}
if(shaderSpec){shader+="uniform sampler2D spec;      \n";}}
if(lights){shader+="uniform float solid;             \n";shader+="varying vec3 fragNormal;         \n";shader+="varying vec3 fragPosition;       \n";shader+="varying vec3 fragEyePosition;    \n";shader+=light;if(shadows){shader+=shadow;}}
if(fogs){shader+=fog;if(!lights){shader+="varying vec3 fragEyePosition;    \n";}}
shader+="void main(void) {    \n";shader+="vec3 rgb      = vec3(0.0, 0.0, 0.0); \n";shader+="float alpha = 1.0 - material.transparency;\n";if(lights){shader+="vec3 ambient   = vec3(0.07, 0.07, 0.07);\n";shader+="vec3 diffuse   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 specular  = vec3(0.0, 0.0, 0.0);\n";if(shadows){shader+="float shadowed = 1.0;\n";shader+="float oneShadowAlreadyExists = 0.0;\n";}
shader+="vec3 eye = normalize(-fragPosition);\n";shader+="vec3 normal = normalize(fragNormal);\n";if(shaderNormal){shader+="vec3 t = normalize( fragTangent );\n";shader+="vec3 b = normalize( fragBinormal );\n";shader+="vec3 n = normalize( fragNormal );\n";shader+="mat3 tangentToWorld = mat3(t, b, n);\n";shader+="normal = texture2D( bump, vec2(fragTexcoord.x, 1.0-fragTexcoord.y) ).rgb;\n";shader+="normal = 2.0 * normal - 1.0;\n";shader+="normal = normalize( normal * tangentToWorld );\n";shader+="normal.y = -normal.y;";shader+="normal.x = -normal.x;";}
shader+="if (solid == 0.0 && dot(normal, eye) < 0.0) {\n";shader+=" normal *= -1.0;\n";shader+="}\n";shader+="for(int i=0; i<NUMLIGHTS; i++) {\n";shader+=" lighting(light[i], normal, eye, ambient, diffuse, specular);\n";if(shadows){shader+=" if(light[i].shadowIntensity > 0.0 && oneShadowAlreadyExists == 0.0){\n";shader+="     vec3 projectiveBiased = projCoord.xyz / projCoord.w;\n";shader+="     shadowed = PCF_Filter(light[i], projectiveBiased, 0.002);\n";shader+="     oneShadowAlreadyExists = 1.0;\n";shader+=" }\n";}
shader+="}\n";if(shaderSpec){shader+="specular *= texture2D( spec, vec2(fragTexcoord.x, 1.0-fragTexcoord.y) ).rgb;\n";}
if(texture||shaderDiffuse){if(cubeMap){shader+="vec3 viewDir = normalize(fragViewDir);\n";shader+="vec3 reflected = reflect(viewDir, normal);\n"
shader+="reflected = (modelViewMatrixInverse * vec4(reflected,0.0)).xyz;\n"
shader+="vec4 texColor = textureCube(tex, reflected);\n";shader+="alpha *= texColor.a;\n";}else{shader+="vec2 texCoord = vec2(fragTexcoord.x, 1.0-fragTexcoord.y);\n";shader+="vec4 texColor = texture2D(tex, texCoord);\n";shader+="alpha *= texColor.a;\n";}
if(blending){shader+="   rgb = (material.emissiveColor + ambient*material.diffuseColor + diffuse*material.diffuseColor + specular*material.specularColor);\n";if(cubeMap){shader+="rgb = mix(rgb, texColor.rgb, vec3(0.75));\n";}else{shader+="rgb *= texColor.rgb;\n";}}else{shader+="   rgb = (material.emissiveColor + ambient*texColor.rgb + diffuse*texColor.rgb + specular*material.specularColor);\n";}}else if(vertexColor){shader+="rgb = diffuse*fragColor.rgb;\n";if(vertexColor==4){shader+="alpha = fragColor.a;\n";}}else{shader+="rgb = (material.emissiveColor + ambient*material.diffuseColor + diffuse*material.diffuseColor + specular*material.specularColor);\n";}
if(shadows){shader+="rgb *= shadowed;\n";}}else{if(texture){shader+="vec2 texCoord = vec2(fragTexcoord.x, 1.0-fragTexcoord.y);\n";shader+="vec4 texColor = texture2D(tex, texCoord);\n";shader+="rgb = texColor.rgb;\n";shader+="alpha *= texColor.a;\n";}else if(vertexColor){shader+="rgb = fragColor.rgb;\n";if(vertexColor==4){shader+="alpha = fragColor.a;\n";}}else{shader+="rgb = material.diffuseColor + material.emissiveColor;\n";}}
if(fogs){shader+="float f0 = calcFog();\n";shader+="rgb = fog.color * (1.0-f0) + f0 * (rgb);\n";}
shader+="if (alpha <= 0.1) discard;\n";shader+="gl_FragColor = vec4(rgb, alpha);\n";shader+="}\n";g_shaders[shaderIdentifier]={};g_shaders[shaderIdentifier].type="fragment";g_shaders[shaderIdentifier].data=shader;}else{}
return shaderIdentifier;};Context.prototype.setupShape=function(gl,shape,viewarea)
{var q=0;var tex=null;var colorBuffer;var vertices;var colors;var positionBuffer;if(shape._webgl!==undefined)
{var oldLightsAndShadow=shape._webgl.lightsAndShadow;shape._webgl.lightsAndShadow=useLightingFunc(viewarea);var needFullReInit=(shape._webgl.lightsAndShadow[0]!=oldLightsAndShadow[0]||shape._webgl.lightsAndShadow[1]!=oldLightsAndShadow[1]||shape._dirty.shader);if(shape._dirty.colors===true&&shape._webgl.shader.color===undefined&&shape._cf.geometry.node._mesh._colors[0].length)
{needFullReInit=true;}
if(shape._dirty.texture===true||needFullReInit)
{tex=shape._cf.appearance.node._cf.texture.node;if((shape._webgl.texture!==undefined&&tex)&&!needFullReInit)
{shape.updateTexture(tex,0,"false");shape._dirty.texture=false;}
else
{needFullReInit=true;var spOld=shape._webgl.shader;var inc=0;for(inc=0;shape._webgl.texture!==undefined&&inc<shape._webgl.texture.length;inc++)
{if(shape._webgl.texture[inc])
{gl.deleteTexture(shape._webgl.texture[inc]);}}
for(q=0;q<shape._webgl.positions.length;q++)
{if(spOld.position!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+1]);gl.deleteBuffer(shape._webgl.buffers[5*q+0]);}
if(spOld.normal!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+2]);}
if(spOld.texcoord!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+3]);}
if(spOld.color!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+4]);}}
for(inc=0;inc<shape._webgl.dynamicFields.length;inc++)
{var h_attrib=shape._webgl.dynamicFields[inc];if(spOld[h_attrib.name]!==undefined)
{gl.deleteBuffer(h_attrib.buf);}}}}
for(q=0;q<shape._webgl.positions.length;q++)
{if(!needFullReInit&&shape._dirty.positions===true)
{if(shape._webgl.shader.position!==undefined)
{shape._webgl.positions[q]=shape._cf.geometry.node._mesh._positions[q];gl.deleteBuffer(shape._webgl.buffers[5*q+1]);positionBuffer=gl.createBuffer();shape._webgl.buffers[5*q+1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[5*q+0]);vertices=new Float32Array(shape._webgl.positions[q]);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.vertexAttribPointer(shape._webgl.shader.position,3,gl.FLOAT,false,0,0);vertices=null;}
shape._dirty.positions=false;}
if(!needFullReInit&&shape._dirty.colors===true)
{if(shape._webgl.shader.color!==undefined)
{shape._webgl.colors[q]=shape._cf.geometry.node._mesh._colors[q];gl.deleteBuffer(shape._webgl.buffers[5*q+4]);colorBuffer=gl.createBuffer();shape._webgl.buffers[5*q+4]=colorBuffer;colors=new Float32Array(shape._webgl.colors[q]);gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);gl.bufferData(gl.ARRAY_BUFFER,colors,gl.STATIC_DRAW);gl.vertexAttribPointer(shape._webgl.shader.color,3,gl.FLOAT,false,0,0);colors=null;}
shape._dirty.colors=false;}}
if(!needFullReInit){return;}}
else if(!x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)&&(!shape._cf.geometry.node||shape._cf.geometry.node._mesh._positions[0].length<1)){x3dom.debug.logError("NO VALID MESH OR NO VERTEX POSITIONS SET!");return;}
shape._dirty.positions=false;shape._dirty.normals=false;shape._dirty.texcoords=false;shape._dirty.colors=false;shape._dirty.indexes=false;shape._dirty.texture=false;if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text))
{var fontStyleNode=shape._cf.geometry.node._cf.fontStyle.node;var font_family=['SERIF'];var font_size=32;var font_style="PLAIN";var font_spacing=1.0;var font_horizontal=true;var font_justify='BEGIN';var font_language="";var font_leftToRight=true;var font_topToBottom=true;if(fontStyleNode!==null){var fonts=fontStyleNode._vf.family.toString();fonts=fonts.trim().replace(/\'/g,'').replace(/\,/,' ');fonts=fonts.split(" ");font_family=Array.map(fonts,function(s){if(s=='SANS'){return'sans-serif';}
else if(s=='SERIF'){return'serif';}
else if(s=='TYPEWRITER'){return'monospace';}
else{return''+s+'';}}).join(",");font_style=fontStyleNode._vf.style.toString().replace(/\'/g,'');switch(font_style.toUpperCase()){case'PLAIN':font_style='normal';break;case'BOLD':font_style='bold';break;case'ITALIC':font_style='italic';break;case'BOLDITALIC':font_style='italic bold';break;default:font_style='normal';}
font_leftToRight=fontStyleNode._vf.leftToRight?'ltr':'rtl';font_topToBottom=fontStyleNode._vf.topToBottom;font_justify=fontStyleNode._vf.justify.toString().replace(/\'/g,'');switch(font_justify.toUpperCase()){case'BEGIN':font_justify='left';break;case'END':font_justify='right';break;case'FIRST':font_justify='left';break;case'MIDDLE':font_justify='center';break;default:font_justify='left';}
font_size=fontStyleNode._vf.size;font_spacing=fontStyleNode._vf.spacing;font_horizontal=fontStyleNode._vf.horizontal;font_language=fontStyleNode._vf.language;}
var string=shape._cf.geometry.node._vf.string;var text_canvas=document.createElement('canvas');text_canvas.dir=font_leftToRight;text_canvas.width=viewarea._width;text_canvas.height=font_size;text_canvas.display='none';document.body.appendChild(text_canvas);var text_ctx=text_canvas.getContext('2d');text_ctx.font=font_style+" "+font_size+"px "+font_family;var txtW=text_ctx.measureText(string).width;var txtH=text_ctx.measureText(string).height||text_canvas.height;text_canvas.width=Math.pow(2,Math.ceil(Math.log(txtW)/Math.log(2)));text_canvas.height=Math.pow(2,Math.ceil(Math.log(txtH)/Math.log(2)));text_ctx.fillStyle='rgba(0,0,0,0)';text_ctx.fillRect(0,0,text_ctx.canvas.width,text_ctx.canvas.height);text_ctx.fillStyle='white';text_ctx.lineWidth=2.5;text_ctx.strokeStyle='grey';text_ctx.textBaseline='top';text_ctx.font=font_style+" "+font_size+"px "+font_family;text_ctx.textAlign=font_justify;var leftOffset=(text_ctx.canvas.width-txtW)/2.0;var topOffset=(text_ctx.canvas.height-font_size)/2.0;text_ctx.fillText(string,leftOffset,topOffset);var ids=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,ids);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,text_canvas);document.body.removeChild(text_canvas);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);var w=txtW/100.0;var h=txtH/100.0;var v0=1;var u0=0;var u=1;var v=0;shape._cf.geometry.node._mesh._positions[0]=[-w,-h,0,w,-h,0,w,h,0,-w,h,0];shape._cf.geometry.node._mesh._normals[0]=[0,0,1,0,0,1,0,0,1,0,0,1];shape._cf.geometry.node._mesh._texCoords[0]=[u0,v,u,v,u,v0,u0,v0];shape._cf.geometry.node._mesh._colors[0]=[];shape._cf.geometry.node._mesh._indices[0]=[0,1,2,2,3,0];shape._cf.geometry.node._mesh._invalidate=true;shape._cf.geometry.node._mesh._numFaces=2;shape._cf.geometry.node._mesh._numCoords=4;shape._webgl={positions:shape._cf.geometry.node._mesh._positions,normals:shape._cf.geometry.node._mesh._normals,texcoords:shape._cf.geometry.node._mesh._texCoords,colors:shape._cf.geometry.node._mesh._colors,indexes:shape._cf.geometry.node._mesh._indices,texture:[ids],textureFilter:[gl.LINEAR],lightsAndShadow:useLightingFunc(viewarea),imageGeometry:0,indexedImageGeometry:0};shape._webgl.primType=gl.TRIANGLES;if(x3dom.caps.MOBILE){shape._webgl.shader=this.getShaderProgram(gl,[this.generateVSMobile(viewarea,shape),this.generateFSMobile(viewarea,shape)]);}else{shape._webgl.shader=this.getShaderProgram(gl,[this.generateVS(viewarea,shape),this.generateFS(viewarea,shape)]);}}
else
{var context=this;tex=shape._cf.appearance.node._cf.texture.node;shape.updateTexture=function(tex,unit,saveSize)
{var that=this;var texture;var childTex=(tex._video!==undefined&&tex._video!==null&&tex._needPerFrameUpdate!==undefined&&tex._needPerFrameUpdate===true);if(this._webgl.texture===undefined){this._webgl.texture=[];}
if(this._webgl.textureFilter===undefined){that._webgl.textureFilter=[];that._webgl.textureFilter[unit]=gl.LINEAR;}
if(tex._isCanvas&&tex._canvas){texture=gl.createTexture();that._webgl.texture[unit]=texture;gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,tex._canvas);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);}
else if(x3dom.isa(tex,x3dom.nodeTypes.RenderedTexture))
{that._webgl.texture[unit]=tex._webgl.fbo.tex;gl.bindTexture(gl.TEXTURE_2D,tex._webgl.fbo.tex);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);}
else if(x3dom.isa(tex,x3dom.nodeTypes.PixelTexture))
{var pixels=new Uint8Array(tex._vf.image.toGL());var format=gl.NONE;switch(tex._vf.image.comp)
{case 1:format=gl.LUMINANCE;break;case 2:format=gl.LUMINANCE_ALPHA;break;case 3:format=gl.RGB;break;case 4:format=gl.RGBA;break;}
texture=gl.createTexture();that._webgl.texture[unit]=texture;gl.bindTexture(gl.TEXTURE_2D,texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);gl.texImage2D(gl.TEXTURE_2D,0,format,tex._vf.image.width,tex._vf.image.height,0,format,gl.UNSIGNED_BYTE,pixels);}
else if(x3dom.isa(tex,x3dom.nodeTypes.MultiTexture))
{for(var cnt=0;cnt<tex.size();cnt++)
{var singleTex=tex.getTexture(cnt);if(!singleTex){break;}
that.updateTexture(singleTex,cnt,"false");}}
else if(x3dom.isa(tex,x3dom.nodeTypes.MovieTexture)||childTex)
{texture=gl.createTexture();if(!childTex)
{tex._video=document.createElement('video');tex._video.setAttribute('autobuffer','true');var p=document.getElementsByTagName('body')[0];p.appendChild(tex._video);tex._video.style.visibility="hidden";}
for(var i=0;i<tex._vf.url.length;i++)
{var videoUrl=tex._nameSpace.getURL(tex._vf.url[i]);x3dom.debug.logInfo('Adding video file: '+videoUrl);var src=document.createElement('source');src.setAttribute('src',videoUrl);tex._video.appendChild(src);}
var updateMovie=function()
{that._nameSpace.doc.needRender=true;if(saveSize=="index"||saveSize=="coord"||saveSize=="normal"||saveSize=="texCoord"){that._webgl.textureFilter[unit]=gl.NEAREST;}
gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,tex._video);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,that._webgl.textureFilter[unit]);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,that._webgl.textureFilter[unit]);gl.bindTexture(gl.TEXTURE_2D,null);};var startVideo=function()
{that._nameSpace.doc.needRender=true;that._webgl.texture[unit]=texture;if(saveSize=="coord"){that._webgl.coordTextureWidth=tex._video.clientWidth;that._webgl.coordTextureHeight=tex._video.clientHeight;}else if(saveSize=="index"){that._webgl.indexTextureWidth=tex._video.clientWidth;that._webgl.indexTextureHeight=tex._video.clientHeight;}
x3dom.debug.logInfo(texture+" video tex url: "+tex._vf.url);tex._video.play();tex._intervalID=setInterval(updateMovie,16);};var videoDone=function()
{clearInterval(tex._intervalID);if(tex._vf.loop===true)
{tex._video.play();tex._intervalID=setInterval(updateMovie,16);}};tex._video.addEventListener("canplaythrough",startVideo,true);tex._video.addEventListener("ended",videoDone,true);}
else if(x3dom.isa(tex,x3dom.nodeTypes.X3DEnvironmentTextureNode))
{texture=context.loadCubeMap(gl,tex.getTexUrl(),that._nameSpace.doc,false);that._webgl.texture[unit]=texture;}
else
{texture=gl.createTexture();var image=new Image();image.crossOrigin='';image.src=tex._nameSpace.getURL(tex._vf.url[0]);that._nameSpace.doc.downloadCount+=1;image.onload=function()
{x3dom.ImageLoadManager.activeDownloads--;that._nameSpace.doc.needRender=true;that._nameSpace.doc.downloadCount-=1;if(tex._vf.scale){image=scaleImage(image);}
that._webgl.texture[unit]=texture;if(saveSize=="coord"){that._webgl.coordTextureWidth=image.width;that._webgl.coordTextureHeight=image.height;}else if(saveSize=="index"){that._webgl.indexTextureWidth=image.width;that._webgl.indexTextureHeight=image.height;}
if(saveSize=="index"||saveSize=="coord"||saveSize=="normal"||saveSize=="texCoord"||saveSize=="color"){that._webgl.textureFilter[unit]=gl.NEAREST;}else{that._webgl.textureFilter[unit]=gl.LINEAR;}
x3dom.debug.logInfo(texture+" bind tex url: "+tex._vf.url+"at unit: "+unit);gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,that._webgl.textureFilter[unit]);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,that._webgl.textureFilter[unit]);gl.bindTexture(gl.TEXTURE_2D,null);tex._complete=true;};image.onerror=function()
{that._nameSpace.doc.downloadCount-=1;x3dom.debug.logError("Can't load tex url: "+tex._vf.url+" (at unit "+unit+").");};}};var indexed=0;var numCoordinateTextures=0;if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.ImageGeometry)){numCoordinateTextures=shape._cf.geometry.node.numCoordinateTextures();indexed=(shape._cf.geometry.node.getIndexTexture()!=null)?1.0:0.0;}
viewarea._scene._webgl.imageGeometry=numCoordinateTextures;shape._webgl={positions:shape._cf.geometry.node._mesh._positions,normals:shape._cf.geometry.node._mesh._normals,texcoords:shape._cf.geometry.node._mesh._texCoords,colors:shape._cf.geometry.node._mesh._colors,indexes:shape._cf.geometry.node._mesh._indices,lightsAndShadow:useLightingFunc(viewarea),imageGeometry:numCoordinateTextures,indexedImageGeometry:indexed};if(tex){shape.updateTexture(tex,0,"false");}
if(shape._webgl.imageGeometry){var IG_texUnit=1;var indexTexture=shape._cf.geometry.node.getIndexTexture();if(indexTexture){shape.updateTexture(indexTexture,IG_texUnit++,'index');}
for(var i=0;i<numCoordinateTextures;i++){var coordinateTexture=shape._cf.geometry.node.getCoordinateTexture(i);if(coordinateTexture){shape.updateTexture(coordinateTexture,IG_texUnit++,'coord');}}
var normalTexture=shape._cf.geometry.node.getNormalTexture(0);if(normalTexture){shape.updateTexture(normalTexture,IG_texUnit++,"normal");}
var texCoordTexture=shape._cf.geometry.node.getTexCoordTexture();if(texCoordTexture){shape.updateTexture(texCoordTexture,IG_texUnit++,"texCoord");}
var colorTexture=shape._cf.geometry.node.getColorTexture();if(colorTexture){shape.updateTexture(colorTexture,IG_texUnit++,"color");}}
if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.PointSet)||x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Polypoint2D)){shape._webgl.primType=gl.POINTS;if(shape._webgl.colors[0].length){shape._webgl.shader=this.getShaderProgram(gl,['vs-x3d-vertexcolorUnlit','fs-x3d-vertexcolorUnlit']);}
else{shape._webgl.shader=this.getShaderProgram(gl,['vs-x3d-default','fs-x3d-default']);}}
else if((x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.IndexedLineSet))||(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Circle2D))||(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Arc2D))||(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Polyline2D)))
{shape._webgl.primType=gl.LINES;if(shape._webgl.colors[0].length){shape._webgl.shader=this.getShaderProgram(gl,['vs-x3d-vertexcolorUnlit','fs-x3d-vertexcolorUnlit']);}
else{shape._webgl.shader=this.getShaderProgram(gl,['vs-x3d-default','fs-x3d-default']);}}
else{if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.ImageGeometry)){shape._webgl.primType=[];for(var i=0;i<shape._cf.geometry.node._vf.primType.length;i++){if(shape._cf.geometry.node._vf.primType[i].toUpperCase()=='POINTS'){shape._webgl.primType.push(gl.POINTS);}else if(shape._cf.geometry.node._vf.primType[i].toUpperCase()=='TRIANGLESTRIP'){shape._webgl.primType.push(gl.TRIANGLE_STRIP);}else{shape._webgl.primType.push(gl.TRIANGLES);}}}else{shape._webgl.primType=gl.TRIANGLES;}
if(shape._cf.appearance.node._shader!==null){if(x3dom.isa(shape._cf.appearance.node._shader,x3dom.nodeTypes.CommonSurfaceShader)){var texCnt=0;var cssMode=0;var cssShader=shape._cf.appearance.node._shader;var diffuseTex=cssShader.getDiffuseMap();var normalTex=cssShader.getNormalMap();var specularTex=cssShader.getSpecularMap();if(diffuseTex!=null){shape.updateTexture(diffuseTex,texCnt++,"false");}
if(normalTex!=null){shape.updateTexture(normalTex,texCnt++,"false");}
if(specularTex!=null){shape.updateTexture(specularTex,texCnt++,"false");}
if(x3dom.caps.MOBILE){x3dom.debug.logWarning("No mobile shader for CommonSurfaceShader! Using high quality shader!");}
shape._webgl.shader=this.getShaderProgram(gl,[this.generateVS(viewarea,shape),this.generateFS(viewarea,shape)]);}else{var hackID='HACK'+shape._objectID;g_shaders['vs-x3d-'+hackID]={};g_shaders['vs-x3d-'+hackID].type="vertex";g_shaders['vs-x3d-'+hackID].data=shape._cf.appearance.node._shader._vertex._vf.url[0];g_shaders['fs-x3d-'+hackID]={};g_shaders['fs-x3d-'+hackID].type="fragment";g_shaders['fs-x3d-'+hackID].data=shape._cf.appearance.node._shader._fragment._vf.url[0];shape._webgl.shader=getDefaultShaderProgram(gl,hackID);shape._dirty.shader=false;}}else{if(x3dom.caps.MOBILE){shape._webgl.shader=this.getShaderProgram(gl,[this.generateVSMobile(viewarea,shape),this.generateFSMobile(viewarea,shape)]);}else{shape._webgl.shader=this.getShaderProgram(gl,[this.generateVS(viewarea,shape),this.generateFS(viewarea,shape)]);}}}}
shape._dirty.shader=false;var sp=shape._webgl.shader;shape._webgl.buffers=[];for(q=0;q<shape._webgl.positions.length;q++)
{if(sp.position!==undefined)
{var indicesBuffer=gl.createBuffer();shape._webgl.buffers[5*q+0]=indicesBuffer;var indexArray=new Uint16Array(shape._webgl.indexes[q]);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indicesBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexArray,gl.STATIC_DRAW);indexArray=null;positionBuffer=gl.createBuffer();shape._webgl.buffers[5*q+1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);vertices=new Float32Array(shape._webgl.positions[q]);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);vertices=null;}
if(sp.normal!==undefined)
{var normalBuffer=gl.createBuffer();shape._webgl.buffers[5*q+2]=normalBuffer;var normals=new Float32Array(shape._webgl.normals[q]);gl.bindBuffer(gl.ARRAY_BUFFER,normalBuffer);gl.bufferData(gl.ARRAY_BUFFER,normals,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.normal,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.normal);normals=null;}
if(sp.texcoord!==undefined)
{var texcBuffer=gl.createBuffer();shape._webgl.buffers[5*q+3]=texcBuffer;var texCoords=new Float32Array(shape._webgl.texcoords[q]);gl.bindBuffer(gl.ARRAY_BUFFER,texcBuffer);gl.bufferData(gl.ARRAY_BUFFER,texCoords,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.texcoord,shape._cf.geometry.node._mesh._numTexComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);texCoords=null;}
if(sp.color!==undefined)
{colorBuffer=gl.createBuffer();shape._webgl.buffers[5*q+4]=colorBuffer;colors=new Float32Array(shape._webgl.colors[q]);gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);gl.bufferData(gl.ARRAY_BUFFER,colors,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.color,shape._cf.geometry.node._mesh._numColComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.color);colors=null;}}
var currAttribs=0;shape._webgl.dynamicFields=[];for(var df in shape._cf.geometry.node._mesh._dynamicFields)
{var attrib=shape._cf.geometry.node._mesh._dynamicFields[df];shape._webgl.dynamicFields[currAttribs]={buf:{},name:df,numComponents:attrib.numComponents};if(sp[df]!==undefined)
{var attribBuffer=gl.createBuffer();shape._webgl.dynamicFields[currAttribs++].buf=attribBuffer;var attribs=new Float32Array(attrib.value);gl.bindBuffer(gl.ARRAY_BUFFER,attribBuffer);gl.bufferData(gl.ARRAY_BUFFER,attribs,gl.STATIC_DRAW);gl.vertexAttribPointer(sp[df],attrib.numComponents,gl.FLOAT,false,0,0);attribs=null;}}
shape._webgl._minFilterDic={NEAREST:gl.NEAREST,LINEAR:gl.LINEAR,NEAREST_MIPMAP_NEAREST:gl.NEAREST_MIPMAP_NEAREST,NEAREST_MIPMAP_LINEAR:gl.NEAREST_MIPMAP_LINEAR,LINEAR_MIPMAP_NEAREST:gl.LINEAR_MIPMAP_NEAREST,LINEAR_MIPMAP_LINEAR:gl.LINEAR_MIPMAP_LINEAR,AVG_PIXEL:gl.LINEAR,AVG_PIXEL_AVG_MIPMAP:gl.LINEAR_MIPMAP_LINEAR,AVG_PIXEL_NEAREST_MIPMAP:gl.LINEAR_MIPMAP_NEAREST,DEFAULT:gl.LINEAR_MIPMAP_LINEAR,FASTEST:gl.NEAREST,NEAREST_PIXEL:gl.NEAREST,NEAREST_PIXEL_AVG_MIPMAP:gl.NEAREST_MIPMAP_LINEAR,NEAREST_PIXEL_NEAREST_MIPMAP:gl.NEAREST_MIPMAP_NEAREST,NICEST:gl.LINEAR_MIPMAP_LINEAR};shape._webgl._magFilterDic={NEAREST:gl.NEAREST,LINEAR:gl.LINEAR,AVG_PIXEL:gl.LINEAR,DEFAULT:gl.LINEAR,FASTEST:gl.NEAREST,NEAREST_PIXEL:gl.NEAREST,NICEST:gl.LINEAR};shape._webgl._boundaryModesDic={CLAMP:gl.CLAMP_TO_EDGE,CLAMP_TO_EDGE:gl.CLAMP_TO_EDGE,CLAMP_TO_BOUNDARY:gl.CLAMP_TO_EDGE,MIRRORED_REPEAT:gl.MIRRORED_REPEAT,REPEAT:gl.REPEAT};};Context.prototype.setupScene=function(gl,bgnd){var sphere;var texture;if(bgnd._webgl!==undefined)
{if(!bgnd._dirty){return;}
if(bgnd._webgl.texture!==undefined&&bgnd._webgl.texture)
{gl.deleteTexture(bgnd._webgl.texture);}
if(bgnd._webgl.shader.position!==undefined)
{gl.deleteBuffer(bgnd._webgl.buffers[1]);gl.deleteBuffer(bgnd._webgl.buffers[0]);}
if(bgnd._webgl.shader.texcoord!==undefined)
{gl.deleteBuffer(bgnd._webgl.buffers[2]);}
bgnd._webgl={};}
bgnd._dirty=false;var url=bgnd.getTexUrl();var i=0;var w=1,h=1;if(url.length>0&&url[0].length>0)
{if(url.length>=6&&url[1].length>0&&url[2].length>0&&url[3].length>0&&url[4].length>0&&url[5].length>0)
{sphere=new x3dom.nodeTypes.Sphere();bgnd._webgl={positions:sphere._mesh._positions[0],indexes:sphere._mesh._indices[0],buffers:[{},{}]};bgnd._webgl.primType=gl.TRIANGLES;bgnd._webgl.shader=this.getShaderProgram(gl,['vs-x3d-bg-textureCube','fs-x3d-bg-textureCube']);bgnd._webgl.texture=this.loadCubeMap(gl,url,bgnd._nameSpace.doc,true);}
else{texture=gl.createTexture();var image=new Image();image.onload=function(){bgnd._nameSpace.doc.needRender=true;bgnd._nameSpace.doc.downloadCount-=1;bgnd._webgl.texture=texture;gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,true);gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.bindTexture(gl.TEXTURE_2D,null);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,false);};image.onerror=function()
{bgnd._nameSpace.doc.downloadCount-=1;x3dom.debug.logError("Can't load tex url: "+url[0]);};image.src=bgnd._nameSpace.getURL(url[0]);bgnd._nameSpace.doc.downloadCount+=1;bgnd._webgl={positions:[-w,-h,0,-w,h,0,w,-h,0,w,h,0],indexes:[0,1,2,3],buffers:[{},{}]};bgnd._webgl.primType=gl.TRIANGLE_STRIP;bgnd._webgl.shader=this.getShaderProgram(gl,['vs-x3d-bg-texture','fs-x3d-bg-texture']);}}
else
{if(bgnd.getSkyColor().length>1||bgnd.getGroundColor().length)
{sphere=new x3dom.nodeTypes.Sphere();texture=gl.createTexture();bgnd._webgl={positions:sphere._mesh._positions[0],texcoords:sphere._mesh._texCoords[0],indexes:sphere._mesh._indices[0],buffers:[{},{},{}],texture:texture,primType:gl.TRIANGLES};var N=nextHighestPowerOfTwo(bgnd.getSkyColor().length+bgnd.getGroundColor().length+2);N=(N<512)?512:N;var n=bgnd._vf.groundAngle.length;var tmp=[],arr=[];var colors=[],sky=[0];for(i=0;i<bgnd._vf.skyColor.length;i++){colors[i]=bgnd._vf.skyColor[i];}
for(i=0;i<bgnd._vf.skyAngle.length;i++){sky[i+1]=bgnd._vf.skyAngle[i];}
if(n>0){if(sky[sky.length-1]<Math.PI/2){sky[sky.length]=Math.PI/2-x3dom.fields.Eps;colors[colors.length]=colors[colors.length-1];}
for(i=n-1;i>=0;i--){if((i==n-1)&&(Math.PI-bgnd._vf.groundAngle[i]<=Math.PI/2)){sky[sky.length]=Math.PI/2;colors[colors.length]=bgnd._vf.groundColor[bgnd._vf.groundColor.length-1];}
sky[sky.length]=Math.PI-bgnd._vf.groundAngle[i];colors[colors.length]=bgnd._vf.groundColor[i+1];}
sky[sky.length]=Math.PI;colors[colors.length]=bgnd._vf.groundColor[0];}
else{if(sky[sky.length-1]<Math.PI){sky[sky.length]=Math.PI;colors[colors.length]=colors[colors.length-1];}}
for(i=0;i<sky.length;i++){sky[i]/=Math.PI;}
x3dom.debug.assert(sky.length==colors.length);var interp=new x3dom.nodeTypes.ColorInterpolator();interp._vf.key=new x3dom.fields.MFFloat(sky);interp._vf.keyValue=new x3dom.fields.MFColor(colors);for(i=0;i<N;i++){var fract=i/(N-1.0);interp._fieldWatchers.set_fraction[0].call(interp,fract);tmp[i]=interp._vf.value_changed;}
tmp.reverse();for(i=0;i<tmp.length;i++){arr[3*i+0]=Math.floor(tmp[i].r*255);arr[3*i+1]=Math.floor(tmp[i].g*255);arr[3*i+2]=Math.floor(tmp[i].b*255);}
var pixels=new Uint8Array(arr);var format=gl.RGB;N=(pixels.length)/3;gl.bindTexture(gl.TEXTURE_2D,texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);gl.texImage2D(gl.TEXTURE_2D,0,format,1,N,0,format,gl.UNSIGNED_BYTE,pixels);gl.bindTexture(gl.TEXTURE_2D,null);bgnd._webgl.shader=this.getShaderProgram(gl,['vs-x3d-bg-texture-bgnd','fs-x3d-bg-texture']);}
else
{bgnd._webgl={};}}
if(bgnd._webgl.shader)
{var sp=bgnd._webgl.shader;var positionBuffer=gl.createBuffer();bgnd._webgl.buffers[1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);var vertices=new Float32Array(bgnd._webgl.positions);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);var indicesBuffer=gl.createBuffer();bgnd._webgl.buffers[0]=indicesBuffer;var indexArray=new Uint16Array(bgnd._webgl.indexes);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indicesBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexArray,gl.STATIC_DRAW);vertices=null;indexArray=null;if(sp.texcoord!==undefined)
{var texcBuffer=gl.createBuffer();bgnd._webgl.buffers[2]=texcBuffer;var texcoords=new Float32Array(bgnd._webgl.texcoords);gl.bindBuffer(gl.ARRAY_BUFFER,texcBuffer);gl.bufferData(gl.ARRAY_BUFFER,texcoords,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.texcoord,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);texcoords=null;}}
bgnd._webgl.render=function(gl,mat_scene)
{var sp=bgnd._webgl.shader;if((sp!==undefined&&sp!==null)&&(sp.texcoord!==undefined&&sp.texcoord!==null)&&(bgnd._webgl.texture!==undefined&&bgnd._webgl.texture!==null))
{gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);gl.frontFace(gl.CCW);gl.disable(gl.CULL_FACE);gl.disable(gl.DEPTH_TEST);gl.disable(gl.BLEND);sp.bind();if(!sp.tex){sp.tex=0;}
sp.alpha=1.0;sp.modelViewProjectionMatrix=mat_scene.toGL();gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,bgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,bgnd._webgl.buffers[0]);gl.bindBuffer(gl.ARRAY_BUFFER,bgnd._webgl.buffers[1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);gl.bindBuffer(gl.ARRAY_BUFFER,bgnd._webgl.buffers[2]);gl.vertexAttribPointer(sp.texcoord,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);try{gl.drawElements(bgnd._webgl.primType,bgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);}
catch(e){x3dom.debug.logException("Render background: "+e);}
gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);gl.disableVertexAttribArray(sp.position);gl.disableVertexAttribArray(sp.texcoord);gl.clear(gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);}
else if(!sp||!bgnd._webgl.texture||(bgnd._webgl.texture.textureCubeReady!==undefined&&bgnd._webgl.texture.textureCubeReady!==true))
{var bgCol=bgnd.getSkyColor().toGL();bgCol[3]=1.0-bgnd.getTransparency();gl.clearColor(bgCol[0],bgCol[1],bgCol[2],bgCol[3]);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);}
else
{gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);gl.frontFace(gl.CCW);gl.disable(gl.CULL_FACE);gl.disable(gl.DEPTH_TEST);gl.disable(gl.BLEND);sp.bind();if(!sp.tex){sp.tex=0;}
if(bgnd._webgl.texture.textureCubeReady){sp.modelViewProjectionMatrix=mat_scene.toGL();gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_CUBE_MAP,bgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MAG_FILTER,gl.LINEAR);}
else{gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,bgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);}
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,bgnd._webgl.buffers[0]);gl.bindBuffer(gl.ARRAY_BUFFER,bgnd._webgl.buffers[1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);try{gl.drawElements(bgnd._webgl.primType,bgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);}
catch(e){x3dom.debug.logException("Render background: "+e);}
gl.disableVertexAttribArray(sp.position);if(bgnd._webgl.texture.textureCubeReady){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);}
else{gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);}
gl.clear(gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);}};};Context.prototype.setupFgnds=function(gl,scene)
{if(scene._fgnd!==undefined){return;}
var w=1,h=1;scene._fgnd={};scene._fgnd._webgl={positions:[-w,-h,0,-w,h,0,w,-h,0,w,h,0],indexes:[0,1,2,3],buffers:[{},{}]};scene._fgnd._webgl.primType=gl.TRIANGLE_STRIP;scene._fgnd._webgl.shader=this.getShaderProgram(gl,['vs-x3d-bg-texture','fs-x3d-bg-texture']);var sp=scene._fgnd._webgl.shader;var positionBuffer=gl.createBuffer();scene._fgnd._webgl.buffers[1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);var vertices=new Float32Array(scene._fgnd._webgl.positions);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);var indicesBuffer=gl.createBuffer();scene._fgnd._webgl.buffers[0]=indicesBuffer;var indexArray=new Uint16Array(scene._fgnd._webgl.indexes);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indicesBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexArray,gl.STATIC_DRAW);vertices=null;indexArray=null;scene._fgnd._webgl.render=function(gl,tex)
{scene._fgnd._webgl.texture=tex;gl.frontFace(gl.CCW);gl.disable(gl.CULL_FACE);gl.disable(gl.DEPTH_TEST);sp.bind();if(!sp.tex){sp.tex=0;}
gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,scene._fgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,scene._fgnd._webgl.buffers[0]);gl.bindBuffer(gl.ARRAY_BUFFER,scene._fgnd._webgl.buffers[1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);try{gl.drawElements(scene._fgnd._webgl.primType,scene._fgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);}
catch(e){x3dom.debug.logException("Render background: "+e);}
gl.disableVertexAttribArray(sp.position);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);};};Context.prototype.renderShadowPass=function(gl,scene,mat_light,mat_scene)
{gl.bindFramebuffer(gl.FRAMEBUFFER,scene._webgl.fboShadow.fbo);gl.viewport(0,0,scene._webgl.fboShadow.width,scene._webgl.fboShadow.height);gl.clearColor(1.0,1.0,1.0,1.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);gl.depthFunc(gl.LEQUAL);gl.enable(gl.DEPTH_TEST);gl.enable(gl.CULL_FACE);gl.disable(gl.BLEND);var sp=scene._webgl.shadowShader;sp.bind();var i,n=scene.drawableObjects.length;for(i=0;i<n;i++)
{var trafo=scene.drawableObjects[i][0];var shape=scene.drawableObjects[i][1];sp.modelViewMatrix=mat_light.mult(trafo).toGL();sp.modelViewProjectionMatrix=mat_scene.mult(trafo).toGL();for(var q=0;q<shape._webgl.positions.length;q++)
{if(sp.position!==undefined)
{gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[5*q+0]);gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);}
try{if(shape._webgl.indexes&&shape._webgl.indexes[q]){if(shape._webgl.imageGeometry){for(var v=0,offset=0;v<shape._cf.geometry.node._vf.vertexCount.length;v++){gl.drawArrays(shape._webgl.primType[v],offset,shape._cf.geometry.node._vf.vertexCount[v]);offset+=shape._cf.geometry.node._vf.vertexCount[v];}}else{gl.drawElements(shape._webgl.primType,shape._webgl.indexes[q].length,gl.UNSIGNED_SHORT,0);}}}
catch(e){x3dom.debug.logException(shape._DEF+" renderShadowPass(): "+e);}
if(sp.position!==undefined){gl.disableVertexAttribArray(sp.position);}}}
gl.flush();gl.bindFramebuffer(gl.FRAMEBUFFER,null);};Context.prototype.renderPickingPass=function(gl,scene,mat_view,mat_scene,min,max,pickMode,lastX,lastY)
{gl.bindFramebuffer(gl.FRAMEBUFFER,scene._webgl.fboPick.fbo);gl.viewport(0,0,scene._webgl.fboPick.width,scene._webgl.fboPick.height);gl.clearColor(0.0,0.0,0.0,1.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);gl.depthFunc(gl.LEQUAL);gl.enable(gl.DEPTH_TEST);gl.enable(gl.CULL_FACE);gl.disable(gl.BLEND);var sp;if(pickMode===0)
{if(scene._webgl.imageGeometry)
{sp=scene._webgl.pickShaderIG;}
else
{sp=scene._webgl.pickShader;}}
else if(pickMode===1)
{sp=scene._webgl.pickColorShader;}
else if(pickMode===2)
{sp=scene._webgl.pickTexCoordShader;}
sp.bind();for(var i=0;i<scene.drawableObjects.length;i++)
{var trafo=scene.drawableObjects[i][0];var shape=scene.drawableObjects[i][1];if(shape._objectID<1||shape._webgl===undefined){continue;}
sp.modelMatrix=trafo.toGL();sp.modelViewProjectionMatrix=mat_scene.mult(trafo).toGL();sp.wcMin=min.toGL();sp.wcMax=max.toGL();sp.alpha=1.0-shape._objectID/255.0;sp.imageGeometry=0.0;if(shape._webgl.imageGeometry)
{sp.imageGeometry=1.0;sp.IG_bboxMin=shape._cf.geometry.node.getMin().toGL();sp.IG_bboxMax=shape._cf.geometry.node.getMax().toGL();sp.IG_coordTextureWidth=shape._webgl.coordTextureWidth;sp.IG_coordTextureHeight=shape._webgl.coordTextureHeight;if(shape._webgl.indexedImageGeometry){sp.indexed=1.0;sp.IG_indexTextureWidth=shape._webgl.indexTextureWidth;sp.IG_indexTextureHeight=shape._webgl.indexTextureHeight;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,shape._webgl.texture[1]);gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,shape._webgl.texture[2]);}else{sp.indexed=0.0;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,shape._webgl.texture[1]);}
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);var texUnit=0;if(shape._cf.geometry.node.getIndexTexture()){if(!sp.IG_indexTexture){sp.IG_indexTexture=texUnit++;}}
if(shape._cf.geometry.node.getCoordinateTexture(0)){if(!sp.IG_coordinateTexture){sp.IG_coordinateTexture=texUnit++;}}}
for(var q=0;q<shape._webgl.positions.length;q++)
{if(sp.position!==undefined)
{gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[5*q+0]);gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);}
if(sp.color!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+4]);gl.vertexAttribPointer(sp.color,shape._cf.geometry.node._mesh._numColComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.color);}
if(sp.texcoord!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+3]);gl.vertexAttribPointer(sp.texcoord,shape._cf.geometry.node._mesh._numTexComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);}
if(shape.isSolid()){gl.enable(gl.CULL_FACE);if(shape.isCCW()){gl.frontFace(gl.CCW);}
else{gl.frontFace(gl.CW);}}
else{gl.disable(gl.CULL_FACE);}
try{if(shape._webgl.indexes&&shape._webgl.indexes[q]){if(shape._webgl.imageGeometry){for(var v=0,offset=0;v<shape._cf.geometry.node._vf.vertexCount.length;v++){gl.drawArrays(shape._webgl.primType[v],offset,shape._cf.geometry.node._vf.vertexCount[v]);offset+=shape._cf.geometry.node._vf.vertexCount[v];}}else{gl.drawElements(shape._webgl.primType,shape._webgl.indexes[q].length,gl.UNSIGNED_SHORT,0);}}}
catch(e){x3dom.debug.logException(shape._DEF+" renderPickingPass(): "+e);}
if(sp.position!==undefined){gl.disableVertexAttribArray(sp.position);}
if(sp.color!==undefined){gl.disableVertexAttribArray(sp.color);}
if(sp.texcoord!==undefined){gl.disableVertexAttribArray(sp.texcoord);}}}
gl.flush();try{var x=lastX*scene._webgl.pickScale,y=scene._webgl.fboPick.height-1-lastY*scene._webgl.pickScale;var data=new Uint8Array(4);gl.readPixels(x,y,1,1,gl.RGBA,gl.UNSIGNED_BYTE,data);scene._webgl.fboPick.pixelData=data;}
catch(se){scene._webgl.fboPick.pixelData=[];x3dom.debug.logException(se+" (cannot pick)");}
gl.bindFramebuffer(gl.FRAMEBUFFER,null);};Context.prototype.renderShape=function(transform,shape,viewarea,slights,numLights,mat_view,mat_scene,mat_light,gl,activeTex,oneShadowExistsAlready)
{if(shape._webgl===undefined){return;}
var tex=null;var scene=viewarea._scene;var sp=shape._webgl.shader;if(!sp){shape._webgl.shader=getDefaultShaderProgram(gl,'default');sp=shape._webgl.shader;}
sp.bind();if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)){sp.useText=1.0;}else{sp.useText=0.0;}
if(shape._webgl.imageGeometry){sp.IG_bboxMin=shape._cf.geometry.node.getMin().toGL();sp.IG_bboxMax=shape._cf.geometry.node.getMax().toGL();sp.IG_coordTextureWidth=shape._webgl.coordTextureWidth;sp.IG_coordTextureHeight=shape._webgl.coordTextureHeight;if(shape._webgl.indexedImageGeometry){sp.IG_indexTextureWidth=shape._webgl.indexTextureWidth;sp.IG_indexTextureHeight=shape._webgl.indexTextureHeight;}}
var fog=scene.getFog();if(fog){if(x3dom.caps.MOBILE){sp.fogColor=fog._vf.color.toGL();sp.fogRange=fog._vf.visibilityRange;sp.fogType=(fog._vf.fogType=="LINEAR")?0.0:1.0;}else{sp['fog.color']=fog._vf.color.toGL();sp['fog.visibilityRange']=fog._vf.visibilityRange;sp['fog.fogType']=(fog._vf.fogType=="LINEAR")?0.0:1.0;}}
var mat=shape._cf.appearance.node._cf.material.node;var shaderCSS=shape._cf.appearance.node._shader;if(shaderCSS!==null&&x3dom.isa(shaderCSS,x3dom.nodeTypes.CommonSurfaceShader)){sp['material.diffuseColor']=shaderCSS._vf.diffuseFactor.toGL();sp['material.specularColor']=shaderCSS._vf.specularFactor.toGL();sp['material.emissiveColor']=shaderCSS._vf.emissiveFactor.toGL();sp['material.shininess']=shaderCSS._vf.shininessFactor;sp['material.ambientIntensity']=(shaderCSS._vf.ambientFactor.x+
shaderCSS._vf.ambientFactor.y+
shaderCSS._vf.ambientFactor.z)/3;sp['material.transparency']=1.0-shaderCSS._vf.alphaFactor;}
else{shaderCSS=null;if(x3dom.caps.MOBILE){sp.diffuseColor=mat._vf.diffuseColor.toGL();sp.specularColor=mat._vf.specularColor.toGL();sp.emissiveColor=mat._vf.emissiveColor.toGL();sp.shininess=mat._vf.shininess;sp.ambientIntensity=mat._vf.ambientIntensity;sp.transparency=mat._vf.transparency;}else{sp['material.diffuseColor']=mat._vf.diffuseColor.toGL();sp['material.specularColor']=mat._vf.specularColor.toGL();sp['material.emissiveColor']=mat._vf.emissiveColor.toGL();sp['material.shininess']=mat._vf.shininess;sp['material.ambientIntensity']=mat._vf.ambientIntensity;sp['material.transparency']=mat._vf.transparency;}}
sp.alpha=1.0-mat._vf.transparency;if(numLights>0)
{if(numLights>8){x3dom.debug.logWarning("Too many lights! Only 8 lights supported!");numLights=8;}
for(var p=0;p<numLights;p++){if(x3dom.isa(slights[p],x3dom.nodeTypes.DirectionalLight))
{if(x3dom.caps.MOBILE){sp['Light'+p+'_Type']=0.0;sp['Light'+p+'_On']=(slights[p]._vf.on)?1.0:0.0;sp['Light'+p+'_Color']=slights[p]._vf.color.toGL();sp['Light'+p+'_Intensity']=slights[p]._vf.intensity;sp['Light'+p+'_AmbientIntensity']=slights[p]._vf.ambientIntensity;sp['Light'+p+'_Direction']=mat_view.multMatrixVec(slights[p]._vf.direction).toGL();sp['Light'+p+'_Attenuation']=[1.0,1.0,1.0];sp['Light'+p+'_Location']=[1.0,1.0,1.0];sp['Light'+p+'_Radius']=0.0;sp['Light'+p+'_BeamWidth']=0.0;sp['Light'+p+'_CutOffAngle']=0.0;sp['Light'+p+'_shadowIntensity']=slights[p]._vf.shadowIntensity;}else{sp['light['+p+'].type']=0.0;sp['light['+p+'].on']=(slights[p]._vf.on)?1.0:0.0;sp['light['+p+'].color']=slights[p]._vf.color.toGL();sp['light['+p+'].intensity']=slights[p]._vf.intensity;sp['light['+p+'].ambientIntensity']=slights[p]._vf.ambientIntensity;sp['light['+p+'].direction']=mat_view.multMatrixVec(slights[p]._vf.direction).toGL();sp['light['+p+'].attenuation']=[1.0,1.0,1.0];sp['light['+p+'].location']=[1.0,1.0,1.0];sp['light['+p+'].radius']=0.0;sp['light['+p+'].beamWidth']=0.0;sp['light['+p+'].cutOffAngle']=0.0;sp['light['+p+'].shadowIntensity']=slights[p]._vf.shadowIntensity;}}
else if(x3dom.isa(slights[p],x3dom.nodeTypes.PointLight))
{if(x3dom.caps.MOBILE){sp['Light'+p+'_Type']=1.0;sp['Light'+p+'_On']=(slights[p]._vf.on)?1.0:0.0;sp['Light'+p+'_Color']=slights[p]._vf.color.toGL();sp['Light'+p+'_Intensity']=slights[p]._vf.intensity;sp['Light'+p+'_AmbientIntensity']=slights[p]._vf.ambientIntensity;sp['Light'+p+'_Direction']=[1.0,1.0,1.0];sp['Light'+p+'_Attenuation']=slights[p]._vf.attenuation.toGL();sp['Light'+p+'_Location']=mat_view.multMatrixPnt(slights[p]._vf.location).toGL();sp['Light'+p+'_Radius']=slights[p]._vf.radius;sp['Light'+p+'_BeamWidth']=0.0;sp['Light'+p+'_CutOffAngle']=0.0;sp['Light'+p+'_shadowIntensity']=slights[p]._vf.shadowIntensity;}else{sp['light['+p+'].type']=1.0;sp['light['+p+'].on']=(slights[p]._vf.on)?1.0:0.0;sp['light['+p+'].color']=slights[p]._vf.color.toGL();sp['light['+p+'].intensity']=slights[p]._vf.intensity;sp['light['+p+'].ambientIntensity']=slights[p]._vf.ambientIntensity;sp['light['+p+'].direction']=[1.0,1.0,1.0];sp['light['+p+'].attenuation']=slights[p]._vf.attenuation.toGL();sp['light['+p+'].location']=mat_view.multMatrixPnt(slights[p]._vf.location).toGL();sp['light['+p+'].radius']=slights[p]._vf.radius;sp['light['+p+'].beamWidth']=0.0;sp['light['+p+'].cutOffAngle']=0.0;sp['light['+p+'].shadowIntensity']=slights[p]._vf.shadowIntensity;}}
else if(x3dom.isa(slights[p],x3dom.nodeTypes.SpotLight))
{if(x3dom.caps.MOBILE){sp['Light'+p+'_Type']=2.0;sp['Light'+p+'_On']=(slights[p]._vf.on)?1.0:0.0;sp['Light'+p+'_Color']=slights[p]._vf.color.toGL();sp['Light'+p+'_Intensity']=slights[p]._vf.intensity;sp['Light'+p+'_AmbientIntensity']=slights[p]._vf.ambientIntensity;sp['Light'+p+'_Direction']=mat_view.multMatrixVec(slights[p]._vf.direction).toGL();sp['Light'+p+'_Attenuation']=slights[p]._vf.attenuation.toGL();sp['Light'+p+'_Location']=mat_view.multMatrixPnt(slights[p]._vf.location).toGL();sp['Light'+p+'_Radius']=slights[p]._vf.radius;sp['Light'+p+'_BeamWidth']=slights[p]._vf.beamWidth;sp['Light'+p+'_CutOffAngle']=slights[p]._vf.cutOffAngle;sp['Light'+p+'_shadowIntensity']=slights[p]._vf.shadowIntensity;}else{sp['light['+p+'].type']=2.0;sp['light['+p+'].on']=(slights[p]._vf.on)?1.0:0.0;sp['light['+p+'].color']=slights[p]._vf.color.toGL();sp['light['+p+'].intensity']=slights[p]._vf.intensity;sp['light['+p+'].ambientIntensity']=slights[p]._vf.ambientIntensity;sp['light['+p+'].direction']=mat_view.multMatrixVec(slights[p]._vf.direction).toGL();sp['light['+p+'].attenuation']=slights[p]._vf.attenuation.toGL();sp['light['+p+'].location']=mat_view.multMatrixPnt(slights[p]._vf.location).toGL();sp['light['+p+'].radius']=slights[p]._vf.radius;sp['light['+p+'].beamWidth']=slights[p]._vf.beamWidth;sp['light['+p+'].cutOffAngle']=slights[p]._vf.cutOffAngle;sp['light['+p+'].shadowIntensity']=slights[p]._vf.shadowIntensity;}}}}
var nav=scene.getNavigationInfo();if(nav._vf.headlight){numLights=(numLights)?numLights:0;if(x3dom.caps.MOBILE){sp['Light'+numLights+'_Type']=0.0;sp['Light'+numLights+'_On']=1.0;sp['Light'+numLights+'_Color']=[1.0,1.0,1.0];sp['Light'+numLights+'_Intensity']=1.0;sp['Light'+numLights+'_AmbientIntensity']=0.0;sp['Light'+numLights+'_Direction']=[0.0,0.0,-1.0];sp['Light'+numLights+'_Attenuation']=[1.0,1.0,1.0];sp['Light'+numLights+'_Location']=[1.0,1.0,1.0];sp['Light'+numLights+'_Radius']=0.0;sp['Light'+numLights+'_BeamWidth']=0.0;sp['Light'+numLights+'_CutOffAngle']=0.0;}else{sp['light['+numLights+'].type']=0.0;sp['light['+numLights+'].on']=1.0;sp['light['+numLights+'].color']=[1.0,1.0,1.0];sp['light['+numLights+'].intensity']=1.0;sp['light['+numLights+'].ambientIntensity']=0.0;sp['light['+numLights+'].direction']=[0.0,0.0,-1.0];sp['light['+numLights+'].attenuation']=[1.0,1.0,1.0];sp['light['+numLights+'].location']=[1.0,1.0,1.0];sp['light['+numLights+'].radius']=0.0;sp['light['+numLights+'].beamWidth']=0.0;sp['light['+numLights+'].cutOffAngle']=0.0;}}
var userShader=shape._cf.appearance.node._shader;if(userShader){for(var fName in userShader._vf){if(userShader._vf.hasOwnProperty(fName)&&fName!=='language'){var field=userShader._vf[fName];try{sp[fName]=field.toGL();}
catch(noToGl){sp[fName]=field;}}}}
var model_view=mat_view.mult(transform);sp.modelViewMatrix=model_view.toGL();sp.normalMatrix=model_view.inverse().transpose().toGL();sp.viewMatrix=mat_view.toGL();sp.modelViewMatrixInverse=model_view.inverse().toGL();sp.modelViewProjectionMatrix=mat_scene.mult(transform).toGL();for(var cnt=0;shape._webgl.texture!==undefined&&cnt<shape._webgl.texture.length;cnt++)
{if(shape._webgl.texture[cnt])
{if(shape._cf.appearance.node._cf.texture.node){tex=shape._cf.appearance.node._cf.texture.node.getTexture(cnt);}
if(tex){sp.origChannelCount=tex._vf.origChannelCount;}
var wrapS=gl.REPEAT,wrapT=gl.REPEAT;var minFilter=gl.LINEAR,magFilter=gl.LINEAR;var genMipMaps=false;if(shape._webgl.textureFilter){minFilter=shape._webgl.textureFilter[cnt];magFilter=shape._webgl.textureFilter[cnt];}
if(tex&&tex._cf.textureProperties.node!==null)
{var texProp=tex._cf.textureProperties.node;wrapS=shape._webgl._boundaryModesDic[texProp._vf.boundaryModeS.toUpperCase()];wrapT=shape._webgl._boundaryModesDic[texProp._vf.boundaryModeT.toUpperCase()];minFilter=shape._webgl._minFilterDic[texProp._vf.minificationFilter.toUpperCase()];magFilter=shape._webgl._magFilterDic[texProp._vf.magnificationFilter.toUpperCase()];if(texProp._vf.generateMipMaps===true)
{if(minFilter==gl.NEAREST)
minFilter=gl.NEAREST_MIPMAP_NEAREST;if(minFilter==gl.LINEAR)
minFilter=gl.LINEAR_MIPMAP_LINEAR;genMipMaps=true;}
else
{if((minFilter==gl.LINEAR_MIPMAP_LINEAR)||(minFilter==gl.LINEAR_MIPMAP_NEAREST))
minFilter=gl.LINEAR;if((minFilter==gl.NEAREST_MIPMAP_LINEAR)||(minFilter==gl.NEAREST_MIPMAP_NEAREST))
minFilter=gl.NEAREST;}}
else
{if(tex&&tex._vf.repeatS===false){wrapS=gl.CLAMP_TO_EDGE;}
if(tex&&tex._vf.repeatT===false){wrapT=gl.CLAMP_TO_EDGE;}}
if(shape._webgl.texture[cnt].textureCubeReady&&tex&&x3dom.isa(tex,x3dom.nodeTypes.X3DEnvironmentTextureNode))
{gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_CUBE_MAP,shape._webgl.texture[cnt]);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_S,wrapS);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_T,wrapT);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MAG_FILTER,magFilter);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MIN_FILTER,minFilter);if(genMipMaps){gl.generateMipmap(gl.TEXTURE_CUBE_MAP);}}
else
{gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_2D,shape._webgl.texture[cnt]);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,wrapS);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,wrapT);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,magFilter);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,minFilter);if(genMipMaps){gl.generateMipmap(gl.TEXTURE_2D);}}
if(shape._cf.appearance.node._cf.textureTransform.node!==null)
{var texTrafo=shape._cf.appearance.node.texTransformMatrix();sp.texTrafoMatrix=texTrafo.toGL();}
if(shape._webgl.imageGeometry)
{var IG_texUnit=1;if(shape._cf.geometry.node.getIndexTexture()){if(!sp.IG_indexTexture){sp.IG_indexTexture=IG_texUnit++;}}
for(var i=0;i<shape._webgl.imageGeometry;i++){if(shape._cf.geometry.node.getCoordinateTexture(i)){if(!sp['IG_coordinateTexture'+i]){sp['IG_coordinateTexture'+i]=IG_texUnit++;}}}
if(shape._cf.geometry.node.getNormalTexture(0)){if(!sp.IG_normalTexture){sp.IG_normalTexture=IG_texUnit++;}}
if(shape._cf.geometry.node.getTexCoordTexture()){if(!sp.IG_texCoordTexture){sp.IG_texCoordTexture=IG_texUnit++;}}
if(shape._cf.geometry.node.getColorTexture()){if(!sp.IG_colorTexture){sp.IG_colorTexture=IG_texUnit++;}}}
if(shaderCSS){var texUnit=0;if(shaderCSS.getDiffuseMap()){if(!sp.tex){sp.tex=texUnit++;}}
if(shaderCSS.getNormalMap()){if(!sp.bump){sp.bump=texUnit++;}}
if(shaderCSS.getSpecularMap()){if(!sp.spec){sp.spec=texUnit++;}}}else{if(!sp.tex){sp.tex=0;}}}}
if(oneShadowExistsAlready)
{if(!sp.sh_tex){sp.sh_tex=cnt;}
gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_2D,scene._webgl.fboShadow.tex);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);sp.matPV=mat_light.mult(transform).toGL();}
var attrib;for(var df=0;df<shape._webgl.dynamicFields.length;df++)
{attrib=shape._webgl.dynamicFields[df];if(sp[attrib.name]!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,attrib.buf);gl.vertexAttribPointer(sp[attrib.name],attrib.numComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp[attrib.name]);}}
if(shape.isSolid()){gl.enable(gl.CULL_FACE);if(shape.isCCW()){gl.frontFace(gl.CCW);}
else{gl.frontFace(gl.CW);}}
else{gl.disable(gl.CULL_FACE);}
sp.solid=(shape.isSolid()?1.0:0.0);for(var q=0;q<shape._webgl.positions.length;q++)
{if(sp.position!==undefined)
{gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[5*q+0]);gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+1]);gl.vertexAttribPointer(sp.position,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);}
if(sp.normal!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+2]);gl.vertexAttribPointer(sp.normal,3,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.normal);}
if(sp.texcoord!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+3]);gl.vertexAttribPointer(sp.texcoord,shape._cf.geometry.node._mesh._numTexComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);}
if(sp.color!==undefined)
{gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5*q+4]);gl.vertexAttribPointer(sp.color,shape._cf.geometry.node._mesh._numColComponents,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.color);}
try{if(viewarea._points!==undefined&&viewarea._points){if(shape._webgl.imageGeometry){gl.drawElements(gl.POINTS,shape._cf.geometry.node._vf.vertexCount[0],gl.UNSIGNED_SHORT,0);}else{gl.drawElements(gl.POINTS,shape._webgl.indexes[q].length,gl.UNSIGNED_SHORT,0);}}
else{if(shape._webgl.primType==gl.POINTS){if(shape._webgl.imageGeometry){gl.drawArrays(gl.POINTS,0,shape._cf.geometry.node._vf.vertexCount[0]);}else{gl.drawArrays(gl.POINTS,0,shape._webgl.positions[q].length/3);}}
else{if(shape._webgl.indexes&&shape._webgl.indexes[q]){if(shape._webgl.imageGeometry){for(var i=0,offset=0;i<shape._cf.geometry.node._vf.vertexCount.length;i++){gl.drawArrays(shape._webgl.primType[i],offset,shape._cf.geometry.node._vf.vertexCount[i]);offset+=shape._cf.geometry.node._vf.vertexCount[i];}}else{gl.drawElements(shape._webgl.primType,shape._webgl.indexes[q].length,gl.UNSIGNED_SHORT,0);}}}}}
catch(e){x3dom.debug.logException(shape._DEF+" renderScene(): "+e);}
if(sp.position!==undefined){gl.disableVertexAttribArray(sp.position);}
if(sp.normal!==undefined){gl.disableVertexAttribArray(sp.normal);}
if(sp.texcoord!==undefined){gl.disableVertexAttribArray(sp.texcoord);}
if(sp.color!==undefined){gl.disableVertexAttribArray(sp.color);}}
if(shape._webgl.indexes&&shape._webgl.indexes[0]){if(shape._webgl.imageGeometry){for(var i=0;i<shape._cf.geometry.node._vf.vertexCount.length;i++)
this.numFaces+=shape._cf.geometry.node._vf.vertexCount[i]/3.0;}else{this.numFaces+=shape._cf.geometry.node._mesh._numFaces;}}
if(shape._webgl.imageGeometry){for(var i=0;i<shape._cf.geometry.node._vf.vertexCount.length;i++)
this.numCoords+=shape._cf.geometry.node._vf.vertexCount[i];}else{this.numCoords+=shape._cf.geometry.node._mesh._numCoords;}
for(cnt=0;shape._webgl.texture!==undefined&&cnt<shape._webgl.texture.length;cnt++)
{if(shape._webgl.texture[cnt])
{tex=null;if(shape._cf.appearance.node._cf.texture.node){tex=shape._cf.appearance.node._cf.texture.node.getTexture(cnt);}
if(shape._webgl.texture[cnt].textureCubeReady&&tex&&x3dom.isa(tex,x3dom.nodeTypes.X3DEnvironmentTextureNode))
{gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);}else{gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_2D,null);}}}
if(oneShadowExistsAlready){gl.activeTexture(activeTex[cnt]);gl.bindTexture(gl.TEXTURE_2D,null);}
for(df=0;df<shape._webgl.dynamicFields.length;df++){attrib=shape._webgl.dynamicFields[df];if(sp[attrib.name]!==undefined){gl.disableVertexAttribArray(sp[attrib.name]);}}};Context.prototype.pickValue=function(viewarea,x,y,viewMat,sceneMat)
{var gl=this.ctx3d;var scene=viewarea._scene;if(gl===null||scene===null||!scene._webgl||scene.drawableObjects===undefined||!scene.drawableObjects||scene._vf.pickMode.toLowerCase()==="box")
{return false;}
var mat_view,mat_scene;if(arguments.length>4){mat_view=viewMat;mat_scene=sceneMat;}
else{mat_view=viewarea._last_mat_view;mat_scene=viewarea._last_mat_scene;}
var pickMode=(scene._vf.pickMode.toLowerCase()==="color")?1:((scene._vf.pickMode.toLowerCase()==="texcoord")?2:0);var min=scene._lastMin;var max=scene._lastMax;this.renderPickingPass(gl,scene,mat_view,mat_scene,min,max,pickMode,x,y);var index=0;if(index>=0&&index<scene._webgl.fboPick.pixelData.length){var pickPos=new x3dom.fields.SFVec3f(0,0,0);var charMax=(pickMode>0)?1:255;pickPos.x=scene._webgl.fboPick.pixelData[index+0]/charMax;pickPos.y=scene._webgl.fboPick.pixelData[index+1]/charMax;pickPos.z=scene._webgl.fboPick.pixelData[index+2]/charMax;if(pickMode===0){pickPos=pickPos.multComponents(max.subtract(min)).add(min);}
var objId=255-scene._webgl.fboPick.pixelData[index+3];if(objId>0){viewarea._pickingInfo.pickPos=pickPos;viewarea._pickingInfo.pickObj=x3dom.nodeTypes.Shape.idMap.nodeID[objId];}
else{viewarea._pickingInfo.pickObj=null;viewarea._pickingInfo.lastClickObj=null;}}
return true;};Context.prototype.renderScene=function(viewarea)
{var gl=this.ctx3d;var scene=viewarea._scene;if(gl===null||scene===null)
{return;}
var rentex=viewarea._doc._nodeBag.renderTextures;var rt_tex,rtl_i,rtl_n=rentex.length;if(!scene._webgl)
{scene._webgl={};this.setupFgnds(gl,scene);scene._webgl.pickScale=0.5;scene._webgl._currFboWidth=Math.round(this.canvas.width*scene._webgl.pickScale);scene._webgl._currFboHeight=Math.round(this.canvas.height*scene._webgl.pickScale);scene._webgl.fboPick=this.initFbo(gl,scene._webgl._currFboWidth,scene._webgl._currFboHeight,true);scene._webgl.fboPick.pixelData=null;scene._webgl.pickShader=getDefaultShaderProgram(gl,'pick');scene._webgl.pickShaderIG=this.getShaderProgram(gl,['vs-x3d-pickIG','fs-x3d-pick']);scene._webgl.pickColorShader=getDefaultShaderProgram(gl,'vertexcolorUnlit');scene._webgl.pickTexCoordShader=getDefaultShaderProgram(gl,'texcoordUnlit');scene._webgl.fboShadow=this.initFbo(gl,1024,1024,false);scene._webgl.shadowShader=getDefaultShaderProgram(gl,'shadow');for(rtl_i=0;rtl_i<rtl_n;rtl_i++){rt_tex=rentex[rtl_i];rt_tex._webgl={};rt_tex._webgl.fbo=this.initFbo(gl,rt_tex._vf.dimensions[0],rt_tex._vf.dimensions[1],false);}
var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();scene.getVolume(min,max,true);scene._lastMin=min;scene._lastMax=max;viewarea._last_mat_view=x3dom.fields.SFMatrix4f.identity();viewarea._last_mat_scene=x3dom.fields.SFMatrix4f.identity();}
else
{var fboWidth=Math.round(this.canvas.width*scene._webgl.pickScale);var fboHeight=Math.round(this.canvas.height*scene._webgl.pickScale);if(scene._webgl._currFboWidth!==fboWidth||scene._webgl._currFboHeight!==fboHeight)
{scene._webgl._currFboWidth=fboWidth;scene._webgl._currFboHeight=fboHeight;scene._webgl.fboPick=this.initFbo(gl,fboWidth,fboHeight,true);scene._webgl.fboPick.pixelData=null;x3dom.debug.logInfo("Refreshed picking FBO to size ("+
(fboWidth)+", "+(fboHeight)+")");}}
var bgnd=scene.getBackground();this.setupScene(gl,bgnd);var t0,t1;this.numFaces=0;this.numCoords=0;scene.drawableObjects=null;scene.drawableObjects=[];scene.drawableObjects.LODs=[];scene.drawableObjects.Billboards=[];t0=new Date().getTime();scene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),scene.drawableObjects);t1=new Date().getTime()-t0;if(this.canvas.parent.statDiv){this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("traverse: "+t1));}
var mat_view=viewarea.getViewMatrix();if(!viewarea._last_mat_view.equals(mat_view))
{var e_viewpoint=viewarea._scene.getViewpoint();var e_eventType="viewpointChanged";try{if(e_viewpoint._xmlNode&&(e_viewpoint._xmlNode["on"+e_eventType]||e_viewpoint._xmlNode.hasAttribute("on"+e_eventType)||e_viewpoint._listeners[e_eventType]))
{var e_viewtrafo=e_viewpoint.getCurrentTransform();e_viewtrafo=e_viewtrafo.inverse().mult(mat_view);var e_mat=e_viewtrafo.inverse();var e_rotation=new x3dom.fields.Quaternion(0,0,1,0);e_rotation.setValue(e_mat);var e_translation=e_mat.e3();var e_event={target:e_viewpoint._xmlNode,type:e_eventType,matrix:e_viewtrafo,position:e_translation,orientation:e_rotation.toAxisAngle(),cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;}};e_viewpoint.callEvtHandler(e_eventType,e_event);}}
catch(e_e){x3dom.debug.logException(e_e);}}
viewarea._last_mat_view=mat_view;var mat_scene=viewarea.getWCtoCCMatrix();viewarea._last_mat_scene=mat_scene;t0=new Date().getTime();var zPos=[];var i,m,n=scene.drawableObjects.length;var center,trafo,obj3d;for(i=0;i<n;i++)
{trafo=scene.drawableObjects[i][0];obj3d=scene.drawableObjects[i][1];this.setupShape(gl,obj3d,viewarea);center=obj3d.getCenter();center=trafo.multMatrixPnt(center);center=mat_view.multMatrixPnt(center);zPos[i]=[i,center.z];}
zPos.sort(function(a,b){return a[1]-b[1];});m=scene.drawableObjects.Billboards.length;n=scene.drawableObjects.LODs.length;if(m||n){center=new x3dom.fields.SFVec3f(0,0,0);center=mat_view.inverse().multMatrixPnt(center);}
for(i=0;i<n;i++)
{trafo=scene.drawableObjects.LODs[i][0];obj3d=scene.drawableObjects.LODs[i][1];if(obj3d){obj3d._eye=trafo.inverse().multMatrixPnt(center);}}
for(i=0;i<m;i++)
{trafo=scene.drawableObjects.Billboards[i][0];obj3d=scene.drawableObjects.Billboards[i][1];if(obj3d){var mat_view_model=mat_view.mult(trafo);obj3d._eye=trafo.inverse().multMatrixPnt(center);obj3d._eyeViewUp=new x3dom.fields.SFVec3f(mat_view_model._10,mat_view_model._11,mat_view_model._12);obj3d._eyeLook=new x3dom.fields.SFVec3f(mat_view_model._20,mat_view_model._21,mat_view_model._22);}}
t1=new Date().getTime()-t0;if(this.canvas.parent.statDiv){this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("sort: "+t1));}
var slights=viewarea.getLights();var numLights=slights.length;var oneShadowExistsAlready=false;var mat_light;for(var p=0;p<numLights;p++){if(slights[p]._vf.shadowIntensity>0.0&&!oneShadowExistsAlready){oneShadowExistsAlready=true;t0=new Date().getTime();var lightMatrix=viewarea.getLightMatrix()[0];mat_light=viewarea.getWCtoLCMatrix(lightMatrix);this.renderShadowPass(gl,scene,lightMatrix,mat_light);t1=new Date().getTime()-t0;if(this.canvas.parent.statDiv){this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("shadow: "+t1));}}}
for(rtl_i=0;rtl_i<rtl_n;rtl_i++){this.renderRTPass(gl,viewarea,rentex[rtl_i]);}
t0=new Date().getTime();gl.viewport(0,0,this.canvas.width,this.canvas.height);bgnd._webgl.render(gl,mat_scene);gl.depthFunc(gl.LEQUAL);gl.enable(gl.DEPTH_TEST);gl.enable(gl.CULL_FACE);gl.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE);gl.enable(gl.BLEND);var activeTex=[gl.TEXTURE0,gl.TEXTURE1,gl.TEXTURE2,gl.TEXTURE3,gl.TEXTURE4,gl.TEXTURE5,gl.TEXTURE6,gl.TEXTURE7];for(i=0,n=zPos.length;i<n;i++)
{var obj=scene.drawableObjects[zPos[i][0]];var needEnableBlending=false;if(obj[1]._cf.appearance.node._cf.blendMode.node&&obj[1]._cf.appearance.node._cf.blendMode.node._vf.srcFactor.toLowerCase()==="none"&&obj[1]._cf.appearance.node._cf.blendMode.node._vf.destFactor.toLowerCase()==="none")
{needEnableBlending=true;gl.disable(gl.BLEND);}
this.renderShape(obj[0],obj[1],viewarea,slights,numLights,mat_view,mat_scene,mat_light,gl,activeTex,oneShadowExistsAlready);if(needEnableBlending){gl.enable(gl.BLEND);}}
gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);if(viewarea._visDbgBuf!==undefined&&viewarea._visDbgBuf)
{if(scene._vf.pickMode.toLowerCase()==="idbuf"||scene._vf.pickMode.toLowerCase()==="color"||scene._vf.pickMode.toLowerCase()==="texcoord"){gl.viewport(0,3*this.canvas.height/4,this.canvas.width/4,this.canvas.height/4);scene._fgnd._webgl.render(gl,scene._webgl.fboPick.tex);}
if(oneShadowExistsAlready){gl.viewport(this.canvas.width/4,3*this.canvas.height/4,this.canvas.width/4,this.canvas.height/4);scene._fgnd._webgl.render(gl,scene._webgl.fboShadow.tex);}}
gl.flush();t1=new Date().getTime()-t0;if(this.canvas.parent.statDiv){this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("render: "+t1));this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("#Tris: "+this.numFaces));this.canvas.parent.statDiv.appendChild(document.createElement("br"));this.canvas.parent.statDiv.appendChild(document.createTextNode("#Pnts: "+this.numCoords));}};Context.prototype.renderRTPass=function(gl,viewarea,rt)
{var scene=viewarea._scene;var bgnd=null;var mat_view=rt.getViewMatrix();var mat_scene=rt.getWCtoCCMatrix();var lightMatrix=viewarea.getLightMatrix()[0];var mat_light=viewarea.getWCtoLCMatrix(lightMatrix);var i,n,m=rt._cf.excludeNodes.nodes.length;var arr=new Array(m);for(i=0;i<m;i++){var render=rt._cf.excludeNodes.nodes[i]._vf.render;if(render===undefined){arr[i]=-1;}
else{if(render===true){arr[i]=1;}else{arr[i]=0;}}
rt._cf.excludeNodes.nodes[i]._vf.render=false;}
gl.bindFramebuffer(gl.FRAMEBUFFER,rt._webgl.fbo.fbo);gl.viewport(0,0,rt._webgl.fbo.width,rt._webgl.fbo.height);if(rt._cf.background.node===null)
{gl.clearColor(0,0,0,1);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);}
else if(rt._cf.background.node===scene.getBackground())
{bgnd=scene.getBackground();bgnd._webgl.render(gl,mat_scene);}
else
{bgnd=rt._cf.background.node;this.setupScene(gl,bgnd);bgnd._webgl.render(gl,mat_scene);}
gl.depthFunc(gl.LEQUAL);gl.enable(gl.DEPTH_TEST);gl.enable(gl.CULL_FACE);gl.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE);gl.enable(gl.BLEND);var slights=viewarea.getLights();var numLights=slights.length;var oneShadowExistsAlready=false;var activeTex=[gl.TEXTURE0,gl.TEXTURE1,gl.TEXTURE2,gl.TEXTURE3,gl.TEXTURE4,gl.TEXTURE5,gl.TEXTURE6,gl.TEXTURE7];var transform,shape;var locScene=rt._cf.scene.node;if(!locScene||locScene===scene)
{n=scene.drawableObjects.length;for(i=0;i<n;i++)
{transform=scene.drawableObjects[i][0];shape=scene.drawableObjects[i][1];if(shape._vf.render!==undefined&&shape._vf.render===false){continue;}
this.renderShape(transform,shape,viewarea,slights,numLights,mat_view,mat_scene,mat_light,gl,activeTex,oneShadowExistsAlready);}}
else
{locScene.drawableObjects=[];locScene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),locScene.drawableObjects);n=locScene.drawableObjects.length;for(i=0;i<n;i++)
{transform=locScene.drawableObjects[i][0];shape=locScene.drawableObjects[i][1];if(shape._vf.render!==undefined&&shape._vf.render===false){continue;}
this.setupShape(gl,shape,viewarea);this.renderShape(transform,shape,viewarea,slights,numLights,mat_view,mat_scene,mat_light,gl,activeTex,oneShadowExistsAlready);}}
gl.disable(gl.BLEND);gl.disable(gl.DEPTH_TEST);gl.flush();gl.bindFramebuffer(gl.FRAMEBUFFER,null);for(i=0;i<m;i++){if(arr[i]!==0){rt._cf.excludeNodes.nodes[i]._vf.render=true;}}};Context.prototype.shutdown=function(viewarea)
{var gl=this.ctx3d;var attrib;var scene;if(gl===null||scene===null||!scene||scene.drawableObjects===null){return;}
scene=viewarea._scene;scene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),scene.drawableObjects);var bgnd=scene.getBackground();if(bgnd._webgl.texture!==undefined&&bgnd._webgl.texture)
{gl.deleteTexture(bgnd._webgl.texture);}
if(bgnd._webgl.shader.position!==undefined)
{gl.deleteBuffer(bgnd._webgl.buffers[1]);gl.deleteBuffer(bgnd._webgl.buffers[0]);}
for(var i=0,n=scene.drawableObjects.length;i<n;i++)
{var shape=scene.drawableObjects[i][1];var sp=shape._webgl.shader;for(var cnt=0;shape._webgl.texture!==undefined&&cnt<shape._webgl.texture.length;cnt++)
{if(shape._webgl.texture[cnt])
{gl.deleteTexture(shape._webgl.texture[cnt]);}}
for(var q=0;q<shape._webgl.positions.length;q++)
{if(sp.position!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+1]);gl.deleteBuffer(shape._webgl.buffers[5*q+0]);}
if(sp.normal!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+2]);}
if(sp.texcoord!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+3]);}
if(sp.color!==undefined)
{gl.deleteBuffer(shape._webgl.buffers[5*q+4]);}}
for(var df=0;df<shape._webgl.dynamicFields.length;df++)
{attrib=shape._webgl.dynamicFields[df];if(sp[attrib.name]!==undefined)
{gl.deleteBuffer(attrib.buf);}}
shape._webgl=null;}};Context.prototype.loadCubeMap=function(gl,url,doc,bgnd)
{var texture=gl.createTexture();gl.bindTexture(gl.TEXTURE_CUBE_MAP,texture);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_CUBE_MAP,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);var faces;if(bgnd){faces=[gl.TEXTURE_CUBE_MAP_POSITIVE_Z,gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,gl.TEXTURE_CUBE_MAP_POSITIVE_Y,gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,gl.TEXTURE_CUBE_MAP_POSITIVE_X,gl.TEXTURE_CUBE_MAP_NEGATIVE_X];}
else{faces=[gl.TEXTURE_CUBE_MAP_NEGATIVE_Z,gl.TEXTURE_CUBE_MAP_POSITIVE_Z,gl.TEXTURE_CUBE_MAP_NEGATIVE_Y,gl.TEXTURE_CUBE_MAP_POSITIVE_Y,gl.TEXTURE_CUBE_MAP_NEGATIVE_X,gl.TEXTURE_CUBE_MAP_POSITIVE_X];}
texture.pendingTextureLoads=-1;texture.textureCubeReady=false;for(var i=0;i<faces.length;i++){var face=faces[i];var image=new Image();texture.pendingTextureLoads++;doc.downloadCount+=1;image.onload=function(texture,face,image,swap){return function(){gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,swap);gl.bindTexture(gl.TEXTURE_CUBE_MAP,texture);gl.texImage2D(face,0,gl.RGBA,gl.RGBA,gl.UNSIGNED_BYTE,image);gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,false);texture.pendingTextureLoads--;doc.downloadCount-=1;if(texture.pendingTextureLoads<0){texture.textureCubeReady=true;x3dom.debug.logInfo("Loading CubeMap finished...");doc.needRender=true;}};}(texture,face,image,(bgnd&&(i<=1||i>=4)));image.onerror=function()
{doc.downloadCount-=1;x3dom.debug.logError("Can't load CubeMap!");};image.src=url[i];}
return texture;};Context.prototype.emptyTexImage2D=function(gl,internalFormat,width,height,format,type)
{try{gl.texImage2D(gl.TEXTURE_2D,0,internalFormat,width,height,0,format,type,null);}
catch(e){var bytes=3;switch(internalFormat)
{case gl.DEPTH_COMPONENT:bytes=3;break;case gl.ALPHA:bytes=1;break;case gl.RGB:bytes=3;break;case gl.RGBA:bytes=4;break;case gl.LUMINANCE:bytes=1;break;case gl.LUMINANCE_ALPHA:bytes=2;break;}
var pixels=new Uint8Array(width*height*bytes);gl.texImage2D(gl.TEXTURE_2D,0,internalFormat,width,height,0,format,type,pixels);}};Context.prototype.initTex=function(gl,w,h,nearest)
{var tex=gl.createTexture();gl.bindTexture(gl.TEXTURE_2D,tex);this.emptyTexImage2D(gl,gl.RGBA,w,h,gl.RGBA,gl.UNSIGNED_BYTE);if(nearest){gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);}
else{gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);}
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_S,gl.CLAMP_TO_EDGE);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.CLAMP_TO_EDGE);gl.bindTexture(gl.TEXTURE_2D,null);tex.width=w;tex.height=h;return tex;};Context.prototype.initFbo=function(gl,w,h,nearest)
{var status=0;var fbo=gl.createFramebuffer();var rb=gl.createRenderbuffer();var tex=this.initTex(gl,w,h,nearest);gl.bindFramebuffer(gl.FRAMEBUFFER,fbo);gl.bindRenderbuffer(gl.RENDERBUFFER,rb);gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT16,w,h);gl.bindRenderbuffer(gl.RENDERBUFFER,null);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,tex,0);gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER,rb);gl.bindFramebuffer(gl.FRAMEBUFFER,null);status=gl.checkFramebufferStatus(gl.FRAMEBUFFER);x3dom.debug.logInfo("FBO-Status: "+status);var r={};r.fbo=fbo;r.rbo=rb;r.tex=tex;r.width=w;r.height=h;return r;};return setupContext;})();x3dom.bridge={setFlashReady:function(driver,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.isFlashReady=true;x3dom.debug.logInfo('Flash is ready for rendering ('+driver+')');},onMouseDown:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onMousePress(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onMouseUp:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onMouseRelease(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onMouseOver:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onMouseOver(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onMouseOut:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onMouseOut(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onDoubleClick:function(x,y,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onDoubleClick(x3dCanvas.gl,x,y);x3dCanvas.doc.needRender=true;x3dom.debug.logInfo("dblClick");},onMouseDrag:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onDrag(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onMouseMove:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onMove(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onMouseWheel:function(x,y,button,canvas){var x3dCanvas=x3dom.canvases[canvas];x3dCanvas.doc.onDrag(x3dCanvas.gl,x,y,button);x3dCanvas.doc.needRender=true;},onKeyDown:function(charCode,canvas){var x3dCanvas=x3dom.canvases[canvas];var keysEnabled=x3dCanvas.x3dElem.getAttribute("keysEnabled");if(!keysEnabled||keysEnabled.toLowerCase()==="true"){x3dCanvas.doc.onKeyPress(charCode);}
x3dCanvas.doc.needRender=true;}};x3dom.gfx_flash=(function(){function Context(object,name){this.object=object;this.name=name;};function setupContext(object){return new Context(object,'flash');};Context.prototype.getName=function(){return this.name;};Context.prototype.renderScene=function(viewarea){var scene=viewarea._scene;this.setupScene(scene,viewarea);var background=scene.getBackground();this.setupBackground(background);scene.drawableObjects=null;scene.drawableObjects=[];scene.drawableObjects.LODs=[];scene.drawableObjects.Billboards=[];scene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),scene.drawableObjects);var numDrawableObjects=scene.drawableObjects.length;if(numDrawableObjects>0)
{var RefList=[];for(var i=0;i<numDrawableObjects;i++)
{var trafo=scene.drawableObjects[i][0];var obj3d=scene.drawableObjects[i][1];if(RefList[obj3d._objectID]!=undefined){RefList[obj3d._objectID]++;}else{RefList[obj3d._objectID]=0;}
this.setupShape(obj3d,trafo,RefList[obj3d._objectID]);}}
this.object.renderScene();};Context.prototype.setupScene=function(scene,viewarea){var mat_view=viewarea.getViewMatrix();this.object.setViewMatrix({viewMatrix:mat_view.toGL()});var mat_proj=viewarea.getProjectionMatrix();this.object.setProjectionMatrix({projectionMatrix:mat_proj.toGL()});var nav=scene.getNavigationInfo();if(nav._vf.headlight){this.object.setLights({idx:0,type:0,on:1.0,color:[1.0,1.0,1.0],intensity:1.0,ambientIntensity:0.0,direction:[0.0,0.0,1.0],attenuation:[1.0,1.0,1.0],location:[1.0,1.0,1.0],radius:0.0,beamWidth:0.0,cutOffAngle:0.0});}
var lights=viewarea.getLights();for(var i=0;i<lights.length;i++){if(lights[i]._dirty){if(x3dom.isa(lights[i],x3dom.nodeTypes.DirectionalLight))
{x3dom.debug.logInfo(lights[i]._lightID);}
else if(x3dom.isa(lights[i],x3dom.nodeTypes.PointLight))
{}
else if(x3dom.isa(lights[i],x3dom.nodeTypes.SpotLight))
{}
lights[i]._dirty=false;}}};Context.prototype.setupBackground=function(background){if(background._dirty)
{this.object.setBackground({texURLs:background.getTexUrl(),skyAngle:background._vf.skyAngle,skyColor:background.getSkyColor().toGL(),groundAngle:background._vf.groundAngle,groundColor:background.getGroundColor().toGL(),transparency:background.getTransparency()});background._dirty=false;}};Context.prototype.setupShape=function(shape,trafo,refID){if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.PointSet)){x3dom.debug.logError("Flash backend don't support PointSets yet");return;}else if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.IndexedLineSet)){x3dom.debug.logError("Flash backend don't support LineSets yet");return;}else if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.Text)){this.setupText(shape,trafo,refID);}else{this.setupIndexedFaceSet(shape,trafo,refID);}};Context.prototype.setupIndexedFaceSet=function(shape,trafo,refID)
{this.object.setMeshTransform({id:shape._objectID,refID:refID,transform:trafo.toGL()});if(refID==0)
{var isImageGeometry=x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.ImageGeometry);if(shape._dirty.indexes===true){if(!isImageGeometry){for(var i=0;i<shape._cf.geometry.node._mesh._indices.length;i++){this.object.setMeshIndices({id:shape._objectID,idx:i,indices:shape._cf.geometry.node._mesh._indices[i]});}}
shape._dirty.indexes=false;}
if(shape._dirty.positions===true){if(!isImageGeometry){for(var i=0;i<shape._cf.geometry.node._mesh._positions.length;i++){this.object.setMeshVertices({id:shape._objectID,idx:i,vertices:shape._cf.geometry.node._mesh._positions[i]});}}else{this.object.setMeshVerticesTexture({id:shape._objectID,idx:0,bboxMin:shape._cf.geometry.node.getMin().toGL(),bboxMax:shape._cf.geometry.node.getMax().toGL(),bboxCenter:shape._cf.geometry.node.getCenter(),primType:shape._cf.geometry.node._vf.primType,vertexCount:shape._cf.geometry.node._vf.vertexCount,coordinateTexture0:shape._cf.geometry.node.getCoordinateTextureURL(0),coordinateTexture1:shape._cf.geometry.node.getCoordinateTextureURL(1)});}
shape._dirty.positions=false;}
if(shape._dirty.normals===true){if(!isImageGeometry){if(shape._cf.geometry.node._mesh._normals[0].length){for(var i=0;i<shape._cf.geometry.node._mesh._normals.length;i++){this.object.setMeshNormals({id:shape._objectID,idx:i,normals:shape._cf.geometry.node._mesh._normals[i]});}}}else{this.object.setMeshNormalsTexture({id:shape._objectID,idx:0,normalTexture:shape._cf.geometry.node.getNormalTextureURL(0)});}
shape._dirty.normals=false;}
if(shape._dirty.colors===true){if(!isImageGeometry){if(shape._cf.geometry.node._mesh._colors[0].length){for(var i=0;i<shape._cf.geometry.node._mesh._colors.length;i++){this.object.setMeshColors({id:shape._objectID,idx:i,colors:shape._cf.geometry.node._mesh._colors[i],components:shape._cf.geometry.node._mesh._numColComponents});}}}else{}
shape._dirty.colors=false;}
if(shape._dirty.texcoords===true){if(!isImageGeometry){if(shape._cf.geometry.node._mesh._texCoords[0].length){for(var i=0;i<shape._cf.geometry.node._mesh._texCoords.length;i++){this.object.setMeshTexCoords({id:shape._objectID,idx:i,texCoords:shape._cf.geometry.node._mesh._texCoords[i]});}}}else{this.object.setMeshTexCoordsTexture({id:shape._objectID,idx:0,texCoordTexture:shape._cf.geometry.node.getTexCoordTextureURL()});}
shape._dirty.texcoords=false;}
if(shape._dirty.material===true){var material=shape._cf.appearance.node._cf.material.node;this.object.setMeshMaterial({id:shape._objectID,ambientIntensity:material._vf.ambientIntensity,diffuseColor:material._vf.diffuseColor.toGL(),emissiveColor:material._vf.emissiveColor.toGL(),shininess:material._vf.shininess,specularColor:material._vf.specularColor.toGL(),transparency:material._vf.transparency});shape._dirty.material=false;}
if(shape._dirty.texture===true){var texture=shape._cf.appearance.node._cf.texture.node;if(texture){var childTex=(texture._video!==undefined&&texture._video!==null&&texture._needPerFrameUpdate!==undefined&&texture._needPerFrameUpdate===true);if(x3dom.isa(texture,x3dom.nodeTypes.PixelTexture))
{this.object.setPixelTexture({id:shape._objectID,width:texture._vf.image.width,height:texture._vf.image.height,comp:texture._vf.image.comp,pixels:texture._vf.image.toGL()});}else if(texture._isCanvas&&texture._canvas){}else if(x3dom.isa(texture,x3dom.nodeTypes.ComposedCubeMapTexture)){this.object.setCubeTexture({id:shape._objectID,texURLs:texture.getTexUrl()});}else if(x3dom.isa(texture,x3dom.nodeTypes.MultiTexture)){x3dom.debug.logError("Flash backend don't support MultiTextures yet");}else if(x3dom.isa(texture,x3dom.nodeTypes.MovieTexture)||childTex){x3dom.debug.logError("Flash backend don't support MovieTextures yet");}else{this.object.setMeshTexture({id:shape._objectID,origChannelCount:texture._vf.origChannelCount,repeatS:texture._vf.repeatS,repeatT:texture._vf.repeatT,url:texture._vf.url[0]});}}
shape._dirty.texture=false;}
this.object.setMeshSolid({id:shape._objectID,solid:shape.isSolid()});if(shape._cf.geometry.node._cf.texCoord!==undefined&&shape._cf.geometry.node._cf.texCoord.node!==null&&!x3dom.isa(shape._cf.geometry.node._cf.texCoord.node,x3dom.nodeTypes.X3DTextureNode)&&shape._cf.geometry.node._cf.texCoord.node._vf.mode)
{var texMode=shape._cf.geometry.node._cf.texCoord.node._vf.mode;if(texMode.toLowerCase()=="sphere"){this.object.setSphereMapping({id:shape._objectID,sphereMapping:1});}
else{this.object.setSphereMapping({id:shape._objectID,sphereMapping:0});}}
else{this.object.setSphereMapping({id:shape._objectID,sphereMapping:0});}}};Context.prototype.setupText=function(shape,trafo,refID)
{this.object.setMeshTransform({id:shape._objectID,refID:refID,transform:trafo.toGL()});if(refID==0)
{if(shape._dirty.text===true){var fontStyleNode=shape._cf.geometry.node._cf.fontStyle.node;if(fontStyleNode===null){this.object.setText({id:shape._objectID,text:shape._cf.geometry.node._vf.string,fontFamily:['SERIF'],fontStyle:"PLAIN",fontAlign:"BEGIN",fontSize:32,fontSpacing:1.0,fontHorizontal:true,fontLanguage:"",fontLeftToRight:true,fontTopToBottom:true});}else{this.object.setText({id:shape._objectID,text:shape._cf.geometry.node._vf.string,fontFamily:fontStyleNode._vf.family.toString(),fontStyle:fontStyleNode._vf.style.toString(),fontAlign:fontStyleNode._vf.justify.toString(),fontSize:fontStyleNode._vf.size,fontSpacing:fontStyleNode._vf.spacing,fontHorizontal:fontStyleNode._vf.horizontal,fontLanguage:fontStyleNode._vf.language,fontLeftToRight:fontStyleNode._vf.leftToRight,fontTopToBottom:fontStyleNode._vf.topToBottom});}
shape._dirty.text=false;}
if(shape._dirty.material===true){var material=shape._cf.appearance.node._cf.material.node;this.object.setMeshMaterial({id:shape._objectID,ambientIntensity:material._vf.ambientIntensity,diffuseColor:material._vf.diffuseColor.toGL(),emissiveColor:material._vf.emissiveColor.toGL(),shininess:material._vf.shininess,specularColor:material._vf.specularColor.toGL(),transparency:material._vf.transparency});shape._dirty.material=false;}
this.object.setMeshSolid({id:shape._objectID,solid:shape.isSolid()});}};Context.prototype.pickValue=function(viewarea,x,y,viewMat,sceneMat)
{var scene=viewarea._scene;if(this.object===null||scene===null||scene.drawableObjects===undefined||!scene.drawableObjects||scene._vf.pickMode.toLowerCase()==="box")
{return false;}
var pickMode=(scene._vf.pickMode.toLowerCase()==="color")?1:((scene._vf.pickMode.toLowerCase()==="texcoord")?2:0);var data=this.object.pickValue({pickMode:pickMode});if(data.objID>0){viewarea._pickingInfo.pickPos=new x3dom.fields.SFVec3f(data.pickPosX,data.pickPosY,data.pickPosZ);viewarea._pickingInfo.pickObj=x3dom.nodeTypes.Shape.idMap.nodeID[data.objID];}else{viewarea._pickingInfo.pickObj=null;viewarea._pickingInfo.lastClickObj=null;}
return true;};Context.prototype.shutdown=function(viewarea)
{};return setupContext;})();x3dom.X3DDocument=function(canvas,ctx,settings){this.properties=settings;this.canvas=canvas;this.ctx=ctx;this.needRender=true;this._scene=null;this._viewarea=null;this._nodeBag={timer:[],lights:[],clipPlanes:[],followers:[],trans:[],renderTextures:[],viewarea:[]};this.downloadCount=0;this.onload=function(){};this.onerror=function(){};};x3dom.X3DDocument.prototype.load=function(uri,sceneElemPos){var uri_docs={};var queued_uris=[uri];var doc=this;function next_step(){if(queued_uris.length===0){doc._setup(uri_docs[uri],uri_docs,sceneElemPos);doc.onload();return;}
var next_uri=queued_uris.shift();if(x3dom.isX3DElement(next_uri)&&(next_uri.localName.toLowerCase()==='x3d'||next_uri.localName.toLowerCase()==='websg'))
{uri_docs[next_uri]=next_uri;next_step();}}
next_step();};x3dom.findScene=function(x3dElem){var sceneElems=[];for(var i=0;i<x3dElem.childNodes.length;i++){var sceneElem=x3dElem.childNodes[i];if(sceneElem&&sceneElem.localName&&sceneElem.localName.toLowerCase()==="scene"){sceneElems.push(sceneElem);}}
if(sceneElems.length>1){x3dom.debug.logError("X3D element has more than one Scene child (has "+
x3dElem.childNodes.length+").");}
else{return sceneElems[0];}
return null;};x3dom.X3DDocument.prototype._setup=function(sceneDoc,uriDocs,sceneElemPos){var doc=this;var domEventListener={onAttrModified:function(e){if('_x3domNode'in e.target){var attrToString={1:"MODIFICATION",2:"ADDITION",3:"REMOVAL"};e.target._x3domNode.updateField(e.attrName,e.newValue);doc.needRender=true;}},onNodeRemoved:function(e){if('_x3domNode'in e.target.parentNode&&'_x3domNode'in e.target){var parent=e.target.parentNode._x3domNode;var child=e.target._x3domNode;if(parent){parent.removeChild(child);doc.needRender=true;}}},onNodeInserted:function(e){if('_x3domNode'in e.target.parentNode){if(e.target.parentNode.tagName=='Inline'||e.target.parentNode.tagName=='INLINE'||e.target.parentNode.tagName=='inline'){return;}else{var parent=e.target.parentNode._x3domNode;var child=e.target;if(parent._nameSpace){var newNode=parent._nameSpace.setupTree(child);parent.addChild(newNode,child.getAttribute("containerField"));doc.needRender=true;}
else{x3dom.debug.logWarning("No _nameSpace in onNodeInserted");}}}}};sceneDoc.addEventListener('DOMNodeRemoved',domEventListener.onNodeRemoved,true);sceneDoc.addEventListener('DOMNodeInserted',domEventListener.onNodeInserted,true);if((x3dom.userAgentFeature.supportsDOMAttrModified===true)){sceneDoc.addEventListener('DOMAttrModified',domEventListener.onAttrModified,true);}
var sceneElem=x3dom.findScene(sceneDoc);this._bindableBag=new x3dom.BindableBag(this);var nameSpace=new x3dom.NodeNameSpace("scene",doc);var scene=nameSpace.setupTree(sceneElem);this._scene=scene;this._bindableBag.setRefNode(scene);this._viewarea=new x3dom.Viewarea(this,scene);this._viewarea._width=this.canvas.width;this._viewarea._height=this.canvas.height;};x3dom.X3DDocument.prototype.advanceTime=function(t){var that;var i;if(this._nodeBag.timer.length){this.needRender=true;for(i=0;i<this._nodeBag.timer.length;i++){this._nodeBag.timer[i].onframe(t);}}
if(this._nodeBag.followers.length){that=this;for(i=0;i<this._nodeBag.followers.length;i++){this.needRender|=this._nodeBag.followers[i].tick(t);}}
if(this._nodeBag.trans.length){that=this;for(i=0;i<this._nodeBag.trans.length;i++){this.needRender|=this._nodeBag.trans[i].tick(t);}}
if(this._nodeBag.viewarea.length){that=this;for(i=0;i<this._nodeBag.viewarea.length;i++){this.needRender|=this._nodeBag.viewarea[i].tick(t);}}};x3dom.X3DDocument.prototype.render=function(ctx){if(!ctx||!this._viewarea){return;}
ctx.renderScene(this._viewarea);};x3dom.X3DDocument.prototype.onMove=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
ctx.pickValue(this._viewarea,x,y);this._viewarea.onMove(x,y,buttonState);};x3dom.X3DDocument.prototype.onMoveView=function(ctx,translation,rotation){if(!ctx||!this._viewarea){return;}
this._viewarea.onMoveView(translation,rotation);};x3dom.X3DDocument.prototype.onDrag=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
ctx.pickValue(this._viewarea,x,y);this._viewarea.onDrag(x,y,buttonState);};x3dom.X3DDocument.prototype.onMousePress=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();this._viewarea._scene.getVolume(min,max,true);this._viewarea._scene._lastMin=min;this._viewarea._scene._lastMax=max;ctx.pickValue(this._viewarea,x,y);this._viewarea.onMousePress(x,y,buttonState);};x3dom.X3DDocument.prototype.onMouseRelease=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
ctx.pickValue(this._viewarea,x,y);this._viewarea.onMouseRelease(x,y,buttonState);};x3dom.X3DDocument.prototype.onMouseOver=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
ctx.pickValue(this._viewarea,x,y);this._viewarea.onMouseOver(x,y,buttonState);};x3dom.X3DDocument.prototype.onMouseOut=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
ctx.pickValue(this._viewarea,x,y);this._viewarea.onMouseOut(x,y,buttonState);};x3dom.X3DDocument.prototype.onDoubleClick=function(ctx,x,y){if(!ctx||!this._viewarea){return;}
this._viewarea.onDoubleClick(x,y);};x3dom.X3DDocument.prototype.onTouchMove=function(ctx,touch){if(!ctx||!this._viewarea){return;}
x3dom.debug.logWarning("onTouchMove not implemented");};x3dom.X3DDocument.prototype.onKeyDown=function(keyCode)
{switch(keyCode){case 37:this._viewarea.strafeLeft();break;case 38:this._viewarea.moveFwd();break;case 39:this._viewarea.strafeRight();break;case 40:this._viewarea.moveBwd();break;default:}};x3dom.X3DDocument.prototype.onKeyUp=function(keyCode)
{var stack=null;switch(keyCode){case 27:window.history.back();break;case 33:stack=this._scene.getViewpoint()._stack;if(stack){stack.switchTo('next');}
else{x3dom.debug.logError('No valid ViewBindable stack.');}
break;case 34:stack=this._scene.getViewpoint()._stack;if(stack){stack.switchTo('prev');}
else{x3dom.debug.logError('No valid ViewBindable stack.');}
break;case 37:break;case 38:break;case 39:break;case 40:break;default:}};x3dom.X3DDocument.prototype.onKeyPress=function(charCode)
{var nav=this._scene.getNavigationInfo();switch(charCode)
{case 32:var statDiv=this.canvas.parent.statDiv;if(statDiv){statDiv.style.display=((statDiv.style.display=='none')?'inline':'none');}
x3dom.debug.logInfo("a: show all | d: show helper buffers | s: light view | "+"m: toggle render mode | p: intersect type | r: reset view | "+"e: examine mode | f: fly mode | w: walk mode | "+"l: lookAt mode | g: game mode | u: upright position");break;case 43:nav._vf.speed=2*nav._vf.speed;x3dom.debug.logInfo("Changed navigation speed to "+nav._vf.speed);break;case 45:nav._vf.speed=0.5*nav._vf.speed;x3dom.debug.logInfo("Changed navigation speed to "+nav._vf.speed);break;case 97:this._viewarea.showAll();break;case 100:if(this._viewarea._visDbgBuf===undefined){this._viewarea._visDbgBuf=true;}
else{this._viewarea._visDbgBuf=!this._viewarea._visDbgBuf;}
x3dom.debug.logContainer.style.display=(this._viewarea._visDbgBuf===true)?"block":"none";break;case 101:nav.setType("examine",this._viewarea);break;case 102:nav.setType("fly",this._viewarea);break;case 103:nav.setType("game",this._viewarea);break;case 108:nav.setType("lookat",this._viewarea);break;case 109:if(this._viewarea._points===undefined){this._viewarea._points=true;}
else{this._viewarea._points=!this._viewarea._points;}
break;case 111:nav.setType("lookaround",this._viewarea);break;case 112:switch(this._scene._vf.pickMode.toLowerCase())
{case"idbuf":this._scene._vf.pickMode="color";break;case"color":this._scene._vf.pickMode="texCoord";break;case"texcoord":this._scene._vf.pickMode="box";break;default:this._scene._vf.pickMode="idBuf";break;};x3dom.debug.logInfo("Switch pickMode to '"+
this._scene._vf.pickMode+"'.");break;case 114:this._viewarea.resetView();break;case 115:if(this._nodeBag.lights.length>0)
{this._viewarea.animateTo(this._viewarea.getLightMatrix()[0],this._scene.getViewpoint());}
break;case 117:this._viewarea.uprightView();break;case 119:nav.setType("walk",this._viewarea);break;default:}};x3dom.X3DDocument.prototype.shutdown=function(ctx)
{if(!ctx){return;}
ctx.shutdown(this._viewarea);};x3dom.MatrixMixer=function(beginTime,endTime){if(arguments.length===0){this._beginTime=0;this._endTime=0;}
else{this._beginTime=beginTime;this._endTime=endTime;}
this._beginMat=x3dom.fields.SFMatrix4f.identity();this._beginInvMat=x3dom.fields.SFMatrix4f.identity();this._beginLogMat=x3dom.fields.SFMatrix4f.identity();this._endMat=x3dom.fields.SFMatrix4f.identity();this._endLogMat=x3dom.fields.SFMatrix4f.identity();};x3dom.MatrixMixer.prototype.calcFraction=function(time){var fraction=(time-this._beginTime)/(this._endTime-this._beginTime);return(Math.sin((fraction*Math.PI)-(Math.PI/2))+1)/2.0;};x3dom.MatrixMixer.prototype.setBeginMatrix=function(mat){this._beginMat.setValues(mat);this._beginInvMat=mat.inverse();this._beginLogMat=x3dom.fields.SFMatrix4f.zeroMatrix();};x3dom.MatrixMixer.prototype.setEndMatrix=function(mat){this._endMat.setValues(mat);this._endLogMat=mat.mult(this._beginInvMat).log();};x3dom.MatrixMixer.prototype.mix=function(time){var mat=x3dom.fields.SFMatrix4f.zeroMatrix();if(time<=this._beginTime)
{mat.setValues(this._beginLogMat);}
else
{if(time>=this._endTime)
{mat.setValues(this._endLogMat);}
else
{var fraction=this.calcFraction(time);mat=this._endLogMat.addScaled(this._beginLogMat,-1);mat=mat.multiply(fraction).add(this._beginLogMat);}}
mat=mat.exp().mult(this._beginMat);return mat;};x3dom.Viewarea=function(document,scene){this._doc=document;this._scene=scene;document._nodeBag.viewarea.push(this);this._pickingInfo={pickPos:{},pickObj:null,lastObj:null,lastClickObj:null};this._rotMat=x3dom.fields.SFMatrix4f.identity();this._transMat=x3dom.fields.SFMatrix4f.identity();this._movement=new x3dom.fields.SFVec3f(0,0,0);this._needNavigationMatrixUpdate=true;this._deltaT=0;this._pitch=0;this._yaw=0;this._eyePos=new x3dom.fields.SFVec3f(0,0,0);this._width=400;this._height=300;this._dx=0;this._dy=0;this._lastX=-1;this._lastY=-1;this._pressX=-1;this._pressY=-1;this._lastButton=0;this._pick=new x3dom.fields.SFVec3f(0,0,0);this._lastTS=0;this._mixer=new x3dom.MatrixMixer();this._geoCache=[];};x3dom.Viewarea.prototype.tick=function(timeStamp)
{var needMixAnim=false;if(this._mixer._beginTime>0)
{needMixAnim=true;if(timeStamp>=this._mixer._beginTime)
{if(timeStamp<=this._mixer._endTime)
{var mat=this._mixer.mix(timeStamp);this._scene.getViewpoint().setView(mat);}
else{this._mixer._beginTime=0;this._mixer._endTime=0;this._scene.getViewpoint().setView(this._mixer._endMat);}}
else{this._scene.getViewpoint().setView(this._mixer._beginMat);}}
var needNavAnim=this.navigateTo(timeStamp);this._lastTS=timeStamp;return(needMixAnim||needNavAnim);};x3dom.Viewarea.prototype.navigateTo=function(timeStamp)
{var navi=this._scene.getNavigationInfo();var needNavAnim=(navi._vf.type[0].toLowerCase()==="game"||(this._lastButton>0&&(navi._vf.type[0].toLowerCase()==="fly"||navi._vf.type[0].toLowerCase()==="walk"||navi._vf.type[0].toLowerCase().substr(0,5)==="looka")));this._deltaT=timeStamp-this._lastTS;if(needNavAnim)
{var avatarRadius=0.25;var avatarHeight=1.6;var avatarKnee=0.75;if(navi._vf.avatarSize.length>2){avatarRadius=navi._vf.avatarSize[0];avatarHeight=navi._vf.avatarSize[1];avatarKnee=navi._vf.avatarSize[2];}
var currViewMat=this.getViewMatrix();var dist=0;var step=(this._lastButton&2)?-1:1;step*=(this._deltaT*navi._vf.speed);var phi=Math.PI*this._deltaT*(this._pressX-this._lastX)/this._width;var theta=Math.PI*this._deltaT*(this._pressY-this._lastY)/this._height;if(this._needNavigationMatrixUpdate===true)
{this._needNavigationMatrixUpdate=false;this._rotMat=x3dom.fields.SFMatrix4f.identity();this._transMat=x3dom.fields.SFMatrix4f.identity();this._movement=new x3dom.fields.SFVec3f(0,0,0);var angleX=0;var angleY=Math.asin(currViewMat._02);var C=Math.cos(angleY);if(Math.abs(C)>0.0001){angleX=Math.atan2(-currViewMat._12/C,currViewMat._22/C);}
this._flyMat=currViewMat.inverse();this._from=this._flyMat.e3();this._at=this._from.subtract(this._flyMat.e2());this._up=new x3dom.fields.SFVec3f(0,1,0);this._pitch=angleX*180/Math.PI;this._yaw=angleY*180/Math.PI;this._eyePos=this._from.negate();}
var tmpAt=null,tmpUp=null,tmpMat=null;if(navi._vf.type[0].toLowerCase()==="game")
{this._pitch+=this._dy;this._yaw+=this._dx;if(this._pitch>=89)this._pitch=89;if(this._pitch<=-89)this._pitch=-89;if(this._yaw>=360)this._yaw-=360;if(this._yaw<0)this._yaw=360+this._yaw;this._dx=0;this._dy=0;var xMat=x3dom.fields.SFMatrix4f.rotationX(this._pitch/180*Math.PI);var yMat=x3dom.fields.SFMatrix4f.rotationY(this._yaw/180*Math.PI);var fPos=x3dom.fields.SFMatrix4f.translation(this._eyePos);this._flyMat=xMat.mult(yMat).mult(fPos);var flyMat=this._flyMat.inverse();var tmpFrom=flyMat.e3();tmpUp=new x3dom.fields.SFVec3f(0,-1,0);tmpAt=tmpFrom.add(tmpUp);tmpUp=flyMat.e0().cross(tmpUp).normalize();tmpMat=x3dom.fields.SFMatrix4f.lookAt(tmpFrom,tmpAt,tmpUp);tmpMat=tmpMat.inverse();this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2,tmpMat,this.getProjectionMatrix().mult(tmpMat));if(this._pickingInfo.pickObj)
{dist=this._pickingInfo.pickPos.subtract(tmpFrom).length();tmpFrom.y+=(avatarHeight-dist);flyMat.setTranslate(tmpFrom);this._eyePos=flyMat.e3().negate();this._flyMat=flyMat.inverse();this._pickingInfo.pickObj=null;}
this._scene.getViewpoint().setView(this._flyMat);return needNavAnim;}
var q=x3dom.fields.Quaternion.axisAngle(this._up,phi);var temp=q.toMatrix();var fin=x3dom.fields.SFMatrix4f.translation(this._from);fin=fin.mult(temp);temp=x3dom.fields.SFMatrix4f.translation(this._from.negate());fin=fin.mult(temp);this._at=fin.multMatrixPnt(this._at);var lv=this._at.subtract(this._from).normalize();var sv=lv.cross(this._up).normalize();var up=sv.cross(lv).normalize();q=x3dom.fields.Quaternion.axisAngle(sv,theta);temp=q.toMatrix();fin=x3dom.fields.SFMatrix4f.translation(this._from);fin=fin.mult(temp);temp=x3dom.fields.SFMatrix4f.translation(this._from.negate());fin=fin.mult(temp);this._at=fin.multMatrixPnt(this._at);if(navi._vf.type[0].toLowerCase().substr(0,5)!=="looka")
{this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2);if(this._pickingInfo.pickObj)
{dist=this._pickingInfo.pickPos.subtract(this._from).length();if(step>0&&dist<=avatarRadius){step=0;}}
lv=this._at.subtract(this._from).normalize().multiply(step);this._at=this._at.add(lv);this._from=this._from.add(lv);if(navi._vf.type[0].toLowerCase()==="walk")
{tmpAt=this._from.addScaled(up,-1.0);tmpUp=sv.cross(up.negate()).normalize();tmpMat=x3dom.fields.SFMatrix4f.lookAt(this._from,tmpAt,tmpUp);tmpMat=tmpMat.inverse();this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2,tmpMat,this.getProjectionMatrix().mult(tmpMat));if(this._pickingInfo.pickObj)
{dist=this._pickingInfo.pickPos.subtract(this._from).length();this._at=this._at.add(up.multiply(avatarHeight-dist));this._from=this._from.add(up.multiply(avatarHeight-dist));}}
this._pickingInfo.pickObj=null;}
this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,this._at,up);this._scene.getViewpoint().setView(this._flyMat.inverse());}
return needNavAnim;};x3dom.Viewarea.prototype.moveFwd=function()
{var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].toLowerCase()==="game")
{var avatarRadius=0.25;var avatarHeight=1.6;if(navi._vf.avatarSize.length>2){avatarRadius=navi._vf.avatarSize[0];avatarHeight=navi._vf.avatarSize[1];}
var speed=5*this._deltaT*navi._vf.speed;var yRotRad=(this._yaw/180*Math.PI);var xRotRad=(this._pitch/180*Math.PI);var dist=0;var fMat=this._flyMat.inverse();this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2);if(this._pickingInfo.pickObj)
{dist=this._pickingInfo.pickPos.subtract(fMat.e3()).length();if(dist<=2*avatarRadius){}
else{this._eyePos.x-=Math.sin(yRotRad)*speed;this._eyePos.z+=Math.cos(yRotRad)*speed;this._eyePos.y+=Math.sin(xRotRad)*speed;}}}};x3dom.Viewarea.prototype.moveBwd=function()
{var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].toLowerCase()==="game")
{var speed=5*this._deltaT*navi._vf.speed;var yRotRad=(this._yaw/180*Math.PI);var xRotRad=(this._pitch/180*Math.PI);this._eyePos.x+=Math.sin(yRotRad)*speed;this._eyePos.z-=Math.cos(yRotRad)*speed;this._eyePos.y-=Math.sin(xRotRad)*speed;}};x3dom.Viewarea.prototype.strafeRight=function()
{var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].toLowerCase()==="game")
{var speed=5*this._deltaT*navi._vf.speed;var yRotRad=(this._yaw/180*Math.PI);this._eyePos.x-=Math.cos(yRotRad)*speed;this._eyePos.z-=Math.sin(yRotRad)*speed;}};x3dom.Viewarea.prototype.strafeLeft=function()
{var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].toLowerCase()==="game")
{var speed=5*this._deltaT*navi._vf.speed;var yRotRad=(this._yaw/180*Math.PI);this._eyePos.x+=Math.cos(yRotRad)*speed;this._eyePos.z+=Math.sin(yRotRad)*speed;}};x3dom.Viewarea.prototype.animateTo=function(target,prev,dur)
{var navi=this._scene.getNavigationInfo();if(x3dom.isa(target,x3dom.nodeTypes.Viewpoint)){target=target.getViewMatrix();}
if(navi._vf.transitionType[0].toLowerCase()!=="teleport"&&navi.getType()!=="game")
{if(prev&&x3dom.isa(prev,x3dom.nodeTypes.Viewpoint)){prev=prev.getCurrentTransform().mult(prev.getViewMatrix()).mult(this._transMat).mult(this._rotMat);}
else{return;}
this._mixer._beginTime=this._lastTS;if(arguments.length>=3){this._mixer._endTime=this._lastTS+dur;}
else{this._mixer._endTime=this._lastTS+navi._vf.transitionTime;}
this._mixer.setBeginMatrix(prev);this._mixer.setEndMatrix(target);}
else
{this._scene.getViewpoint().setView(target);}
this._rotMat=x3dom.fields.SFMatrix4f.identity();this._transMat=x3dom.fields.SFMatrix4f.identity();this._movement=new x3dom.fields.SFVec3f(0,0,0);this._needNavigationMatrixUpdate=true;};x3dom.Viewarea.prototype.getLights=function(){return this._doc._nodeBag.lights;};x3dom.Viewarea.prototype.getLightsShadow=function(){var lights=this._doc._nodeBag.lights;for(var l=0;l<lights.length;l++){if(lights[l]._vf.shadowIntensity>0.0){return true;}}};x3dom.Viewarea.prototype.getViewpointMatrix=function(){var viewpoint=this._scene.getViewpoint();var mat_viewpoint=viewpoint.getCurrentTransform();return viewpoint.getViewMatrix().mult(mat_viewpoint.inverse());};x3dom.Viewarea.prototype.getViewMatrix=function(){return this.getViewpointMatrix().mult(this._transMat).mult(this._rotMat);};x3dom.Viewarea.prototype.getLightMatrix=function()
{var lights=this._doc._nodeBag.lights;var i,n=lights.length;if(n>0)
{var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var ok=this._scene.getVolume(min,max,true);if(ok)
{var l_arr=[];var viewpoint=this._scene.getViewpoint();var fov=viewpoint.getFieldOfView();var dia=max.subtract(min);var dist1=(dia.y/2.0)/Math.tan(fov/2.0)+(dia.z/2.0);var dist2=(dia.x/2.0)/Math.tan(fov/2.0)+(dia.z/2.0);dia=min.add(dia.multiply(0.5));for(i=0;i<n;i++)
{if(x3dom.isa(lights[i],x3dom.nodeTypes.PointLight)){dia=dia.subtract(lights[i]._vf.location).normalize();}
else{var dir=lights[i]._vf.direction.normalize().negate();dia=dia.add(dir.multiply(1.2*(dist1>dist2?dist1:dist2)));}
l_arr[i]=lights[i].getViewMatrix(dia);}
return l_arr;}}
return[this.getViewMatrix()];};x3dom.Viewarea.prototype.getWCtoLCMatrix=function(lMat)
{var proj=this.getProjectionMatrix();var view;if(arguments.length===0){view=this.getLightMatrix()[0];}
else{view=lMat;}
return proj.mult(view);};x3dom.Viewarea.prototype.getProjectionMatrix=function()
{var viewpoint=this._scene.getViewpoint();return viewpoint.getProjectionMatrix(this._width/this._height);};x3dom.Viewarea.prototype.getWCtoCCMatrix=function()
{var view=this.getViewMatrix();var proj=this.getProjectionMatrix();return proj.mult(view);};x3dom.Viewarea.prototype.getCCtoWCMatrix=function()
{var mat=this.getWCtoCCMatrix();return mat.inverse();};x3dom.Viewarea.prototype.calcViewRay=function(x,y)
{var cctowc=this.getCCtoWCMatrix();var rx=x/(this._width-1.0)*2.0-1.0;var ry=(this._height-1.0-y)/(this._height-1.0)*2.0-1.0;var from=cctowc.multFullMatrixPnt(new x3dom.fields.SFVec3f(rx,ry,-1));var at=cctowc.multFullMatrixPnt(new x3dom.fields.SFVec3f(rx,ry,1));var dir=at.subtract(from);return new x3dom.fields.Line(from,dir);};x3dom.Viewarea.prototype.showAll=function()
{var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var ok=this._scene.getVolume(min,max,true);if(ok)
{var viewpoint=this._scene.getViewpoint();var fov=viewpoint.getFieldOfView();var dia=max.subtract(min);var dist1=(dia.y/2.0)/Math.tan(fov/2.0)+(dia.z/2.0);var dist2=(dia.x/2.0)/Math.tan(fov/2.0)+(dia.z/2.0);dia=min.add(dia.multiply(0.5));dia.z+=(dist1>dist2?dist1:dist2);this.animateTo(x3dom.fields.SFMatrix4f.translation(dia.multiply(-1)),viewpoint);}};x3dom.Viewarea.prototype.resetView=function()
{var navi=this._scene.getNavigationInfo();if(navi._vf.transitionType[0].toLowerCase()!=="teleport"&&navi.getType()!=="game")
{this._mixer._beginTime=this._lastTS;this._mixer._endTime=this._lastTS+navi._vf.transitionTime;this._mixer.setBeginMatrix(this.getViewMatrix());this._scene.getViewpoint().resetView();this._mixer.setEndMatrix(this._scene.getViewpoint().getViewMatrix());}
else
{this._scene.getViewpoint().resetView();}
this._rotMat=x3dom.fields.SFMatrix4f.identity();this._transMat=x3dom.fields.SFMatrix4f.identity();this._movement=new x3dom.fields.SFVec3f(0,0,0);this._needNavigationMatrixUpdate=true;};x3dom.Viewarea.prototype.uprightView=function()
{var mat=this.getViewMatrix().inverse();var from=mat.e3();var at=from.subtract(mat.e2());var up=new x3dom.fields.SFVec3f(0,1,0);var s=mat.e2().cross(up).normalize();var v=s.cross(up).normalize();at=from.add(v);mat=x3dom.fields.SFMatrix4f.lookAt(from,at,up);mat=mat.inverse();this.animateTo(mat,this._scene.getViewpoint());};x3dom.Viewarea.prototype.callEvtHandler=function(node,eventType,event)
{event.target=node._xmlNode;var attrib=node._xmlNode[eventType];try{if(typeof(attrib)==="function"){attrib.call(node._xmlNode,event);}
else{var funcStr=node._xmlNode.getAttribute(eventType);var func=new Function('event',funcStr);func.call(node._xmlNode,event);}
var list=node._listeners[event.type];if(list){for(var it=0;it<list.length;it++){list[it].call(node._xmlNode,event);}}}
catch(ex){x3dom.debug.logException(ex);}
return event.cancelBubble;};x3dom.Viewarea.prototype.checkEvents=function(obj,x,y,buttonState,eventType)
{var that=this;var needRecurse=true;var event={target:{},type:eventType.substr(2,eventType.length-2),button:buttonState,layerX:x,layerY:y,worldX:that._pick.x,worldY:that._pick.y,worldZ:that._pick.z,hitPnt:that._pick.toGL(),hitObject:obj._xmlNode?obj._xmlNode:null,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;}};try{var anObj=obj;if(!anObj._xmlNode[eventType]&&!anObj._xmlNode.hasAttribute(eventType)&&!anObj._listeners[event.type]){anObj=anObj._cf.geometry.node;}
if(that.callEvtHandler(anObj,eventType,event)===true){needRecurse=false;}}
catch(e){x3dom.debug.logException(e);}
var recurse=function(obj){Array.forEach(obj._parentNodes,function(node){if(node._xmlNode&&(node._xmlNode[eventType]||node._xmlNode.hasAttribute(eventType)||node._listeners[event.type]))
{if(that.callEvtHandler(node,eventType,event)===true){needRecurse=false;}}
if(x3dom.isa(node,x3dom.nodeTypes.Anchor)&&eventType==='onclick'){node.handleTouch();needRecurse=false;}
else if(needRecurse){recurse(node);}});};if(needRecurse){recurse(obj);}};x3dom.Viewarea.prototype.initMouseState=function()
{this._deltaT=0;this._dx=0;this._dy=0;this._lastX=-1;this._lastY=-1;this._pressX=-1;this._pressY=-1;this._lastButton=0;this._needNavigationMatrixUpdate=true;}
x3dom.Viewarea.prototype.onMousePress=function(x,y,buttonState)
{this._needNavigationMatrixUpdate=true;this.prepareEvents(x,y,buttonState,"onmousedown");this._pickingInfo.lastClickObj=this._pickingInfo.pickObj;this._dx=0;this._dy=0;this._lastX=x;this._lastY=y;this._pressX=x;this._pressY=y;this._lastButton=buttonState;};x3dom.Viewarea.prototype.onMouseRelease=function(x,y,buttonState)
{var tDist=3.0;var dir;var navi=this._scene.getNavigationInfo();if(this._scene._vf.pickMode.toLowerCase()!=="box"){this.prepareEvents(x,y,buttonState,"onmouseup");if(this._pickingInfo.pickObj&&this._pickingInfo.pickObj===this._pickingInfo.lastClickObj){this.prepareEvents(x,y,buttonState,"onclick");}}
else{var t0=new Date().getTime();var line=this.calcViewRay(x,y);var isect=this._scene.doIntersect(line);var obj=line.hitObject;if(isect&&obj)
{this._pick.setValues(line.hitPoint);this.checkEvents(obj,x,y,buttonState,"onclick");x3dom.debug.logInfo("Hit '"+obj._xmlNode.localName+"/ "+
obj._DEF+"' at dist="+line.dist.toFixed(4));x3dom.debug.logInfo("Ray hit at position "+this._pick);}
var t1=new Date().getTime()-t0;x3dom.debug.logInfo("Picking time (box): "+t1+"ms");if(!isect){dir=this.getViewMatrix().e2().negate();var u=dir.dot(line.pos.negate())/dir.dot(line.dir);this._pick=line.pos.add(line.dir.multiply(u));}}
if(this._pickingInfo.pickObj&&navi._vf.type[0].toLowerCase()==="lookat"&&this._pressX===x&&this._pressY===y)
{var step=(this._lastButton&2)?-1:1;var dist=this._pickingInfo.pickPos.subtract(this._from).length()/tDist;var laMat=new x3dom.fields.SFMatrix4f();laMat.setValues(this.getViewMatrix());laMat=laMat.inverse();var from=laMat.e3();var at=from.subtract(laMat.e2());var up=laMat.e1();dir=this._pickingInfo.pickPos.subtract(from);var len=dir.length();dir=dir.normalize();var newUp=new x3dom.fields.SFVec3f(0,1,0);var newAt=from.addScaled(dir,len);var s=dir.cross(newUp).normalize();dir=s.cross(newUp).normalize();if(step<0){dist=(0.5+len+dist)*2;}
var newFrom=newAt.addScaled(dir,dist);laMat=x3dom.fields.SFMatrix4f.lookAt(newFrom,newAt,newUp);laMat=laMat.inverse();dist=newFrom.subtract(from).length();var dur=Math.log(dist/navi._vf.speed);this.animateTo(laMat,this._scene.getViewpoint(),dur);}
this._dx=0;this._dy=0;this._lastX=x;this._lastY=y;this._lastButton=buttonState;};x3dom.Viewarea.prototype.onMouseOver=function(x,y,buttonState)
{this._dx=0;this._dy=0;this._lastButton=0;this._lastX=x;this._lastY=y;this._deltaT=0;};x3dom.Viewarea.prototype.onMouseOut=function(x,y,buttonState)
{this._dx=0;this._dy=0;this._lastButton=0;this._lastX=x;this._lastY=y;this._deltaT=0;};x3dom.Viewarea.prototype.onDoubleClick=function(x,y)
{if(this._doc.properties.getProperty('disableDoubleClick','false')==='true'){return;}
var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].length<=1||navi._vf.type[0].toLowerCase()=="none"){return;}
if((this._scene._vf.pickMode.toLowerCase()==="color"||this._scene._vf.pickMode.toLowerCase()==="texcoord")){return;}
var viewpoint=this._scene.getViewpoint();viewpoint._vf.centerOfRotation.setValues(this._pick);x3dom.debug.logInfo("New center of Rotation:  "+this._pick);var mat=this.getViewMatrix().inverse();var from=mat.e3();var at=this._pick;var up=mat.e1();var norm=mat.e0().cross(up).normalize();var dist=norm.dot(this._pick.subtract(from));from=at.addScaled(norm,-dist);mat=x3dom.fields.SFMatrix4f.lookAt(from,at,up);x3dom.debug.logInfo("New camera position:  "+from);this.animateTo(mat.inverse(),viewpoint);};x3dom.Viewarea.prototype.handleMoveEvt=function(x,y,buttonState)
{this.prepareEvents(x,y,buttonState,"onmousemove");if(this._pickingInfo.pickObj!==this._pickingInfo.lastObj)
{if(this._pickingInfo.lastObj){var obj=this._pickingInfo.pickObj;this._pickingInfo.pickObj=this._pickingInfo.lastObj;this.prepareEvents(x,y,buttonState,"onmouseout");this._pickingInfo.pickObj=obj;}
if(this._pickingInfo.pickObj){this.prepareEvents(x,y,buttonState,"onmouseover");}
this._pickingInfo.lastObj=this._pickingInfo.pickObj;}};x3dom.Viewarea.prototype.onMove=function(x,y,buttonState)
{this.handleMoveEvt(x,y,buttonState);if(this._lastX<0||this._lastY<0){this._lastX=x;this._lastY=y;}
this._dx=x-this._lastX;this._dy=y-this._lastY;this._lastX=x;this._lastY=y;};x3dom.Viewarea.prototype.onMoveView=function(translation,rotation)
{var navi=this._scene.getNavigationInfo();var viewpoint=this._scene.getViewpoint();if(navi._vf.type[0].toLowerCase()==="examine")
{if(translation)
{var distance=10;if(this._scene._lastMin!==undefined&&this._scene._lastMax!==undefined)
{distance=(this._scene._lastMax.subtract(this._scene._lastMin)).length();distance=(distance<x3dom.fields.Eps)?1:distance;}
translation=translation.multiply(distance);this._movement=this._movement.add(translation);this._transMat=viewpoint.getViewMatrix().inverse().mult(x3dom.fields.SFMatrix4f.translation(this._movement)).mult(viewpoint.getViewMatrix());}
if(rotation){this._rotMat=rotation.mult(this._rotMat);}}};x3dom.Viewarea.prototype.onDrag=function(x,y,buttonState)
{this.handleMoveEvt(x,y,buttonState);var navi=this._scene.getNavigationInfo();if(navi._vf.type[0].length<=1||navi._vf.type[0].toLowerCase()==="none"){return;}
var dx=x-this._lastX;var dy=y-this._lastY;var min,max,ok,d,vec;var viewpoint=this._scene.getViewpoint();if(navi._vf.type[0].toLowerCase()==="examine")
{if(buttonState&1)
{var alpha=(dy*2*Math.PI)/this._width;var beta=(dx*2*Math.PI)/this._height;var mat=this.getViewMatrix();var mx=x3dom.fields.SFMatrix4f.rotationX(alpha);var my=x3dom.fields.SFMatrix4f.rotationY(beta);var center=viewpoint.getCenterOfRotation();mat.setTranslate(new x3dom.fields.SFVec3f(0,0,0));this._rotMat=this._rotMat.mult(x3dom.fields.SFMatrix4f.translation(center)).mult(mat.inverse()).mult(mx).mult(my).mult(mat).mult(x3dom.fields.SFMatrix4f.translation(center.negate()));}
if(buttonState&4)
{if(this._scene._lastMin!==undefined&&this._scene._lastMax!==undefined)
{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=(d<x3dom.fields.Eps)?1:d;}
else
{min=x3dom.fields.SFVec3f.MAX();max=x3dom.fields.SFVec3f.MIN();ok=this._scene.getVolume(min,max,true);d=ok?(max.subtract(min)).length():10;d=(d<x3dom.fields.Eps)?1:d;}
vec=new x3dom.fields.SFVec3f(d*dx/this._width,d*(-dy)/this._height,0);this._movement=this._movement.add(vec);this._transMat=viewpoint.getViewMatrix().inverse().mult(x3dom.fields.SFMatrix4f.translation(this._movement)).mult(viewpoint.getViewMatrix());}
if(buttonState&2)
{if(this._scene._lastMin!==undefined&&this._scene._lastMax!==undefined)
{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=(d<x3dom.fields.Eps)?1:d;}
else
{min=x3dom.fields.SFVec3f.MAX();max=x3dom.fields.SFVec3f.MIN();ok=this._scene.getVolume(min,max,true);d=ok?(max.subtract(min)).length():10;d=(d<x3dom.fields.Eps)?1:d;}
vec=new x3dom.fields.SFVec3f(0,0,d*(dx+dy)/this._height);this._movement=this._movement.add(vec);this._transMat=viewpoint.getViewMatrix().inverse().mult(x3dom.fields.SFMatrix4f.translation(this._movement)).mult(viewpoint.getViewMatrix());}}
this._dx=dx;this._dy=dy;this._lastX=x;this._lastY=y;};x3dom.Viewarea.prototype.prepareEvents=function(x,y,buttonState,eventType)
{var avoidTraversal=(this._scene._vf.pickMode.toLowerCase()==="idbuf"||this._scene._vf.pickMode.toLowerCase()==="color"||this._scene._vf.pickMode.toLowerCase()==="texcoord");if(avoidTraversal){var obj=this._pickingInfo.pickObj;if(obj){this._pick.setValues(this._pickingInfo.pickPos);this.checkEvents(obj,x,y,buttonState,eventType);if(eventType==="onclick"){x3dom.debug.logInfo("Hit \""+obj._xmlNode.localName+"/ "+obj._DEF+"\"");x3dom.debug.logInfo("Ray hit at position "+this._pick);}}}};x3dom.Mesh=function(parent)
{this._parent=parent;this._min=new x3dom.fields.SFVec3f(0,0,0);this._max=new x3dom.fields.SFVec3f(0,0,0);this._invalidate=true;this._numFaces=0;this._numCoords=0;this._positions=[];this._normals=[];this._texCoords=[];this._colors=[];this._indices=[];this._positions[0]=[];this._normals[0]=[];this._texCoords[0]=[];this._colors[0]=[];this._indices[0]=[];};x3dom.Mesh.prototype._dynamicFields={};x3dom.Mesh.prototype._numTexComponents=2;x3dom.Mesh.prototype._numColComponents=3;x3dom.Mesh.prototype._lit=true;x3dom.Mesh.prototype._min={};x3dom.Mesh.prototype._max={};x3dom.Mesh.prototype._invalidate=true;x3dom.Mesh.prototype._numFaces=0;x3dom.Mesh.prototype._numCoords=0;x3dom.Mesh.prototype.setMeshData=function(positions,normals,texCoords,colors,indices)
{this._positions[0]=positions;this._normals[0]=normals;this._texCoords[0]=texCoords;this._colors[0]=colors;this._indices[0]=indices;this._invalidate=true;this._numFaces=this._indices[0].length/3;this._numCoords=this._positions[0].length/3;};x3dom.Mesh.prototype.getBBox=function(min,max,invalidate)
{if(this._invalidate===true&&invalidate===true)
{var coords=this._positions[0];var n=coords.length;if(n>3)
{this._min=new x3dom.fields.SFVec3f(coords[0],coords[1],coords[2]);this._max=new x3dom.fields.SFVec3f(coords[0],coords[1],coords[2]);}
else
{this._min=new x3dom.fields.SFVec3f(0,0,0);this._max=new x3dom.fields.SFVec3f(0,0,0);}
for(var i=3;i<n;i+=3)
{if(this._min.x>coords[i+0]){this._min.x=coords[i+0];}
if(this._min.y>coords[i+1]){this._min.y=coords[i+1];}
if(this._min.z>coords[i+2]){this._min.z=coords[i+2];}
if(this._max.x<coords[i+0]){this._max.x=coords[i+0];}
if(this._max.y<coords[i+1]){this._max.y=coords[i+1];}
if(this._max.z<coords[i+2]){this._max.z=coords[i+2];}}
this._invalidate=false;}
min.setValues(this._min);max.setValues(this._max);};x3dom.Mesh.prototype.getCenter=function()
{var min=new x3dom.fields.SFVec3f(0,0,0);var max=new x3dom.fields.SFVec3f(0,0,0);this.getBBox(min,max,true);var center=min.add(max).multiply(0.5);return center;};x3dom.Mesh.prototype.doIntersect=function(line)
{var min=new x3dom.fields.SFVec3f(0,0,0);var max=new x3dom.fields.SFVec3f(0,0,0);this.getBBox(min,max,true);var isect=line.intersect(min,max);if(isect&&line.enter<line.dist)
{line.dist=line.enter;line.hitObject=this._parent;line.hitPoint=line.pos.add(line.dir.multiply(line.enter));}
return isect;};x3dom.Mesh.prototype.calcNormals=function(creaseAngle)
{var i=0,j=0,num=0;var multInd=(this._multiIndIndices!==undefined&&this._multiIndIndices.length);var coords=this._positions[0];var idxs=multInd?this._multiIndIndices:this._indices[0];var vertNormals=[];var vertFaceNormals=[];var a,b,n=null;num=(this._posSize!==undefined&&this._posSize>coords.length)?this._posSize/3:coords.length/3;num=3*((num-Math.floor(num)>0)?Math.floor(num+1):num);for(i=0;i<num;++i){vertFaceNormals[i]=[];}
num=idxs.length;for(i=0;i<num;i+=3){if(!multInd){a=new x3dom.fields.SFVec3f(coords[idxs[i]*3],coords[idxs[i]*3+1],coords[idxs[i]*3+2]).subtract(new x3dom.fields.SFVec3f(coords[idxs[i+1]*3],coords[idxs[i+1]*3+1],coords[idxs[i+1]*3+2]));b=new x3dom.fields.SFVec3f(coords[idxs[i+1]*3],coords[idxs[i+1]*3+1],coords[idxs[i+1]*3+2]).subtract(new x3dom.fields.SFVec3f(coords[idxs[i+2]*3],coords[idxs[i+2]*3+1],coords[idxs[i+2]*3+2]));}
else{a=new x3dom.fields.SFVec3f(coords[i*3],coords[i*3+1],coords[i*3+2]).subtract(new x3dom.fields.SFVec3f(coords[(i+1)*3],coords[(i+1)*3+1],coords[(i+1)*3+2]));b=new x3dom.fields.SFVec3f(coords[(i+1)*3],coords[(i+1)*3+1],coords[(i+1)*3+2]).subtract(new x3dom.fields.SFVec3f(coords[(i+2)*3],coords[(i+2)*3+1],coords[(i+2)*3+2]));}
n=a.cross(b).normalize();if(creaseAngle<=x3dom.fields.Eps){vertNormals[i*3]=vertNormals[(i+1)*3]=vertNormals[(i+2)*3]=n.x;vertNormals[i*3+1]=vertNormals[(i+1)*3+1]=vertNormals[(i+2)*3+1]=n.y;vertNormals[i*3+2]=vertNormals[(i+1)*3+2]=vertNormals[(i+2)*3+2]=n.z;}
else{vertFaceNormals[idxs[i]].push(n);vertFaceNormals[idxs[i+1]].push(n);vertFaceNormals[idxs[i+2]].push(n);}}
if(creaseAngle>x3dom.fields.Eps)
{for(i=0;i<coords.length;i+=3){n=new x3dom.fields.SFVec3f(0,0,0);if(!multInd){num=vertFaceNormals[i/3].length;for(j=0;j<num;++j){n=n.add(vertFaceNormals[i/3][j]);}}
else{num=vertFaceNormals[idxs[i/3]].length;for(j=0;j<num;++j){n=n.add(vertFaceNormals[idxs[i/3]][j]);}}
n=n.normalize();vertNormals[i]=n.x;vertNormals[i+1]=n.y;vertNormals[i+2]=n.z;}}
if(multInd){this._multiIndIndices=[];}
this._normals[0]=vertNormals;};x3dom.Mesh.prototype.splitMesh=function()
{var MAX=65535;if(this._positions[0].length/3<=MAX){return;}
var positions=this._positions[0];var normals=this._normals[0];var texCoords=this._texCoords[0];var colors=this._colors[0];var indices=this._indices[0];var i=0;do
{this._positions[i]=[];this._normals[i]=[];this._texCoords[i]=[];this._colors[i]=[];this._indices[i]=[];var k=((indices.length-((i+1)*MAX)<0)?false:true);if(k){this._indices[i]=indices.slice(i*MAX,(i+1)*MAX);}else{this._indices[i]=indices.slice(i*MAX);}
if(i){var m=i*MAX;for(var j=0,l=this._indices[i].length;j<l;j++){this._indices[i][j]-=m;}}
if(k){this._positions[i]=positions.slice(i*MAX*3,3*(i+1)*MAX);}else{this._positions[i]=positions.slice(i*MAX*3);}
if(normals.length){if(k){this._normals[i]=normals.slice(i*MAX*3,3*(i+1)*MAX);}else{this._normals[i]=normals.slice(i*MAX*3);}}
if(texCoords.length){if(k){this._texCoords[i]=texCoords.slice(i*MAX*this._numTexComponents,this._numTexComponents*(i+1)*MAX);}else{this._texCoords[i]=texCoords.slice(i*MAX*this._numTexComponents);}}
if(colors.length){if(k){this._colors[i]=colors.slice(i*MAX*this._numColComponents,this._numColComponents*(i+1)*MAX);}else{this._colors[i]=colors.slice(i*MAX*this._numColComponents);}}}
while(positions.length>++i*MAX*3);};x3dom.Mesh.prototype.calcTexCoords=function(mode)
{this._texCoords[0]=[];if(mode.toLowerCase()==="sphere-local")
{for(var i=0,j=0,n=this._normals[0].length;i<n;i+=3)
{this._texCoords[0][j++]=0.5+this._normals[0][i]/2.0;this._texCoords[0][j++]=0.5+this._normals[0][i+1]/2.0;}}
else
{var min=new x3dom.fields.SFVec3f(0,0,0),max=new x3dom.fields.SFVec3f(0,0,0);this.getBBox(min,max,true);var dia=max.subtract(min);var S=0,T=1;if(dia.x>=dia.y)
{if(dia.x>=dia.z)
{S=0;T=dia.y>=dia.z?1:2;}
else
{S=2;T=0;}}
else
{if(dia.y>=dia.z)
{S=1;T=dia.x>=dia.z?0:2;}
else
{S=2;T=1;}}
var sDenom=1,tDenom=1;var sMin=0,tMin=0;switch(S){case 0:sDenom=dia.x;sMin=min.x;break;case 1:sDenom=dia.y;sMin=min.y;break;case 2:sDenom=dia.z;sMin=min.z;break;}
switch(T){case 0:tDenom=dia.x;tMin=min.x;break;case 1:tDenom=dia.y;tMin=min.y;break;case 2:tDenom=dia.z;tMin=min.z;break;}
for(var k=0,l=0,m=this._positions[0].length;k<m;k+=3)
{this._texCoords[0][l++]=(this._positions[0][k+S]-sMin)/sDenom;this._texCoords[0][l++]=(this._positions[0][k+T]-tMin)/tDenom;}}};x3dom.fields={};x3dom.fields.Eps=0.000001;x3dom.fields.SFMatrix4f=function(_00,_01,_02,_03,_10,_11,_12,_13,_20,_21,_22,_23,_30,_31,_32,_33)
{if(arguments.length===0){this._00=1;this._01=0;this._02=0;this._03=0;this._10=0;this._11=1;this._12=0;this._13=0;this._20=0;this._21=0;this._22=1;this._23=0;this._30=0;this._31=0;this._32=0;this._33=1;}
else{this._00=_00;this._01=_01;this._02=_02;this._03=_03;this._10=_10;this._11=_11;this._12=_12;this._13=_13;this._20=_20;this._21=_21;this._22=_22;this._23=_23;this._30=_30;this._31=_31;this._32=_32;this._33=_33;}};x3dom.fields.SFMatrix4f.prototype.e0=function(){var baseVec=new x3dom.fields.SFVec3f(this._00,this._10,this._20);return baseVec.normalize();};x3dom.fields.SFMatrix4f.prototype.e1=function(){var baseVec=new x3dom.fields.SFVec3f(this._01,this._11,this._21);return baseVec.normalize();};x3dom.fields.SFMatrix4f.prototype.e2=function(){var baseVec=new x3dom.fields.SFVec3f(this._02,this._12,this._22);return baseVec.normalize();};x3dom.fields.SFMatrix4f.prototype.e3=function(){return new x3dom.fields.SFVec3f(this._03,this._13,this._23);};x3dom.fields.SFMatrix4f.identity=function(){return new x3dom.fields.SFMatrix4f(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);};x3dom.fields.SFMatrix4f.zeroMatrix=function(){return new x3dom.fields.SFMatrix4f(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);};x3dom.fields.SFMatrix4f.translation=function(vec){return new x3dom.fields.SFMatrix4f(1,0,0,vec.x,0,1,0,vec.y,0,0,1,vec.z,0,0,0,1);};x3dom.fields.SFMatrix4f.rotationX=function(a){var c=Math.cos(a);var s=Math.sin(a);return new x3dom.fields.SFMatrix4f(1,0,0,0,0,c,-s,0,0,s,c,0,0,0,0,1);};x3dom.fields.SFMatrix4f.rotationY=function(a){var c=Math.cos(a);var s=Math.sin(a);return new x3dom.fields.SFMatrix4f(c,0,s,0,0,1,0,0,-s,0,c,0,0,0,0,1);};x3dom.fields.SFMatrix4f.rotationZ=function(a){var c=Math.cos(a);var s=Math.sin(a);return new x3dom.fields.SFMatrix4f(c,-s,0,0,s,c,0,0,0,0,1,0,0,0,0,1);};x3dom.fields.SFMatrix4f.scale=function(vec){return new x3dom.fields.SFMatrix4f(vec.x,0,0,0,0,vec.y,0,0,0,0,vec.z,0,0,0,0,1);};x3dom.fields.SFMatrix4f.lookAt=function(from,at,up)
{var view=from.subtract(at).normalize();var right=up.normalize().cross(view);if(right.dot(right)<x3dom.fields.Eps){x3dom.debug.logWarning("View matrix is linearly dependent.");return x3dom.fields.SFMatrix4f.translation(from);}
var newUp=view.cross(right.normalize()).normalize();var tmp=x3dom.fields.SFMatrix4f.identity();tmp.setValue(right,newUp,view,from);return tmp;};x3dom.fields.SFMatrix4f.prototype.setTranslate=function(vec){this._03=vec.x;this._13=vec.y;this._23=vec.z;};x3dom.fields.SFMatrix4f.prototype.setScale=function(vec){this._00=vec.x;this._11=vec.y;this._22=vec.z;};x3dom.fields.SFMatrix4f.parseRotation=function(str){var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);var x=+m[1],y=+m[2],z=+m[3],a=+m[4];var d=Math.sqrt(x*x+y*y+z*z);if(d===0){x=1;y=z=0;}else{x/=d;y/=d;z/=d;}
var c=Math.cos(a);var s=Math.sin(a);var t=1-c;return new x3dom.fields.SFMatrix4f(t*x*x+c,t*x*y+s*z,t*x*z-s*y,0,t*x*y-s*z,t*y*y+c,t*y*z+s*x,0,t*x*z+s*y,t*y*z-s*x,t*z*z+c,0,0,0,0,1).transpose();};x3dom.fields.SFMatrix4f.parse=function(str){var needTranspose=false;var val=/matrix.*\((.+)\)/;if(val.exec(str)){str=RegExp.$1;needTranspose=true;}
var arr=Array.map(str.split(/[,\s]+/),function(n){return+n;});if(arr.length>=16)
{if(!needTranspose){return new x3dom.fields.SFMatrix4f(arr[0],arr[1],arr[2],arr[3],arr[4],arr[5],arr[6],arr[7],arr[8],arr[9],arr[10],arr[11],arr[12],arr[13],arr[14],arr[15]);}
else{return new x3dom.fields.SFMatrix4f(arr[0],arr[4],arr[8],arr[12],arr[1],arr[5],arr[9],arr[13],arr[2],arr[6],arr[10],arr[14],arr[3],arr[7],arr[11],arr[15]);}}
else if(arr.length===6){return new x3dom.fields.SFMatrix4f(arr[0],arr[1],0,arr[4],arr[2],arr[3],0,arr[5],0,0,1,0,0,0,0,1);}
else{x3dom.debug.logWarning("SFMatrix4f - can't parse string: "+str);return x3dom.fields.SFMatrix4f.identity();}};x3dom.fields.SFMatrix4f.prototype.mult=function(that){return new x3dom.fields.SFMatrix4f(this._00*that._00+this._01*that._10+this._02*that._20+this._03*that._30,this._00*that._01+this._01*that._11+this._02*that._21+this._03*that._31,this._00*that._02+this._01*that._12+this._02*that._22+this._03*that._32,this._00*that._03+this._01*that._13+this._02*that._23+this._03*that._33,this._10*that._00+this._11*that._10+this._12*that._20+this._13*that._30,this._10*that._01+this._11*that._11+this._12*that._21+this._13*that._31,this._10*that._02+this._11*that._12+this._12*that._22+this._13*that._32,this._10*that._03+this._11*that._13+this._12*that._23+this._13*that._33,this._20*that._00+this._21*that._10+this._22*that._20+this._23*that._30,this._20*that._01+this._21*that._11+this._22*that._21+this._23*that._31,this._20*that._02+this._21*that._12+this._22*that._22+this._23*that._32,this._20*that._03+this._21*that._13+this._22*that._23+this._23*that._33,this._30*that._00+this._31*that._10+this._32*that._20+this._33*that._30,this._30*that._01+this._31*that._11+this._32*that._21+this._33*that._31,this._30*that._02+this._31*that._12+this._32*that._22+this._33*that._32,this._30*that._03+this._31*that._13+this._32*that._23+this._33*that._33);};x3dom.fields.SFMatrix4f.prototype.multMatrixPnt=function(vec){return new x3dom.fields.SFVec3f(this._00*vec.x+this._01*vec.y+this._02*vec.z+this._03,this._10*vec.x+this._11*vec.y+this._12*vec.z+this._13,this._20*vec.x+this._21*vec.y+this._22*vec.z+this._23);};x3dom.fields.SFMatrix4f.prototype.multMatrixVec=function(vec){return new x3dom.fields.SFVec3f(this._00*vec.x+this._01*vec.y+this._02*vec.z,this._10*vec.x+this._11*vec.y+this._12*vec.z,this._20*vec.x+this._21*vec.y+this._22*vec.z);};x3dom.fields.SFMatrix4f.prototype.multFullMatrixPnt=function(vec){var w=this._30*vec.x+this._31*vec.y+this._32*vec.z+this._33;if(w){w=1.0/w;}
return new x3dom.fields.SFVec3f((this._00*vec.x+this._01*vec.y+this._02*vec.z+this._03)*w,(this._10*vec.x+this._11*vec.y+this._12*vec.z+this._13)*w,(this._20*vec.x+this._21*vec.y+this._22*vec.z+this._23)*w);};x3dom.fields.SFMatrix4f.prototype.transpose=function(){return new x3dom.fields.SFMatrix4f(this._00,this._10,this._20,this._30,this._01,this._11,this._21,this._31,this._02,this._12,this._22,this._32,this._03,this._13,this._23,this._33);};x3dom.fields.SFMatrix4f.prototype.negate=function(){return new x3dom.fields.SFMatrix4f(-this._00,-this._01,-this._02,-this._03,-this._10,-this._11,-this._12,-this._13,-this._20,-this._21,-this._22,-this._23,-this._30,-this._31,-this._32,-this._33);};x3dom.fields.SFMatrix4f.prototype.multiply=function(s){return new x3dom.fields.SFMatrix4f(s*this._00,s*this._01,s*this._02,s*this._03,s*this._10,s*this._11,s*this._12,s*this._13,s*this._20,s*this._21,s*this._22,s*this._23,s*this._30,s*this._31,s*this._32,s*this._33);};x3dom.fields.SFMatrix4f.prototype.add=function(that){return new x3dom.fields.SFMatrix4f(this._00+that._00,this._01+that._01,this._02+that._02,this._03+that._03,this._10+that._10,this._11+that._11,this._12+that._12,this._13+that._13,this._20+that._20,this._21+that._21,this._22+that._22,this._23+that._23,this._30+that._30,this._31+that._31,this._32+that._32,this._33+that._33);};x3dom.fields.SFMatrix4f.prototype.addScaled=function(that,s){return new x3dom.fields.SFMatrix4f(this._00+s*that._00,this._01+s*that._01,this._02+s*that._02,this._03+s*that._03,this._10+s*that._10,this._11+s*that._11,this._12+s*that._12,this._13+s*that._13,this._20+s*that._20,this._21+s*that._21,this._22+s*that._22,this._23+s*that._23,this._30+s*that._30,this._31+s*that._31,this._32+s*that._32,this._33+s*that._33);};x3dom.fields.SFMatrix4f.prototype.setValues=function(that){this._00=that._00;this._01=that._01;this._02=that._02;this._03=that._03;this._10=that._10;this._11=that._11;this._12=that._12;this._13=that._13;this._20=that._20;this._21=that._21;this._22=that._22;this._23=that._23;this._30=that._30;this._31=that._31;this._32=that._32;this._33=that._33;};x3dom.fields.SFMatrix4f.prototype.setValue=function(v1,v2,v3,v4){this._00=v1.x;this._01=v2.x;this._02=v3.x;this._10=v1.y;this._11=v2.y;this._12=v3.y;this._20=v1.z;this._21=v2.z;this._22=v3.z;this._30=0;this._31=0;this._32=0;if(arguments.length>3){this._03=v4.x;this._13=v4.y;this._23=v4.z;this._33=1;}};x3dom.fields.SFMatrix4f.prototype.toGL=function(){return[this._00,this._10,this._20,this._30,this._01,this._11,this._21,this._31,this._02,this._12,this._22,this._32,this._03,this._13,this._23,this._33];};x3dom.fields.SFMatrix4f.prototype.at=function(i,j){var field="_"+i+j;return this[field];};x3dom.fields.SFMatrix4f.prototype.sqrt=function(){var iX=x3dom.fields.SFMatrix4f.identity(),Y=x3dom.fields.SFMatrix4f.identity(),iY=x3dom.fields.SFMatrix4f.identity(),result=x3dom.fields.SFMatrix4f.identity();var i,g,ig;result.setValues(this);for(i=0;i<6;i++)
{iX=result.inverse();iY=Y.inverse();g=Math.abs(Math.pow(result.det()*Y.det(),-0.125));ig=1.0/g;result=result.multiply(g);result=result.addScaled(iY,ig);result=result.multiply(0.5);Y=Y.multiply(g);Y=Y.addScaled(iX,ig);Y=Y.multiply(0.5);}
return result;};x3dom.fields.SFMatrix4f.prototype.normInfinity=function(){var t=0,m=0;if((t=Math.abs(this._00))>m){m=t;}
if((t=Math.abs(this._01))>m){m=t;}
if((t=Math.abs(this._02))>m){m=t;}
if((t=Math.abs(this._03))>m){m=t;}
if((t=Math.abs(this._10))>m){m=t;}
if((t=Math.abs(this._11))>m){m=t;}
if((t=Math.abs(this._12))>m){m=t;}
if((t=Math.abs(this._13))>m){m=t;}
if((t=Math.abs(this._20))>m){m=t;}
if((t=Math.abs(this._21))>m){m=t;}
if((t=Math.abs(this._22))>m){m=t;}
if((t=Math.abs(this._23))>m){m=t;}
if((t=Math.abs(this._30))>m){m=t;}
if((t=Math.abs(this._31))>m){m=t;}
if((t=Math.abs(this._32))>m){m=t;}
if((t=Math.abs(this._33))>m){m=t;}
return m;};x3dom.fields.SFMatrix4f.prototype.norm1_3x3=function(){var max,t=0;max=Math.abs(this._00)+
Math.abs(this._10)+
Math.abs(this._20);if((t=Math.abs(this._01)+
Math.abs(this._11)+
Math.abs(this._21))>max)
{max=t;}
if((t=Math.abs(this._02)+
Math.abs(this._12)+
Math.abs(this._22))>max)
{max=t;}
return max;};x3dom.fields.SFMatrix4f.prototype.normInf_3x3=function(){var max,t=0;max=Math.abs(this._00)+
Math.abs(this._01)+
Math.abs(this._02);if((t=Math.abs(this._10)+
Math.abs(this._11)+
Math.abs(this._12))>max)
{max=t;}
if((t=Math.abs(this._20)+
Math.abs(this._21)+
Math.abs(this._22))>max)
{max=t;}
return max;};x3dom.fields.SFMatrix4f.prototype.adjointT_3x3=function(){var result=x3dom.fields.SFMatrix4f.identity();result._00=this._11*this._22-this._12*this._21;result._01=this._12*this._20-this._10*this._22;result._02=this._10*this._21-this._11*this._20;result._10=this._21*this._02-this._22*this._01;result._11=this._22*this._00-this._20*this._02;result._12=this._20*this._01-this._21*this._00;result._20=this._01*this._12-this._02*this._11;result._21=this._02*this._10-this._00*this._12;result._22=this._00*this._11-this._01*this._10;return result;};x3dom.fields.SFMatrix4f.prototype.equals=function(that){var eps=0.000000000001;return Math.abs(this._00-that._00)<eps&&Math.abs(this._01-that._01)<eps&&Math.abs(this._02-that._02)<eps&&Math.abs(this._03-that._03)<eps&&Math.abs(this._10-that._10)<eps&&Math.abs(this._11-that._11)<eps&&Math.abs(this._12-that._12)<eps&&Math.abs(this._13-that._13)<eps&&Math.abs(this._20-that._20)<eps&&Math.abs(this._21-that._21)<eps&&Math.abs(this._22-that._22)<eps&&Math.abs(this._23-that._23)<eps&&Math.abs(this._30-that._30)<eps&&Math.abs(this._31-that._31)<eps&&Math.abs(this._32-that._32)<eps&&Math.abs(this._33-that._33)<eps;};x3dom.fields.SFMatrix4f.prototype.getTransform=function(translation,rotation,scaleFactor,scaleOrientation,center)
{var m=x3dom.fields.SFMatrix4f.identity();if(arguments.length>4){m=x3dom.fields.SFMatrix4f.translation(center.negate());m=m.mult(this);var c=x3dom.fields.SFMatrix4f.translation(center);m=m.mult(c);}
else{m.setValues(this);}
var flip=m.decompose(translation,rotation,scaleFactor,scaleOrientation);scaleFactor=scaleFactor.multiply(flip);};x3dom.fields.SFMatrix4f.prototype.decompose=function(t,r,s,so)
{var A=x3dom.fields.SFMatrix4f.identity();A.setValues(this);var Q=x3dom.fields.SFMatrix4f.identity(),S=x3dom.fields.SFMatrix4f.identity(),SO=x3dom.fields.SFMatrix4f.identity();t.x=A._03;t.y=A._13;t.z=A._23;A._03=0.0;A._13=0.0;A._23=0.0;A._30=0.0;A._31=0.0;A._32=0.0;var det=A.polarDecompose(Q,S);var f=1.0;if(det<0.0){Q=Q.negate();f=-1.0;}
else{f=1.0;}
r.setValue(Q);S.spectralDecompose(SO,s);so.setValue(SO);return f;};x3dom.fields.SFMatrix4f.prototype.polarDecompose=function(Q,S)
{var TOL=1.0e-6;var Mk=this.transpose();var Ek=x3dom.fields.SFMatrix4f.identity();var MkAdjT;var Mk_one=Mk.norm1_3x3();var Mk_inf=Mk.normInf_3x3();var MkAdjT_one,MkAdjT_inf;var Ek_one,Mk_det;do
{MkAdjT=Mk.adjointT_3x3();Mk_det=Mk._00*MkAdjT._00+
Mk._01*MkAdjT._01+
Mk._02*MkAdjT._02;if(Mk_det===0)
{x3dom.debug.logWarning("polarDecompose: Mk_det == 0.0");break;}
MkAdjT_one=MkAdjT.norm1_3x3();MkAdjT_inf=MkAdjT.normInf_3x3();var gamma=Math.sqrt(Math.sqrt((MkAdjT_one*MkAdjT_inf)/(Mk_one*Mk_inf))/Math.abs(Mk_det));var g1=0.5*gamma;var g2=0.5/(gamma*Mk_det);Ek.setValues(Mk);Mk=Mk.multiply(g1);Mk=Mk.addScaled(MkAdjT,g2);Ek=Ek.addScaled(Mk,-1.0);Ek_one=Ek.norm1_3x3();Mk_one=Mk.norm1_3x3();Mk_inf=Mk.normInf_3x3();}while(Ek_one>(Mk_one*TOL));var Q=Mk.transpose();var S=Mk.mult(this);var i,j;for(i=0;i<3;++i)
{for(j=i;j<3;++j)
{S['_'+j+i]=0.5*(S['_'+j+i]+S['_'+i+j]);S['_'+i+j]=0.5*(S['_'+j+i]+S['_'+i+j]);}}
return Mk_det;};x3dom.fields.SFMatrix4f.prototype.spectralDecompose=function(SO,k)
{var next=[1,2,0];var maxIterations=20;var iter,i,j;var diag=[],offDiag=[];diag[0]=this._00;diag[1]=this._11;diag[2]=this._22;offDiag[0]=this._12;offDiag[1]=this._20;offDiag[2]=this._01;for(iter=0;iter<maxIterations;++iter)
{var sm=Math.abs(offDiag[0])+Math.abs(offDiag[1])+Math.abs(offDiag[2]);if(sm===0){break;}
for(i=2;i>=0;--i)
{var p=next[i];var q=next[p];var absOffDiag=Math.abs(offDiag[i]);var g=100.0*absOffDiag;if(absOffDiag>0.0)
{var t,h=diag[q]-diag[p];var absh=Math.abs(h);if(absh+g==absh)
{t=offDiag[i]/h;}
else
{var theta=0.5*h/offDiag[i];t=1.0/(Math.abs(theta)+Math.sqrt(theta*theta+1.0));t=theta<0.0?-t:t;}
var c=1.0/Math.sqrt(t*t+1.0);var s=t*c;var tau=s/(c+1.0);var ta=t*offDiag[i];offDiag[i]=0.0;diag[p]-=ta;diag[q]+=ta;var offDiagq=offDiag[q];offDiag[q]-=s*(offDiag[p]+tau*offDiagq);offDiag[p]+=s*(offDiagq-tau*offDiag[p]);for(j=2;j>=0;--j)
{var a=SO['_'+j+p];var b=SO['_'+j+q];SO['_'+j+p]-=s*(b+tau*a);SO['_'+j+q]+=s*(a-tau*b);}}}}
k.x=diag[0];k.y=diag[1];k.z=diag[2];};x3dom.fields.SFMatrix4f.prototype.log=function(){var maxiter=12;var k=0,i=0;var eps=0.000000000001;var A=x3dom.fields.SFMatrix4f.identity(),Z=x3dom.fields.SFMatrix4f.identity(),result=x3dom.fields.SFMatrix4f.identity();A.setValues(this);Z.setValues(this);Z._00-=1;Z._11-=1;Z._22-=1;Z._33-=1;while(Z.normInfinity()>0.5)
{A=A.sqrt();Z.setValues(A);Z._00-=1;Z._11-=1;Z._22-=1;Z._33-=1;k++;}
A._00-=1;A._11-=1;A._22-=1;A._33-=1;A=A.negate();result.setValues(A);Z.setValues(A);i=1;while(Z.normInfinity()>eps&&i<maxiter)
{Z=Z.mult(A);i++;result=result.addScaled(Z,(1.0/i));}
result=result.multiply((-1.0)*(1<<k));return result;};x3dom.fields.SFMatrix4f.prototype.exp=function(){var q=6;var A=x3dom.fields.SFMatrix4f.identity(),D=x3dom.fields.SFMatrix4f.identity(),N=x3dom.fields.SFMatrix4f.identity(),result=x3dom.fields.SFMatrix4f.identity();var j=1,k=0,c=1.0;A.setValues(this);j+=Math.floor(Math.log(A.normInfinity()/0.693));if(j<0){j=0;}
A=A.multiply(1.0/(1<<j));for(k=1;k<=q;k++)
{c*=(q-k+1)/(k*(2*q-k+1));result=A.mult(result);N=N.addScaled(result,c);if(k%2)
{D=D.addScaled(result,-c);}
else
{D=D.addScaled(result,c);}}
result=D.inverse().mult(N);for(k=0;k<j;k++)
{result=result.mult(result);}
return result;};x3dom.fields.SFMatrix4f.prototype.det3=function(a1,a2,a3,b1,b2,b3,c1,c2,c3){var d=(a1*b2*c3)+(a2*b3*c1)+(a3*b1*c2)-
(a1*b3*c2)-(a2*b1*c3)-(a3*b2*c1);return d;};x3dom.fields.SFMatrix4f.prototype.det=function(){var a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;a1=this._00;b1=this._10;c1=this._20;d1=this._30;a2=this._01;b2=this._11;c2=this._21;d2=this._31;a3=this._02;b3=this._12;c3=this._22;d3=this._32;a4=this._03;b4=this._13;c4=this._23;d4=this._33;var d=+a1*this.det3(b2,b3,b4,c2,c3,c4,d2,d3,d4)-
b1*this.det3(a2,a3,a4,c2,c3,c4,d2,d3,d4)+
c1*this.det3(a2,a3,a4,b2,b3,b4,d2,d3,d4)-
d1*this.det3(a2,a3,a4,b2,b3,b4,c2,c3,c4);return d;};x3dom.fields.SFMatrix4f.prototype.inverse=function(){var a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;a1=this._00;b1=this._10;c1=this._20;d1=this._30;a2=this._01;b2=this._11;c2=this._21;d2=this._31;a3=this._02;b3=this._12;c3=this._22;d3=this._32;a4=this._03;b4=this._13;c4=this._23;d4=this._33;var rDet=this.det();if(Math.abs(rDet)===0)
{x3dom.debug.logWarning("Invert matrix: singular matrix, no inverse!");return x3dom.fields.SFMatrix4f.identity();}
rDet=1.0/rDet;return new x3dom.fields.SFMatrix4f(+this.det3(b2,b3,b4,c2,c3,c4,d2,d3,d4)*rDet,-this.det3(a2,a3,a4,c2,c3,c4,d2,d3,d4)*rDet,+this.det3(a2,a3,a4,b2,b3,b4,d2,d3,d4)*rDet,-this.det3(a2,a3,a4,b2,b3,b4,c2,c3,c4)*rDet,-this.det3(b1,b3,b4,c1,c3,c4,d1,d3,d4)*rDet,+this.det3(a1,a3,a4,c1,c3,c4,d1,d3,d4)*rDet,-this.det3(a1,a3,a4,b1,b3,b4,d1,d3,d4)*rDet,+this.det3(a1,a3,a4,b1,b3,b4,c1,c3,c4)*rDet,+this.det3(b1,b2,b4,c1,c2,c4,d1,d2,d4)*rDet,-this.det3(a1,a2,a4,c1,c2,c4,d1,d2,d4)*rDet,+this.det3(a1,a2,a4,b1,b2,b4,d1,d2,d4)*rDet,-this.det3(a1,a2,a4,b1,b2,b4,c1,c2,c4)*rDet,-this.det3(b1,b2,b3,c1,c2,c3,d1,d2,d3)*rDet,+this.det3(a1,a2,a3,c1,c2,c3,d1,d2,d3)*rDet,-this.det3(a1,a2,a3,b1,b2,b3,d1,d2,d3)*rDet,+this.det3(a1,a2,a3,b1,b2,b3,c1,c2,c3)*rDet);};x3dom.fields.SFMatrix4f.prototype.toString=function(){return'[SFMatrix4f \n'+
this._00.toFixed(6)+', '+this._01.toFixed(6)+', '+
this._02.toFixed(6)+', '+this._03.toFixed(6)+', \n'+
this._10.toFixed(6)+', '+this._11.toFixed(6)+', '+
this._12.toFixed(6)+', '+this._13.toFixed(6)+', \n'+
this._20.toFixed(6)+', '+this._21.toFixed(6)+', '+
this._22.toFixed(6)+', '+this._23.toFixed(6)+', \n'+
this._30.toFixed(6)+', '+this._31.toFixed(6)+', '+
this._32.toFixed(6)+', '+this._33.toFixed(6)+']';};x3dom.fields.SFMatrix4f.prototype.setValueByStr=function(str){var needTranspose=false;var val=/matrix.*\((.+)\)/;if(val.exec(str)){str=RegExp.$1;needTranspose=true;}
var arr=Array.map(str.split(/[,\s]+/),function(n){return+n;});if(arr.length>=16)
{if(!needTranspose){this._00=arr[0];this._01=arr[1];this._02=arr[2];this._03=arr[3];this._10=arr[4];this._11=arr[5];this._12=arr[6];this._13=arr[7];this._20=arr[8];this._21=arr[9];this._22=arr[10];this._23=arr[11];this._30=arr[12];this._31=arr[13];this._32=arr[14];this._33=arr[15];}
else{this._00=arr[0];this._01=arr[4];this._02=arr[8];this._03=arr[12];this._10=arr[1];this._11=arr[5];this._12=arr[9];this._13=arr[13];this._20=arr[2];this._21=arr[6];this._22=arr[10];this._23=arr[14];this._30=arr[3];this._31=arr[7];this._32=arr[11];this._33=arr[15];}}
else if(arr.length===6){this._00=arr[0];this._01=arr[1];this._02=0;this._03=arr[4];this._10=arr[2];this._11=arr[3];this._12=0;this._13=arr[5];this._20=0;this._21=0;this._22=1;this._23=0;this._30=0;this._31=0;this._32=0;this._33=1;}
else{x3dom.debug.logWarning("SFMatrix4f - can't parse string: "+str);}
return this;};x3dom.fields.SFVec2f=function(x,y){if(arguments.length===0){this.x=this.y=0;}
else{this.x=x;this.y=y;}};x3dom.fields.SFVec2f.parse=function(str){var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);return new x3dom.fields.SFVec2f(+m[1],+m[2]);};x3dom.fields.SFVec2f.prototype.setValues=function(that){this.x=that.x;this.y=that.y;};x3dom.fields.SFVec2f.prototype.add=function(that){return new x3dom.fields.SFVec2f(this.x+that.x,this.y+that.y);};x3dom.fields.SFVec2f.prototype.subtract=function(that){return new x3dom.fields.SFVec2f(this.x-that.x,this.y-that.y);};x3dom.fields.SFVec2f.prototype.negate=function(){return new x3dom.fields.SFVec2f(-this.x,-this.y);};x3dom.fields.SFVec2f.prototype.dot=function(that){return this.x*that.x+this.y*that.y;};x3dom.fields.SFVec2f.prototype.reflect=function(n){var d2=this.dot(n)*2;return new x3dom.fields.SFVec2f(this.x-d2*n.x,this.y-d2*n.y);};x3dom.fields.SFVec2f.prototype.normalize=function(that){var n=this.length();if(n){n=1.0/n;}
return new x3dom.fields.SFVec2f(this.x*n,this.y*n);};x3dom.fields.SFVec2f.prototype.multComponents=function(that){return new x3dom.fields.SFVec2f(this.x*that.x,this.y*that.y);};x3dom.fields.SFVec2f.prototype.multiply=function(n){return new x3dom.fields.SFVec2f(this.x*n,this.y*n);};x3dom.fields.SFVec2f.prototype.divide=function(n){var denom=n?(1.0/n):1.0;return new x3dom.fields.SFVec2f(this.x*denom,this.y*denom);};x3dom.fields.SFVec2f.prototype.equals=function(that,eps){return Math.abs(this.x-that.x)<eps&&Math.abs(this.y-that.y)<eps;};x3dom.fields.SFVec2f.prototype.length=function(){return Math.sqrt((this.x*this.x)+(this.y*this.y));};x3dom.fields.SFVec2f.prototype.toGL=function(){return[this.x,this.y];};x3dom.fields.SFVec2f.prototype.toString=function(){return"{ x "+this.x+" y "+this.y+" }";};x3dom.fields.SFVec2f.prototype.setValueByStr=function(str){var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);this.x=+m[1];this.y=+m[2];return this;};x3dom.fields.SFVec3f=function(x,y,z){if(arguments.length===0){this.x=this.y=this.z=0;}
else{this.x=x;this.y=y;this.z=z;}};x3dom.fields.SFVec3f.copy=function(v){return new x3dom.fields.SFVec3f(v.x,v.y,v.z);};x3dom.fields.SFVec3f.MIN=function(){return new x3dom.fields.SFVec3f(Number.MIN_VALUE,Number.MIN_VALUE,Number.MIN_VALUE);};x3dom.fields.SFVec3f.MAX=function(){return new x3dom.fields.SFVec3f(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE);};x3dom.fields.SFVec3f.parse=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);return new x3dom.fields.SFVec3f(+m[1],+m[2],+m[3]);}
catch(e){var c=x3dom.fields.SFColor.colorParse(str);return new x3dom.fields.SFVec3f(c.r,c.g,c.b);}};x3dom.fields.SFVec3f.prototype.setValues=function(that){this.x=that.x;this.y=that.y;this.z=that.z;};x3dom.fields.SFVec3f.prototype.add=function(that){return new x3dom.fields.SFVec3f(this.x+that.x,this.y+that.y,this.z+that.z);};x3dom.fields.SFVec3f.prototype.addScaled=function(that,s){return new x3dom.fields.SFVec3f(this.x+s*that.x,this.y+s*that.y,this.z+s*that.z);};x3dom.fields.SFVec3f.prototype.subtract=function(that){return new x3dom.fields.SFVec3f(this.x-that.x,this.y-that.y,this.z-that.z);};x3dom.fields.SFVec3f.prototype.negate=function(){return new x3dom.fields.SFVec3f(-this.x,-this.y,-this.z);};x3dom.fields.SFVec3f.prototype.dot=function(that){return(this.x*that.x+this.y*that.y+this.z*that.z);};x3dom.fields.SFVec3f.prototype.cross=function(that){return new x3dom.fields.SFVec3f(this.y*that.z-this.z*that.y,this.z*that.x-this.x*that.z,this.x*that.y-this.y*that.x);};x3dom.fields.SFVec3f.prototype.reflect=function(n){var d2=this.dot(n)*2;return new x3dom.fields.SFVec3f(this.x-d2*n.x,this.y-d2*n.y,this.z-d2*n.z);};x3dom.fields.SFVec3f.prototype.length=function(){return Math.sqrt((this.x*this.x)+(this.y*this.y)+(this.z*this.z));};x3dom.fields.SFVec3f.prototype.normalize=function(that){var n=this.length();if(n){n=1.0/n;}
return new x3dom.fields.SFVec3f(this.x*n,this.y*n,this.z*n);};x3dom.fields.SFVec3f.prototype.multComponents=function(that){return new x3dom.fields.SFVec3f(this.x*that.x,this.y*that.y,this.z*that.z);};x3dom.fields.SFVec3f.prototype.multiply=function(n){return new x3dom.fields.SFVec3f(this.x*n,this.y*n,this.z*n);};x3dom.fields.SFVec3f.prototype.divide=function(n){var denom=n?(1.0/n):1.0;return new x3dom.fields.SFVec3f(this.x*denom,this.y*denom,this.z*denom);};x3dom.fields.SFVec3f.prototype.equals=function(that,eps){return Math.abs(this.x-that.x)<eps&&Math.abs(this.y-that.y)<eps&&Math.abs(this.z-that.z)<eps;};x3dom.fields.SFVec3f.prototype.toGL=function(){return[this.x,this.y,this.z];};x3dom.fields.SFVec3f.prototype.toString=function(){return"{ x "+this.x+" y "+this.y+" z "+this.z+" }";};x3dom.fields.SFVec3f.prototype.setValueByStr=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);this.x=+m[1];this.y=+m[2];this.z=+m[3];}
catch(e){var c=x3dom.fields.SFColor.colorParse(str);this.x=c.r;this.y=c.g;this.z=c.b;}
return this;};x3dom.fields.Quaternion=function(x,y,z,w){this.x=x;this.y=y;this.z=z;this.w=w;};x3dom.fields.Quaternion.prototype.multiply=function(that){return new x3dom.fields.Quaternion(this.w*that.x+this.x*that.w+this.y*that.z-this.z*that.y,this.w*that.y+this.y*that.w+this.z*that.x-this.x*that.z,this.w*that.z+this.z*that.w+this.x*that.y-this.y*that.x,this.w*that.w-this.x*that.x-this.y*that.y-this.z*that.z);};x3dom.fields.Quaternion.parseAxisAngle=function(str){var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);return x3dom.fields.Quaternion.axisAngle(new x3dom.fields.SFVec3f(+m[1],+m[2],+m[3]),+m[4]);};x3dom.fields.Quaternion.axisAngle=function(axis,a){var t=axis.length();if(t>x3dom.fields.Eps)
{var s=Math.sin(a/2)/t;var c=Math.cos(a/2);return new x3dom.fields.Quaternion(axis.x*s,axis.y*s,axis.z*s,c);}
else
{return new x3dom.fields.Quaternion(0,0,0,1);}};x3dom.fields.Quaternion.prototype.toMatrix=function(){var xx=this.x*this.x;var xy=this.x*this.y;var xz=this.x*this.z;var yy=this.y*this.y;var yz=this.y*this.z;var zz=this.z*this.z;var wx=this.w*this.x;var wy=this.w*this.y;var wz=this.w*this.z;return new x3dom.fields.SFMatrix4f(1-2*(yy+zz),2*(xy-wz),2*(xz+wy),0,2*(xy+wz),1-2*(xx+zz),2*(yz-wx),0,2*(xz-wy),2*(yz+wx),1-2*(xx+yy),0,0,0,0,1);};x3dom.fields.Quaternion.prototype.toAxisAngle=function()
{var x=0,y=0,z=0;var s=0,a=0;var that=this;if(this.w>1)
{that=x3dom.fields.Quaternion.normalize(this);}
a=2*Math.acos(that.w);s=Math.sqrt(1-that.w*that.w);if(s===0)
{x=that.x;y=that.y;z=that.z;}
else
{x=that.x/s;y=that.y/s;z=that.z/s;}
return[new x3dom.fields.SFVec3f(x,y,z),a];};x3dom.fields.Quaternion.prototype.angle=function()
{return 2*Math.acos(this.w);};x3dom.fields.Quaternion.prototype.setValue=function(matrix)
{var tr,s=1;var qt=[0,0,0];var i=0,j=0,k=0;var nxt=[1,2,0];tr=matrix._00+matrix._11+matrix._22;if(tr>0.0)
{s=Math.sqrt(tr+1.0);this.w=s*0.5;s=0.5/s;this.x=(matrix._21-matrix._12)*s;this.y=(matrix._02-matrix._20)*s;this.z=(matrix._10-matrix._01)*s;}
else
{if(matrix._11>matrix._00){i=1;}
else{i=0;}
if(matrix._22>matrix.at(i,i)){i=2;}
j=nxt[i];k=nxt[j];s=Math.sqrt(matrix.at(i,i)-(matrix.at(j,j)+matrix.at(k,k))+1.0);qt[i]=s*0.5;s=0.5/s;this.w=(matrix.at(k,j)-matrix.at(j,k))*s;qt[j]=(matrix.at(j,i)+matrix.at(i,j))*s;qt[k]=(matrix.at(k,i)+matrix.at(i,k))*s;this.x=qt[0];this.y=qt[1];this.z=qt[2];}
if(this.w>1.0||this.w<-1.0)
{var errThreshold=1+(x3dom.fields.Eps*100);if(this.w>errThreshold||this.w<-errThreshold)
{x3dom.debug.logInfo("MatToQuat: BUG: |quat[4]| ("+this.w+") >> 1.0 !");}
if(this.w>1.0){this.w=1.0;}
else{this.w=-1.0;}}};x3dom.fields.Quaternion.prototype.dot=function(that){return this.x*that.x+this.y*that.y+this.z*that.z+this.w*that.w;};x3dom.fields.Quaternion.prototype.add=function(that){return new x3dom.fields.Quaternion(this.x+that.x,this.y+that.y,this.z+that.z,this.w+that.w);};x3dom.fields.Quaternion.prototype.subtract=function(that){return new x3dom.fields.Quaternion(this.x-that.x,this.y-that.y,this.z-that.z,this.w-that.w);};x3dom.fields.Quaternion.prototype.setValues=function(that){this.x=that.x;this.y=that.y;this.z=that.z;this.w=that.w;};x3dom.fields.Quaternion.prototype.equals=function(that,eps){return Math.abs(this.x-that.x)<eps&&Math.abs(this.y-that.y)<eps&&Math.abs(this.z-that.z)<eps&&Math.abs(this.w-that.w)<eps;};x3dom.fields.Quaternion.prototype.multScalar=function(s){return new x3dom.fields.Quaternion(this.x*s,this.y*s,this.z*s,this.w*s);};x3dom.fields.Quaternion.prototype.normalize=function(that){var d2=this.dot(that);var id=1.0;if(d2){id=1.0/Math.sqrt(d2);}
return new x3dom.fields.Quaternion(this.x*id,this.y*id,this.z*id,this.w*id);};x3dom.fields.Quaternion.prototype.negate=function(){return new x3dom.fields.Quaternion(-this.x,-this.y,-this.z,-this.w);};x3dom.fields.Quaternion.prototype.inverse=function(){return new x3dom.fields.Quaternion(-this.x,-this.y,-this.z,this.w);};x3dom.fields.Quaternion.prototype.slerp=function(that,t){var cosom=this.dot(that);var rot1;if(cosom<0.0)
{cosom=-cosom;rot1=that.negate();}
else
{rot1=new x3dom.fields.Quaternion(that.x,that.y,that.z,that.w);}
var scalerot0,scalerot1;if((1.0-cosom)>0.00001)
{var omega=Math.acos(cosom);var sinom=Math.sin(omega);scalerot0=Math.sin((1.0-t)*omega)/sinom;scalerot1=Math.sin(t*omega)/sinom;}
else
{scalerot0=1.0-t;scalerot1=t;}
return this.multScalar(scalerot0).add(rot1.multScalar(scalerot1));};x3dom.fields.Quaternion.rotateFromTo=function(fromVec,toVec){var from=fromVec.normalize();var to=toVec.normalize();var cost=from.dot(to);if(cost>0.99999)
{return new x3dom.fields.Quaternion(0,0,0,1);}
else if(cost<-0.99999)
{var cAxis=new x3dom.fields.SFVec3f(1,0,0);var tmp=from.cross(cAxis);if(tmp.length()<0.00001)
{cAxis.x=0;cAxis.y=1;cAxis.z=0;tmp=from.cross(cAxis);}
tmp=tmp.normalize();return x3dom.fields.Quaternion.axisAngle(tmp,Math.PI);}
var axis=fromVec.cross(toVec);axis=axis.normalize();var s=Math.sqrt(0.5*(1.0-cost));axis=axis.multiply(s);s=Math.sqrt(0.5*(1.0+cost));return new x3dom.fields.Quaternion(axis.x,axis.y,axis.z,s);};x3dom.fields.Quaternion.prototype.toString=function(){return'(('+this.x+', '+this.y+', '+this.z+'), '+this.w+')';};x3dom.fields.Quaternion.prototype.setValueByStr=function(str){var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);var quat=x3dom.fields.Quaternion.axisAngle(new x3dom.fields.SFVec3f(+m[1],+m[2],+m[3]),+m[4]);this.x=quat.x;this.y=quat.y;this.z=quat.z;this.w=quat.w;return this;};x3dom.fields.SFColor=function(r,g,b){if(arguments.length===0){this.r=this.g=this.b=0;}
else{this.r=r;this.g=g;this.b=b;}};x3dom.fields.SFColor.parse=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);return new x3dom.fields.SFColor(+m[1],+m[2],+m[3]);}
catch(e){return x3dom.fields.SFColor.colorParse(str);}};x3dom.fields.SFColor.prototype.setHSV=function(h,s,v){x3dom.debug.logWarning("SFColor.setHSV() NYI");};x3dom.fields.SFColor.prototype.getHSV=function(){var h=0,s=0,v=0;x3dom.debug.logWarning("SFColor.getHSV() NYI");return[h,s,v];};x3dom.fields.SFColor.prototype.setValues=function(color){this.r=color.r;this.g=color.g;this.b=color.b;};x3dom.fields.SFColor.prototype.equals=function(that,eps){return Math.abs(this.r-that.r)<eps&&Math.abs(this.g-that.g)<eps&&Math.abs(this.b-that.b)<eps;};x3dom.fields.SFColor.prototype.add=function(that){return new x3dom.fields.SFColor(this.r+that.r,this.g+that.g,this.b+that.b);};x3dom.fields.SFColor.prototype.subtract=function(that){return new x3dom.fields.SFColor(this.r-that.r,this.g-that.g,this.b-that.b);};x3dom.fields.SFColor.prototype.multiply=function(n){return new x3dom.fields.SFColor(this.r*n,this.g*n,this.b*n);};x3dom.fields.SFColor.prototype.toGL=function(){return[this.r,this.g,this.b];};x3dom.fields.SFColor.prototype.toString=function(){return"{ r "+this.r+" g "+this.g+" b "+this.b+" }";};x3dom.fields.SFColor.prototype.setValueByStr=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);this.r=+m[1];this.g=+m[2];this.b=+m[3];}
catch(e){var c=x3dom.fields.SFColor.colorParse(str);this.r=c.r;this.g=c.g;this.b=c.b;}
return this;};x3dom.fields.SFColor.colorParse=function(color){var red=0,green=0,blue=0;var color_names={aliceblue:'f0f8ff',antiquewhite:'faebd7',aqua:'00ffff',aquamarine:'7fffd4',azure:'f0ffff',beige:'f5f5dc',bisque:'ffe4c4',black:'000000',blanchedalmond:'ffebcd',blue:'0000ff',blueviolet:'8a2be2',brown:'a52a2a',burlywood:'deb887',cadetblue:'5f9ea0',chartreuse:'7fff00',chocolate:'d2691e',coral:'ff7f50',cornflowerblue:'6495ed',cornsilk:'fff8dc',crimson:'dc143c',cyan:'00ffff',darkblue:'00008b',darkcyan:'008b8b',darkgoldenrod:'b8860b',darkgray:'a9a9a9',darkgreen:'006400',darkkhaki:'bdb76b',darkmagenta:'8b008b',darkolivegreen:'556b2f',darkorange:'ff8c00',darkorchid:'9932cc',darkred:'8b0000',darksalmon:'e9967a',darkseagreen:'8fbc8f',darkslateblue:'483d8b',darkslategray:'2f4f4f',darkturquoise:'00ced1',darkviolet:'9400d3',deeppink:'ff1493',deepskyblue:'00bfff',dimgray:'696969',dodgerblue:'1e90ff',feldspar:'d19275',firebrick:'b22222',floralwhite:'fffaf0',forestgreen:'228b22',fuchsia:'ff00ff',gainsboro:'dcdcdc',ghostwhite:'f8f8ff',gold:'ffd700',goldenrod:'daa520',gray:'808080',green:'008000',greenyellow:'adff2f',honeydew:'f0fff0',hotpink:'ff69b4',indianred:'cd5c5c',indigo:'4b0082',ivory:'fffff0',khaki:'f0e68c',lavender:'e6e6fa',lavenderblush:'fff0f5',lawngreen:'7cfc00',lemonchiffon:'fffacd',lightblue:'add8e6',lightcoral:'f08080',lightcyan:'e0ffff',lightgoldenrodyellow:'fafad2',lightgrey:'d3d3d3',lightgreen:'90ee90',lightpink:'ffb6c1',lightsalmon:'ffa07a',lightseagreen:'20b2aa',lightskyblue:'87cefa',lightslateblue:'8470ff',lightslategray:'778899',lightsteelblue:'b0c4de',lightyellow:'ffffe0',lime:'00ff00',limegreen:'32cd32',linen:'faf0e6',magenta:'ff00ff',maroon:'800000',mediumaquamarine:'66cdaa',mediumblue:'0000cd',mediumorchid:'ba55d3',mediumpurple:'9370d8',mediumseagreen:'3cb371',mediumslateblue:'7b68ee',mediumspringgreen:'00fa9a',mediumturquoise:'48d1cc',mediumvioletred:'c71585',midnightblue:'191970',mintcream:'f5fffa',mistyrose:'ffe4e1',moccasin:'ffe4b5',navajowhite:'ffdead',navy:'000080',oldlace:'fdf5e6',olive:'808000',olivedrab:'6b8e23',orange:'ffa500',orangered:'ff4500',orchid:'da70d6',palegoldenrod:'eee8aa',palegreen:'98fb98',paleturquoise:'afeeee',palevioletred:'d87093',papayawhip:'ffefd5',peachpuff:'ffdab9',peru:'cd853f',pink:'ffc0cb',plum:'dda0dd',powderblue:'b0e0e6',purple:'800080',red:'ff0000',rosybrown:'bc8f8f',royalblue:'4169e1',saddlebrown:'8b4513',salmon:'fa8072',sandybrown:'f4a460',seagreen:'2e8b57',seashell:'fff5ee',sienna:'a0522d',silver:'c0c0c0',skyblue:'87ceeb',slateblue:'6a5acd',slategray:'708090',snow:'fffafa',springgreen:'00ff7f',steelblue:'4682b4',tan:'d2b48c',teal:'008080',thistle:'d8bfd8',tomato:'ff6347',turquoise:'40e0d0',violet:'ee82ee',violetred:'d02090',wheat:'f5deb3',white:'ffffff',whitesmoke:'f5f5f5',yellow:'ffff00',yellowgreen:'9acd32'};if(color_names[color]){color="#"+color_names[color];}
if(color.substr&&color.substr(0,1)==="#"){color=color.substr(1);var len=color.length;if(len===6){red=parseInt("0x"+color.substr(0,2),16)/255.0;green=parseInt("0x"+color.substr(2,2),16)/255.0;blue=parseInt("0x"+color.substr(4,2),16)/255.0;}
else if(len===3){red=parseInt("0x"+color.substr(0,1),16)/15.0;green=parseInt("0x"+color.substr(1,1),16)/15.0;blue=parseInt("0x"+color.substr(2,1),16)/15.0;}}
return new x3dom.fields.SFColor(red,green,blue);};x3dom.fields.SFImage=function(w,h,c,arr){if(arguments.length===0){this.width=this.height=this.comp=0;this.array=[];}
else{this.width=w;this.height=h;this.comp=c;arr.map(function(v){this.array.push(v);},this.array);}};x3dom.fields.SFImage.parse=function(str){var img=new x3dom.fields.SFImage();img.setValueByStr(str);return img;};x3dom.fields.SFImage.prototype.setValueByStr=function(str){var mc=str.match(/(\w+)/g);var n=mc.length;var c2=0;var hex="0123456789ABCDEF";this.array=[];if(n>2){this.width=+mc[0];this.height=+mc[1];this.comp=+mc[2];c2=2*this.comp;}else{this.width=0;this.height=0;this.comp=0;return;}
var len,i;for(i=3;i<n;i++){if(!mc[i].substr){continue;}
if(mc[i].substr(1,1).toLowerCase()!=="x"){var out="";var inp=parseInt(mc[i],10);while(inp!==0){out=hex.charAt(inp%16)+out;inp=inp>>4;}
len=out.length;while(out.length<c2){out="0"+out;}
mc[i]="0x"+out;}
if(mc[i].substr(1,1).toLowerCase()==="x"){mc[i]=mc[i].substr(2);len=mc[i].length;var r,g,b,a;if(len===c2){if(this.comp===1){r=parseInt("0x"+mc[i].substr(0,2),16);this.array.push(r);}
else if(this.comp===2){r=parseInt("0x"+mc[i].substr(0,2),16);g=parseInt("0x"+mc[i].substr(2,2),16);this.array.push(r,g);}
else if(this.comp===3){r=parseInt("0x"+mc[i].substr(0,2),16);g=parseInt("0x"+mc[i].substr(2,2),16);b=parseInt("0x"+mc[i].substr(4,2),16);this.array.push(r,g,b);}
else if(this.comp===4){r=parseInt("0x"+mc[i].substr(0,2),16);g=parseInt("0x"+mc[i].substr(2,2),16);b=parseInt("0x"+mc[i].substr(4,2),16);a=parseInt("0x"+mc[i].substr(6,2),16);this.array.push(r,g,b,a);}}}}};x3dom.fields.SFImage.prototype.toGL=function(){var a=[];Array.map(this.array,function(c){a.push(c);});return a;};x3dom.fields.MFColor=function(colorArray){if(arguments.length===0){}else{var that=this;colorArray.map(function(c){that.push(c);},this);}};x3dom.fields.MFColor.prototype=x3dom.extend([]);x3dom.fields.MFColor.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var colors=[];for(var i=0,n=mc.length;i<n;i+=3){colors.push(new x3dom.fields.SFColor(+mc[i+0],+mc[i+1],+mc[i+2]));}
return new x3dom.fields.MFColor(colors);};x3dom.fields.MFColor.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i+=3){this.push(new x3dom.fields.SFColor(+mc[i+0],+mc[i+1],+mc[i+2]));}};x3dom.fields.MFColor.prototype.toGL=function(){var a=[];Array.map(this,function(c){a.push(c.r);a.push(c.g);a.push(c.b);});return a;};x3dom.fields.SFColorRGBA=function(r,g,b,a){if(arguments.length===0){this.r=this.g=this.b=this.a=0;}
else{this.r=r;this.g=g;this.b=b;this.a=a;}};x3dom.fields.SFColorRGBA.parse=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);return new x3dom.fields.SFColorRGBA(+m[1],+m[2],+m[3],+m[4]);}
catch(e){return x3dom.fields.SFColorRGBA.colorParse(str);}};x3dom.fields.SFColorRGBA.prototype.setValues=function(color){this.r=color.r;this.g=color.g;this.b=color.b;this.a=color.a;};x3dom.fields.SFColorRGBA.prototype.equals=function(that,eps){return Math.abs(this.r-that.r)<eps&&Math.abs(this.g-that.g)<eps&&Math.abs(this.b-that.b)<eps&&Math.abs(this.a-that.a)<eps;};x3dom.fields.SFColorRGBA.prototype.toGL=function(){return[this.r,this.g,this.b,this.a];};x3dom.fields.SFColorRGBA.prototype.toString=function(){return"{ r "+this.r+" g "+this.g+" b "+this.b+" a "+this.a+" }";};x3dom.fields.SFColorRGBA.prototype.setValueByStr=function(str){try{var m=/^([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)$/.exec(str);this.r=+m[1];this.g=+m[2];this.b=+m[3];this.a=+m[4];}
catch(e){var c=x3dom.fields.SFColorRGBA.colorParse(str);this.r=c.r;this.g=c.g;this.b=c.b;this.a=c.a;}
return this;};x3dom.fields.MFColorRGBA=function(colorArray){if(arguments.length===0){}
else{var that=this;colorArray.map(function(c){that.push(c);},this);}};x3dom.fields.MFColorRGBA.prototype=x3dom.extend([]);x3dom.fields.MFColorRGBA.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var colors=[];for(var i=0,n=mc.length;i<n;i+=4){colors.push(new x3dom.fields.SFColorRGBA(+mc[i+0],+mc[i+1],+mc[i+2],+mc[i+3]));}
return new x3dom.fields.MFColorRGBA(colors);};x3dom.fields.MFColorRGBA.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i+=4){this.push(new x3dom.fields.SFColor(+mc[i+0],+mc[i+1],+mc[i+2],+mc[i+3]));}};x3dom.fields.MFColorRGBA.prototype.toGL=function(){var a=[];Array.map(this,function(c){a.push(c.r);a.push(c.g);a.push(c.b);a.push(c.a);});return a;};x3dom.fields.MFRotation=function(rotArray){if(arguments.length===0){}
else{var that=this;rotArray.map(function(v){that.push(v);},this);}};x3dom.fields.MFRotation.prototype=x3dom.extend([]);x3dom.fields.MFRotation.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc.length;i<n;i+=4){vecs.push(x3dom.fields.Quaternion.axisAngle(new x3dom.fields.SFVec3f(+mc[i+0],+mc[i+1],+mc[i+2]),+mc[i+3]));}
return new x3dom.fields.MFRotation(vecs);};x3dom.fields.MFRotation.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i+=4){this.push(x3dom.fields.Quaternion.axisAngle(new x3dom.fields.SFVec3f(+mc[i+0],+mc[i+1],+mc[i+2]),+mc[i+3]));}};x3dom.fields.MFRotation.prototype.toGL=function(){var a=[];return a;};x3dom.fields.MFVec3f=function(vec3Array){if(arguments.length===0){}
else{var that=this;vec3Array.map(function(v){that.push(v);},this);}};x3dom.fields.MFVec3f.copy=function(vec3Array){var destination=new x3dom.fields.MFVec3f();vec3Array.map(function(v){destination.push(x3dom.fields.SFVec3f.copy(v));},this);return destination;};x3dom.fields.MFVec3f.prototype=x3dom.extend([]);x3dom.fields.MFVec3f.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc.length;i<n;i+=3){vecs.push(new x3dom.fields.SFVec3f(+mc[i+0],+mc[i+1],+mc[i+2]));}
return new x3dom.fields.MFVec3f(vecs);};x3dom.fields.MFVec3f.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i+=3){this.push(new x3dom.fields.SFVec3f(+mc[i+0],+mc[i+1],+mc[i+2]));}};x3dom.fields.MFVec3f.prototype.toGL=function(){var a=[];Array.map(this,function(c){a.push(c.x);a.push(c.y);a.push(c.z);});return a;};x3dom.fields.MFVec2f=function(vec2Array){if(arguments.length===0){}
else{var that=this;vec2Array.map(function(v){that.push(v);},this);}};x3dom.fields.MFVec2f.prototype=x3dom.extend([]);x3dom.fields.MFVec2f.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc.length;i<n;i+=2){vecs.push(new x3dom.fields.SFVec2f(+mc[i+0],+mc[i+1]));}
return new x3dom.fields.MFVec2f(vecs);};x3dom.fields.MFVec2f.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i+=2){this.push(new x3dom.fields.SFVec2f(+mc[i+0],+mc[i+1]));}};x3dom.fields.MFVec2f.prototype.toGL=function(){var a=[];Array.map(this,function(v){a.push(v.x);a.push(v.y);});return a;};x3dom.fields.MFInt32=function(array){if(arguments.length===0){}
else{var that=this;array.map(function(v){that.push(v);},this);}};x3dom.fields.MFInt32.prototype=x3dom.extend([]);x3dom.fields.MFInt32.parse=function(str){var mc=str.match(/([+\-]?\d+\s*){1},?\s*/g);var vals=[];for(var i=0,n=mc.length;i<n;++i){vals.push(parseInt(mc[i],10));}
return new x3dom.fields.MFInt32(vals);};x3dom.fields.MFInt32.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-]?\d+\s*){1},?\s*/g);for(var i=0,n=mc.length;i<n;++i){this.push(parseInt(mc[i],10));}};x3dom.fields.MFInt32.prototype.toGL=function(){var a=[];Array.map(this,function(v){a.push(v);});return a;};x3dom.fields.MFFloat=function(array){if(arguments.length===0){}
else{var that=this;array.map(function(v){that.push(v);},this);}};x3dom.fields.MFFloat.prototype=x3dom.extend([]);x3dom.fields.MFFloat.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vals=[];for(var i=0,n=mc.length;i<n;i++){vals.push(+mc[i]);}
return new x3dom.fields.MFFloat(vals);};x3dom.fields.MFFloat.prototype.setValueByStr=function(str){while(this.length){this.pop();}
var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc.length;i<n;i++){this.push(+mc[i]);}};x3dom.fields.MFFloat.prototype.toGL=function(){var a=[];Array.map(this,function(v){a.push(v);});return a;};x3dom.fields.MFString=function(strArray){if(arguments.length===0){}
else{var that=this;strArray.map(function(v){that.push(v);},this);}};x3dom.fields.MFString.parse=function(str){var arr=[];if(str.length&&str[0]=='"'){var m,re=/"((?:[^\\"]|\\\\|\\")*)"/g;while((m=re.exec(str))){var s=m[1].replace(/\\([\\"])/,"$1");if(s!==undefined){arr.push(s);}}}
else{arr.push(str);}
return new x3dom.fields.MFString(arr);};x3dom.fields.MFString.prototype=x3dom.extend([]);x3dom.fields.MFString.prototype.setValueByStr=function(str){var arr=this;while(arr.length){arr.pop();}
if(str.length&&str[0]=='"'){var m,re=/"((?:[^\\"]|\\\\|\\")*)"/g;while((m=re.exec(str))){var s=m[1].replace(/\\([\\"])/,"$1");if(s!==undefined){arr.push(s);}}}
else{arr.push(str);}
return this;};x3dom.fields.MFString.prototype.toString=function(){var str="";for(var i=0;i<this.length;i++){str=str+this[i]+" ";}
return str;};x3dom.fields.SFNode=function(type){this.type=type;this.node=null;};x3dom.fields.SFNode.prototype.hasLink=function(node){return(node?(this.node===node):this.node);};x3dom.fields.SFNode.prototype.addLink=function(node){this.node=node;return true;};x3dom.fields.SFNode.prototype.rmLink=function(node){if(this.node===node){this.node=null;return true;}
else{return false;}};x3dom.fields.MFNode=function(type){this.type=type;this.nodes=[];};x3dom.fields.MFNode.prototype.hasLink=function(node){if(node){for(var i=0,n=this.nodes.length;i<n;i++){if(this.nodes[i]===node){return true;}}}
else{return(this.length>0);}
return false;};x3dom.fields.MFNode.prototype.addLink=function(node){this.nodes.push(node);return true;};x3dom.fields.MFNode.prototype.rmLink=function(node){for(var i=0,n=this.nodes.length;i<n;i++){if(this.nodes[i]===node){this.nodes.splice(i,1);return true;}}
return false;};x3dom.fields.MFNode.prototype.length=function(){return this.nodes.length;};x3dom.fields.Line=function(pos,dir)
{if(arguments.length===0)
{this.pos=new x3dom.fields.SFVec3f(0,0,0);this.dir=new x3dom.fields.SFVec3f(0,0,1);}
else
{this.pos=new x3dom.fields.SFVec3f(pos.x,pos.y,pos.z);var n=dir.length();if(n){n=1.0/n;}
this.dir=new x3dom.fields.SFVec3f(dir.x*n,dir.y*n,dir.z*n);}
this.enter=0;this.exit=0;this.hitObject=null;this.hitPoint={};this.dist=Number.MAX_VALUE;};x3dom.fields.Line.prototype.toString=function(){var str='Line: ['+this.pos.toString()+'; '+this.dir.toString()+']';return str;};x3dom.fields.Line.prototype.intersect=function(low,high)
{var isect=0.0;var out=Number.MAX_VALUE;var r,te,tl;if(this.dir.x>x3dom.fields.Eps)
{r=1.0/this.dir.x;te=(low.x-this.pos.x)*r;tl=(high.x-this.pos.x)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}}
else if(this.dir.x<-x3dom.fields.Eps)
{r=1.0/this.dir.x;te=(high.x-this.pos.x)*r;tl=(low.x-this.pos.x)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}}
else if(this.pos.x<low.x||this.pos.x>high.x)
{return false;}
if(this.dir.y>x3dom.fields.Eps)
{r=1.0/this.dir.y;te=(low.y-this.pos.y)*r;tl=(high.y-this.pos.y)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}
if(isect-out>=x3dom.fields.Eps){return false;}}
else if(this.dir.y<-x3dom.fields.Eps)
{r=1.0/this.dir.y;te=(high.y-this.pos.y)*r;tl=(low.y-this.pos.y)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}
if(isect-out>=x3dom.fields.Eps){return false;}}
else if(this.pos.y<low.y||this.pos.y>high.y)
{return false;}
if(this.dir.z>x3dom.fields.Eps)
{r=1.0/this.dir.z;te=(low.z-this.pos.z)*r;tl=(high.z-this.pos.z)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}}
else if(this.dir.z<-x3dom.fields.Eps)
{r=1.0/this.dir.z;te=(high.z-this.pos.z)*r;tl=(low.z-this.pos.z)*r;if(tl<out){out=tl;}
if(te>isect){isect=te;}}
else if(this.pos.z<low.z||this.pos.z>high.z)
{return false;}
this.enter=isect;this.exit=out;return(isect-out<x3dom.fields.Eps);};x3dom.NodeNameSpace=function(name,document){this.name=name;this.doc=document;this.baseURL="";this.defMap={};this.parent=null;this.childSpaces=[];};x3dom.NodeNameSpace.prototype.addNode=function(node,name){this.defMap[name]=node;node._nameSpace=this;};x3dom.NodeNameSpace.prototype.removeNode=function(name){var node=this.defMap.name;delete this.defMap.name;if(node){node._nameSpace=null;}};x3dom.NodeNameSpace.prototype.getNamedNode=function(name){return this.defMap[name];};x3dom.NodeNameSpace.prototype.getNamedElement=function(name){var node=this.defMap[name];return(node?node._xmlNode:null);};x3dom.NodeNameSpace.prototype.addSpace=function(space){this.childSpaces.push(space);space.parent=this;};x3dom.NodeNameSpace.prototype.removeSpace=function(space){this.childSpaces.push(space);space.parent=null;};x3dom.NodeNameSpace.prototype.setBaseURL=function(url){var i=url.lastIndexOf("/");this.baseURL=(i>=0)?url.substr(0,i+1):"";x3dom.debug.logInfo("setBaseURL: "+this.baseURL);};x3dom.NodeNameSpace.prototype.getURL=function(url){if(url===undefined||!url.length){return"";}
else{return((url[0]==='/')||(url.indexOf(":")>=0))?url:(this.baseURL+url);}};x3dom.getElementAttribute=function(attrName)
{var attrib=this.__getAttribute(attrName);if((attrib!==undefined)||!this._x3domNode)
return attrib;else
return this._x3domNode._vf[attrName];};x3dom.setElementAttribute=function(attrName,newVal)
{this.__setAttribute(attrName,newVal);this._x3domNode.updateField(attrName,newVal);this._x3domNode._nameSpace.doc.needRender=true;};x3dom.NodeNameSpace.prototype.setupTree=function(domNode){var n,t;if(x3dom.isX3DElement(domNode)){if(domNode._x3domNode){x3dom.debug.logWarning('Tree is already initialized');return;}
if((domNode.tagName!==undefined)&&(!domNode.__addEventListener)&&(!domNode.__removeEventListener))
{domNode.__addEventListener=domNode.addEventListener;domNode.addEventListener=function(type,func,phase){if(!this._x3domNode._listeners[type]){this._x3domNode._listeners[type]=[];}
this._x3domNode._listeners[type].push(func);x3dom.debug.logInfo('addEventListener for '+this.tagName+".on"+type);this.__addEventListener(type,func,phase);};domNode.__removeEventListener=domNode.removeEventListener;domNode.removeEventListener=function(type,func,phase){var list=this._x3domNode._listeners[type];if(list){for(var it=0;it<list.length;it++){if(list[it]==func){list.splice(it,1);x3dom.debug.logInfo('removeEventListener for '+
this.tagName+".on"+type);}}}
this.__removeEventListener(type,func,phase);};}
if(domNode.hasAttribute('USE')){n=this.defMap[domNode.getAttribute('USE')];if(n===null){x3dom.debug.logWarning('Could not USE: '+domNode.getAttribute('USE'));}
return n;}
else{if(domNode.localName.toLowerCase()==='route'){var route=domNode;var fromNode=this.defMap[route.getAttribute('fromNode')];var toNode=this.defMap[route.getAttribute('toNode')];if(!(fromNode&&toNode)){x3dom.debug.logWarning("Broken route - can't find all DEFs for "+
route.getAttribute('fromNode')+" -> "+route.getAttribute('toNode'));return null;}
fromNode.setupRoute(route.getAttribute('fromField'),toNode,route.getAttribute('toField'));return null;}
var nodeType=x3dom.nodeTypesLC[domNode.localName.toLowerCase()];if(nodeType===undefined){x3dom.debug.logInfo("Unrecognised X3D element &lt;"+domNode.localName+"&gt;.");}
else{var ctx={doc:this.doc,xmlNode:domNode};n=new nodeType(ctx);n._nameSpace=this;if((x3dom.userAgentFeature.supportsDOMAttrModified===false)&&(domNode.tagName!==undefined))
{if(!domNode.__setAttribute)
{domNode.__setAttribute=domNode.setAttribute;domNode.setAttribute=x3dom.setElementAttribute;}
if(!domNode.__getAttribute)
{domNode.__getAttribute=domNode.getAttribute;domNode.getAttribute=x3dom.getElementAttribute;}}
if(domNode.hasAttribute('DEF')){n._DEF=domNode.getAttribute('DEF');this.defMap[n._DEF]=n;}
else{if(domNode.hasAttribute('id')){n._DEF=domNode.getAttribute('id');this.defMap[n._DEF]=n;}}
n._xmlNode=domNode;domNode._x3domNode=n;var that=this;Array.forEach(domNode.childNodes,function(childDomNode){var c=that.setupTree(childDomNode);if(c){n.addChild(c,childDomNode.getAttribute("containerField"));}});n.nodeChanged();return n;}}}
else if(domNode.localName){x3dom.debug.logInfo("Unrecognised X3D element &lt;"+domNode.localName+"&gt;.");n=null;}
return n;};x3dom.registerNodeType("X3DNode","Core",defineClass(null,function(ctx){this._DEF=null;this._nameSpace=null;this._vf={};this._cf={};this._fieldWatchers={};this._parentNodes=[];this._listeners={};this._childNodes=[];this.addField_SFNode('metadata',x3dom.nodeTypes.X3DMetadataObject);},{type:function(){return this.constructor;},typeName:function(){return this.constructor._typeName;},addChild:function(node,containerFieldName){if(node){var field=null;if(containerFieldName){field=this._cf[containerFieldName];}
else{for(var fieldName in this._cf){if(this._cf.hasOwnProperty(fieldName)){var testField=this._cf[fieldName];if(x3dom.isa(node,testField.type)){field=testField;break;}}}}
if(field&&field.addLink(node)){node._parentNodes.push(this);this._childNodes.push(node);node.parentAdded(this);return true;}}
return false;},removeChild:function(node){if(node){for(var fieldName in this._cf){if(this._cf.hasOwnProperty(fieldName)){var field=this._cf[fieldName];if(field.rmLink(node)){for(var i=0,n=node._parentNodes.length;i<n;i++){if(node._parentNodes[i]===this){node._parentNodes.splice(i,1);node.parentRemoved(this);}}
for(var j=0,m=this._childNodes.length;j<m;j++){if(this._childNodes[j]===node){this._childNodes.splice(j,1);return true;}}}}}}
return false;},parentAdded:function(parent){},parentRemoved:function(parent){for(var i=0,n=this._childNodes.length;i<n;i++){if(this._childNodes[i]){this._childNodes[i].parentRemoved(this);}}},getCurrentTransform:function(){if(this._parentNodes.length>=1){return this.transformMatrix(this._parentNodes[0].getCurrentTransform());}
else{return x3dom.fields.SFMatrix4f.identity();}},transformMatrix:function(transform){return transform;},getVolume:function(min,max,invalidate)
{var valid=false;for(var i=0,n=this._childNodes.length;i<n;i++)
{if(this._childNodes[i])
{var childMin=x3dom.fields.SFVec3f.MAX();var childMax=x3dom.fields.SFVec3f.MIN();valid=this._childNodes[i].getVolume(childMin,childMax,invalidate)||valid;if(valid)
{if(min.x>childMin.x){min.x=childMin.x;}
if(min.y>childMin.y){min.y=childMin.y;}
if(min.z>childMin.z){min.z=childMin.z;}
if(max.x<childMax.x){max.x=childMax.x;}
if(max.y<childMax.y){max.y=childMax.y;}
if(max.z<childMax.z){max.z=childMax.z;}}}}
return valid;},find:function(type){for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){if(this._childNodes[i].constructor==type){return this._childNodes[i];}
var c=this._childNodes[i].find(type);if(c){return c;}}}
return null;},findAll:function(type){var found=[];for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){if(this._childNodes[i].constructor==type){found.push(this._childNodes[i]);}
found=found.concat(this._childNodes[i].findAll(type));}}
return found;},findParentProperty:function(propertyName,checkDOMNode){var value=this[propertyName];if(!value&&checkDOMNode&&this._xmlNode){value=this._xmlNode[propertyName];}
if(!value){for(var i=0,n=this._parentNodes.length;i<n;i++){if((value=this._parentNodes[i].findParentProperty(propertyName,checkDOMNode))){break;}}}
return value;},findX3DDoc:function(){return this._nameSpace.doc;},collectDrawableObjects:function(transform,out){for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){var childTransform=this._childNodes[i].transformMatrix(transform);this._childNodes[i].collectDrawableObjects(childTransform,out);}}},doIntersect:function(line){var isect=false;for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){isect=this._childNodes[i].doIntersect(line)||isect;}}
return isect;},postMessage:function(field,msg){this._vf[field]=msg;var listeners=this._fieldWatchers[field];var thisp=this;if(listeners){Array.forEach(listeners,function(l){l.call(thisp,msg);});}},updateField:function(field,msg){var f=this._vf[field];if(f===undefined){f={};this._vf[field]=f;}
if(f!==null){try{this._vf[field].setValueByStr(msg);}
catch(exc1){try{switch((typeof(this._vf[field])).toString()){case"number":this._vf[field]=+msg;break;case"boolean":this._vf[field]=(msg.toLowerCase()==="true");break;case"string":this._vf[field]=msg;break;}}
catch(exc2){x3dom.debug.logError("updateField: setValueByStr() NYI for "+typeof(f));}}
this.fieldChanged(field);}},setupRoute:function(fromField,toNode,toField){var pos;var fieldName;var pre="set_",post="_changed";if(!this._vf[fromField]){pos=fromField.indexOf(pre);if(pos===0){fieldName=fromField.substr(pre.length,fromField.length-1);if(this._vf[fieldName]){fromField=fieldName;}}else{pos=fromField.indexOf(post);if(pos>0){fieldName=fromField.substr(0,fromField.length-post.length);if(this._vf[fieldName]){fromField=fieldName;}}}}
if(!toNode._vf[toField]){pos=toField.indexOf(pre);if(pos===0){fieldName=toField.substr(pre.length,toField.length-1);if(toNode._vf[fieldName]){toField=fieldName;}}
else{pos=toField.indexOf(post);if(pos>0){fieldName=toField.substr(0,toField.length-post.length);if(toNode._vf[fieldName]){toField=fieldName;}}}}
if(!this._fieldWatchers[fromField]){this._fieldWatchers[fromField]=[];}
this._fieldWatchers[fromField].push(function(msg){toNode.postMessage(toField,msg);});if(!toNode._fieldWatchers[toField]){toNode._fieldWatchers[toField]=[];}
toNode._fieldWatchers[toField].push(function(msg){toNode._vf[toField]=msg;toNode.fieldChanged(toField);});},fieldChanged:function(fieldName){},nodeChanged:function(){},callEvtHandler:function(eventType,event){var node=this;try{var attrib=node._xmlNode[eventType];event.target=node._xmlNode;if(typeof(attrib)==="function"){attrib.call(node._xmlNode,event);}
else{var funcStr=node._xmlNode.getAttribute(eventType);var func=new Function('event',funcStr);func.call(node._xmlNode,event);}
var list=node._listeners[event.type];if(list){for(var it=0;it<list.length;it++){list[it].call(node._xmlNode,event);}}}
catch(ex){x3dom.debug.logException(ex);}
return event.cancelBubble;},initSetter:function(xmlNode,name){if(xmlNode.__defineSetter__!=undefined){xmlNode.__defineSetter__(name,function(value){xmlNode.setAttribute(name,value);});}else{Object.defineProperty(xmlNode,name,{set:function(value){xmlNode.setAttribute(name,value);}});}},addField_SFInt32:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode.hasAttribute(name)?parseInt(ctx.xmlNode.getAttribute(name),10):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFFloat:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?+ctx.xmlNode.getAttribute(name):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFDouble:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?+ctx.xmlNode.getAttribute(name):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFTime:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?+ctx.xmlNode.getAttribute(name):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFBool:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?ctx.xmlNode.getAttribute(name).toLowerCase()==="true":n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFString:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?ctx.xmlNode.getAttribute(name):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFColor:function(ctx,name,r,g,b){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFColor.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFColor(r,g,b);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFColorRGBA:function(ctx,name,r,g,b,a){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFColorRGBA.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFColorRGBA(r,g,b,a);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFVec2f:function(ctx,name,x,y){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFVec2f.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFVec2f(x,y);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFVec3f:function(ctx,name,x,y,z){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFVec3f.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFVec3f(x,y,z);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFVec3d:function(ctx,name,x,y,z){this.addField_SFVec3f(ctx,name,x,y,z);},addField_SFRotation:function(ctx,name,x,y,z,a){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.Quaternion.parseAxisAngle(ctx.xmlNode.getAttribute(name)):x3dom.fields.Quaternion.axisAngle(new x3dom.fields.SFVec3f(x,y,z),a);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFMatrix4f:function(ctx,name,_00,_01,_02,_03,_10,_11,_12,_13,_20,_21,_22,_23,_30,_31,_32,_33){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFMatrix4f.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFMatrix4f(_00,_01,_02,_03,_10,_11,_12,_13,_20,_21,_22,_23,_30,_31,_32,_33);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFImage:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.SFImage.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.SFImage(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFString:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFString.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFString(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFInt32:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFInt32.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFInt32(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFFloat:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFFloat.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFFloat(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFDouble:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFFloat.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFFloat(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFColor:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFColor.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFColor(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFColorRGBA:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFColorRGBA.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFColorRGBA(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFVec2f:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFVec2f.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFVec2f(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFVec3f:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFVec3f.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFVec3f(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_MFVec3d:function(ctx,name,def){this.addField_MFVec3f(ctx,name,def);},addField_MFRotation:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFRotation.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFRotation(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}},addField_SFNode:function(name,type){this._cf[name]=new x3dom.fields.SFNode(type);},addField_MFNode:function(name,type){this._cf[name]=new x3dom.fields.MFNode(type);}}));x3dom.registerNodeType("X3DMetadataObject","Core",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DMetadataObject.superClass.call(this,ctx);this.addField_SFString(ctx,'name',"");this.addField_SFString(ctx,'reference',"");}));x3dom.registerNodeType("MetadataDouble","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataDouble.superClass.call(this,ctx);this.addField_MFDouble(ctx,'value',[]);}));x3dom.registerNodeType("MetadataFloat","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataFloat.superClass.call(this,ctx);this.addField_MFFloat(ctx,'value',[]);}));x3dom.registerNodeType("MetadataInteger","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataInteger.superClass.call(this,ctx);this.addField_MFInt32(ctx,'value',[]);}));x3dom.registerNodeType("MetadataSet","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataSet.superClass.call(this,ctx);this.addField_MFNode('value',x3dom.nodeTypes.X3DMetadataObject);}));x3dom.registerNodeType("MetadataString","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataString.superClass.call(this,ctx);this.addField_MFString(ctx,'value',[]);}));x3dom.registerNodeType("Field","Core",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.Field.superClass.call(this,ctx);this.addField_SFString(ctx,'name',"");this.addField_SFString(ctx,'type',"");this.addField_SFString(ctx,'value',"");},{fieldChanged:function(fieldName){var that=this;if(fieldName==='value'){Array.forEach(this._parentNodes,function(node){node.fieldChanged(that._vf.name);});}}}));x3dom.registerNodeType("X3DChildNode","Core",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DChildNode.superClass.call(this,ctx);}));x3dom.registerNodeType("X3DBindableNode","Core",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DBindableNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'set_bind',false);this.addField_SFString(ctx,'description',"");this.addField_SFBool(ctx,'isActive',false);this._autoGen=(ctx.autoGen?true:false);if(ctx&&ctx.doc._bindableBag){this._stack=ctx.doc._bindableBag.addBindable(this);}
else{this._stack=null;x3dom.debug.logError('Could not find bindableBag for registration '+this.typeName());}},{initDefault:function(){},bind:function(value){if(this._stack){if(value){this._stack.push(this);}
else{this._stack.pop(this);}}
else{x3dom.debug.logError('No BindStack in Bindable\n');}},activate:function(prev){x3dom.debug.logInfo('activate Bindable '+this._DEF);this.postMessage('isActive',true);},deactivate:function(prev){x3dom.debug.logInfo('deactivate Bindable '+this._DEF);this.postMessage('isActive',false);},fieldChanged:function(fieldName){if(fieldName==="set_bind"){this.bind(this._vf.set_bind);}},nodeChanged:function(){}}));x3dom.registerNodeType("WorldInfo","Core",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.WorldInfo.superClass.call(this,ctx);this.addField_MFString(ctx,'info',[]);this.addField_SFString(ctx,'title',"");x3dom.debug.logInfo(this._vf.info);x3dom.debug.logInfo(this._vf.title);},{}));x3dom.registerNodeType("X3DSensorNode","Core",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DSensorNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Param","Core",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.Param.superClass.call(this,ctx);},{nodeChanged:function(){x3dom.debug.logWarning('DEPRECATED 1.3: Param element needs to be child of X3D element [<a href="http://x3dom.org/docs/latest/configuration.html">DOCS</a>]');}}));x3dom.registerNodeType("X3DGroupingNode","Grouping",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DGroupingNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'render',true);this.addField_MFNode('children',x3dom.nodeTypes.X3DChildNode);},{collectDrawableObjects:function(transform,out)
{if(!this._vf.render){return;}
for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){var childTransform=this._childNodes[i].transformMatrix(transform);this._childNodes[i].collectDrawableObjects(childTransform,out);}}}}));x3dom.registerNodeType("Switch","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Switch.superClass.call(this,ctx);this.addField_SFInt32(ctx,'whichChoice',-1);},{getVolume:function(min,max,invalidate)
{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return false;}
if(this._childNodes[this._vf.whichChoice]){return this._childNodes[this._vf.whichChoice].getVolume(min,max,invalidate);}
return false;},find:function(type)
{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return null;}
if(this._childNodes[this._vf.whichChoice]){if(this._childNodes[this._vf.whichChoice].constructor==type){return this._childNodes[this._vf.whichChoice];}
var c=this._childNodes[this._vf.whichChoice].find(type);if(c){return c;}}
return null;},findAll:function(type)
{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return[];}
var found=[];if(this._childNodes[this._vf.whichChoice]){if(this._childNodes[this._vf.whichChoice].constructor==type){found.push(this._childNodes[this._vf.whichChoice]);}
found=found.concat(this._childNodes[this._vf.whichChoice].findAll(type));}
return found;},collectDrawableObjects:function(transform,out)
{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return;}
if(this._childNodes[this._vf.whichChoice]){var childTransform=this._childNodes[this._vf.whichChoice].transformMatrix(transform);this._childNodes[this._vf.whichChoice].collectDrawableObjects(childTransform,out);}},doIntersect:function(line)
{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return false;}
if(this._childNodes[this._vf.whichChoice]){return this._childNodes[this._vf.whichChoice].doIntersect(line);}
return false;}}));x3dom.registerNodeType("X3DTransformNode","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.X3DTransformNode.superClass.call(this,ctx);ctx.doc._nodeBag.trans.push(this);this._trafo=null;},{tick:function(t)
{if(this._xmlNode&&(this._xmlNode['transform']||this._xmlNode.hasAttribute('transform')||this._listeners['transform']))
{var transMatrix=this.getCurrentTransform();var event={target:{},type:'transform',worldX:transMatrix._03,worldY:transMatrix._13,worldZ:transMatrix._23,stopPropagation:function(){this.cancelBubble=true;}};var attrib=this._xmlNode[event.type];if(typeof(attrib)==="function")
attrib.call(this._xmlNode,event);else
{var funcStr=this._xmlNode.getAttribute(event.type);var func=new Function('event',funcStr);func.call(this._xmlNode,event);}
var list=this._listeners[event.type];if(list)
for(var it=0;it<list.length;it++)
list[it].call(this._xmlNode,event);}
var trans=x3dom.getStyle(this._xmlNode,"-webkit-transform");if(trans&&(trans!='none')){this._trafo.setValueByStr(trans);return true;}
return false;},transformMatrix:function(transform){return transform.mult(this._trafo);},getVolume:function(min,max,invalidate)
{var nMin=x3dom.fields.SFVec3f.MAX();var nMax=x3dom.fields.SFVec3f.MIN();var valid=false;for(var i=0,n=this._childNodes.length;i<n;i++)
{if(this._childNodes[i])
{var childMin=x3dom.fields.SFVec3f.MAX();var childMax=x3dom.fields.SFVec3f.MIN();valid=this._childNodes[i].getVolume(childMin,childMax,invalidate)||valid;if(valid)
{if(nMin.x>childMin.x){nMin.x=childMin.x;}
if(nMin.y>childMin.y){nMin.y=childMin.y;}
if(nMin.z>childMin.z){nMin.z=childMin.z;}
if(nMax.x<childMax.x){nMax.x=childMax.x;}
if(nMax.y<childMax.y){nMax.y=childMax.y;}
if(nMax.z<childMax.z){nMax.z=childMax.z;}}}}
if(valid)
{nMin=this._trafo.multMatrixPnt(nMin);nMax=this._trafo.multMatrixPnt(nMax);min.x=nMin.x<nMax.x?nMin.x:nMax.x;min.y=nMin.y<nMax.y?nMin.y:nMax.y;min.z=nMin.z<nMax.z?nMin.z:nMax.z;max.x=nMax.x>nMin.x?nMax.x:nMin.x;max.y=nMax.y>nMin.y?nMax.y:nMin.y;max.z=nMax.z>nMin.z?nMax.z:nMin.z;}
return valid;},doIntersect:function(line)
{var isect=false;var mat=this._trafo.inverse();var tmpPos=new x3dom.fields.SFVec3f(line.pos.x,line.pos.y,line.pos.z);var tmpDir=new x3dom.fields.SFVec3f(line.dir.x,line.dir.y,line.dir.z);line.pos=mat.multMatrixPnt(line.pos);line.dir=mat.multMatrixVec(line.dir);if(line.hitObject){line.dist*=line.dir.length();}
for(var i=0;i<this._childNodes.length;i++)
{if(this._childNodes[i]){isect=this._childNodes[i].doIntersect(line)||isect;}}
line.pos.setValues(tmpPos);line.dir.setValues(tmpDir);if(isect){line.hitPoint=this._trafo.multMatrixPnt(line.hitPoint);line.dist*=line.dir.length();}
return isect;},parentRemoved:function(parent)
{var i;var n;if(this._parentNodes.length===0){var doc=this.findX3DDoc();for(i=0,n=doc._nodeBag.trans.length;i<n;i++){if(doc._nodeBag.trans[i]===this){doc._nodeBag.trans.splice(i,1);}}}
for(i=0,n=this._childNodes.length;i<n;i++){if(this._childNodes[i]){this._childNodes[i].parentRemoved(this);}}}}));x3dom.registerNodeType("Transform","Grouping",defineClass(x3dom.nodeTypes.X3DTransformNode,function(ctx){x3dom.nodeTypes.Transform.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'center',0,0,0);this.addField_SFVec3f(ctx,'translation',0,0,0);this.addField_SFRotation(ctx,'rotation',0,0,1,0);this.addField_SFVec3f(ctx,'scale',1,1,1);this.addField_SFRotation(ctx,'scaleOrientation',0,0,1,0);this._trafo=x3dom.fields.SFMatrix4f.translation(this._vf.translation.add(this._vf.center)).mult(this._vf.rotation.toMatrix()).mult(this._vf.scaleOrientation.toMatrix()).mult(x3dom.fields.SFMatrix4f.scale(this._vf.scale)).mult(this._vf.scaleOrientation.toMatrix().inverse()).mult(x3dom.fields.SFMatrix4f.translation(this._vf.center.negate()));},{fieldChanged:function(fieldName){this._trafo=x3dom.fields.SFMatrix4f.translation(this._vf.translation.add(this._vf.center)).mult(this._vf.rotation.toMatrix()).mult(this._vf.scaleOrientation.toMatrix()).mult(x3dom.fields.SFMatrix4f.scale(this._vf.scale)).mult(this._vf.scaleOrientation.toMatrix().inverse()).mult(x3dom.fields.SFMatrix4f.translation(this._vf.center.negate()));}}));x3dom.registerNodeType("MatrixTransform","Grouping",defineClass(x3dom.nodeTypes.X3DTransformNode,function(ctx){x3dom.nodeTypes.MatrixTransform.superClass.call(this,ctx);this.addField_SFMatrix4f(ctx,'matrix',1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);this._trafo=this._vf.matrix;},{}));x3dom.registerNodeType("Group","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Group.superClass.call(this,ctx);},{}));x3dom.registerNodeType("StaticGroup","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.StaticGroup.superClass.call(this,ctx);x3dom.debug.logWarning("StaticGroup NYI");}));x3dom.registerNodeType("Scene","Core",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Scene.superClass.call(this,ctx);this.addField_SFString(ctx,'pickMode',"idBuf");},{}));x3dom.BindableStack=function(doc,type,defaultType,getter){this._doc=doc;this._type=type;this._defaultType=defaultType;this._defaultRoot=0;this._getter=getter;this._bindBag=[];this._bindStack=[];};x3dom.BindableStack.prototype.top=function(){return((this._bindStack.length>=0)?this._bindStack[this._bindStack.length-1]:null);};x3dom.BindableStack.prototype.push=function(bindable){var top=this.top();if(top===bindable){return;}
if(top){top.deactivate();}
this._bindStack.push(bindable);bindable.activate(top);};x3dom.BindableStack.prototype.replaceTop=function(bindable){var top=this.top();if(top===bindable){return;}
if(top){top.deactivate();this._bindStack[this._bindStack.length-1]=bindable;bindable.activate(top);}};x3dom.BindableStack.prototype.pop=function(bindable){var top;if(bindable){top=this.top();if(bindable!==top){return null;}}
top=this._bindStack.pop();if(top){top.deactivate();}
return top;};x3dom.BindableStack.prototype.switchTo=function(target){var last=this.getActive();var n=this._bindBag.length;var toBind=0;var i=0,lastIndex=-1;if(n<=1){return;}
switch(target)
{case'first':toBind=this._bindBag[0];break;case'last':toBind=this._bindBag[n-1];break;default:for(i=0;i<n;i++){if(this._bindBag[i]==last){lastIndex=i;break;}}
if(lastIndex>=0){i=lastIndex;while(!toBind){if(target=='next'){i=(i<(n-1))?(i+1):0;}else{i=(i>0)?(i-1):(n-1);}
if(i==lastIndex){break;}
if(this._bindBag[i]._vf.description.length>=0){toBind=this._bindBag[i];}}}
break;}
if(toBind){this.replaceTop(toBind);}else{x3dom.debug.logWarning('Cannot switch bindable; no other bindable with description found.');}};x3dom.BindableStack.prototype.getActive=function(){if(this._bindStack.length===0){if(this._bindBag.length===0){x3dom.debug.logInfo('create new '+this._defaultType._typeName+' for '+this._type._typeName+'-stack');var obj=new this._defaultType({doc:this._doc,autoGen:true});if(obj){if(this._defaultRoot){this._defaultRoot.addChild(obj);obj._nameSpace=this._defaultRoot._nameSpace;}
else{x3dom.debug.logError('stack without defaultRoot');}
obj.initDefault();this._bindBag.push(obj);}}
else{x3dom.debug.logInfo('activate first '+this._type._typeName+' for '+this._type._typeName+'-stack');}
this._bindStack.push(this._bindBag[0]);this._bindBag[0].activate();}
return this._bindStack[this._bindStack.length-1];};x3dom.BindableBag=function(doc){this._stacks=[];this.addType("X3DViewpointNode","Viewpoint","getViewpoint",doc);this.addType("X3DNavigationInfoNode","NavigationInfo","getNavigationInfo",doc);this.addType("X3DBackgroundNode","Background","getBackground",doc);this.addType("X3DFogNode","Fog","getFog",doc);};x3dom.BindableBag.prototype.addType=function(typeName,defaultTypeName,getter,doc){var type=x3dom.nodeTypes[typeName];var defaultType=x3dom.nodeTypes[defaultTypeName];var stack;if(type&&defaultType){stack=new x3dom.BindableStack(doc,type,defaultType,getter);this._stacks.push(stack);}
else{x3dom.debug.logWarning('Invalid Bindable type/defaultType:'+typeName+'/'+defaultType);}};x3dom.BindableBag.prototype.setRefNode=function(node){Array.forEach(this._stacks,function(stack){stack._defaultRoot=node;node[stack._getter]=function(){return stack.getActive();};});};x3dom.BindableBag.prototype.addBindable=function(node){for(var i=0,n=this._stacks.length;i<n;i++){if(x3dom.isa(node,this._stacks[i]._type)){x3dom.debug.logInfo('register bindable '+node.typeName());this._stacks[i]._bindBag.push(node);return this._stacks[i];}}
x3dom.debug.logError(node.typeName()+' is not a valid bindable');return null;};x3dom.registerNodeType("X3DGeometryNode","Rendering",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DGeometryNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'solid',true);this.addField_SFBool(ctx,'ccw',true);this._mesh=new x3dom.Mesh(this);this._pickable=true;},{getVolume:function(min,max,invalidate){this._mesh.getBBox(min,max,invalidate);return true;},getCenter:function(){return this._mesh.getCenter();},doIntersect:function(line){if(this._pickable){return this._mesh.doIntersect(line);}
else{return false;}},getColorTexture:function(){return null;},getColorTextureURL:function(){return null;}}));x3dom.registerNodeType("Mesh","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Mesh.superClass.call(this,ctx);this.addField_SFString(ctx,'primType',"triangle");this.addField_MFInt32(ctx,'index',[]);this.addField_MFNode('vertexAttributes',x3dom.nodeTypes.X3DVertexAttributeNode);},{nodeChanged:function()
{var time0=new Date().getTime();var i,n=this._cf.vertexAttributes.nodes.length;for(i=0;i<n;i++)
{var name=this._cf.vertexAttributes.nodes[i]._vf.name;switch(name.toLowerCase())
{case"position":this._mesh._positions[0]=this._cf.vertexAttributes.nodes[i]._vf.value.toGL();break;case"normal":this._mesh._normals[0]=this._cf.vertexAttributes.nodes[i]._vf.value.toGL();break;case"texcoord":this._mesh._texCoords[0]=this._cf.vertexAttributes.nodes[i]._vf.value.toGL();break;case"color":this._mesh._colors[0]=this._cf.vertexAttributes.nodes[i]._vf.value.toGL();break;default:this._mesh._dynamicFields[name]={};this._mesh._dynamicFields[name].numComponents=this._cf.vertexAttributes.nodes[i]._vf.numComponents;this._mesh._dynamicFields[name].value=this._cf.vertexAttributes.nodes[i]._vf.value.toGL();break;}}
this._mesh._indices[0]=this._vf.index.toGL();this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;var time1=new Date().getTime()-time0;x3dom.debug.logWarning("Mesh load time: "+time1+" ms");}}));x3dom.registerNodeType("PointSet","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.PointSet.superClass.call(this,ctx);this.addField_SFNode('coord',x3dom.nodeTypes.Coordinate);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this._pickable=false;},{nodeChanged:function()
{var time0=new Date().getTime();var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);var positions=coordNode._vf.point;var numColComponents=3;var colorNode=this._cf.color.node;var colors=new x3dom.fields.MFColor();if(colorNode){colors=colorNode._vf.color;x3dom.debug.assert(positions.length==colors.length);if(x3dom.isa(colorNode,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
else{for(var i=0,n=positions.length;i<n;i++){colors.push(1.0);}}
this._mesh._numColComponents=numColComponents;this._mesh._indices[0]=[];this._mesh._positions[0]=positions.toGL();this._mesh._colors[0]=colors.toGL();this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._lit=false;this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
{var pnts;var i,n;if(fieldName=="coord")
{pnts=this._cf.coord.node._vf.point;n=pnts.length;this._mesh._positions[0]=[];for(i=0;i<n;i++)
{this._mesh._positions[0].push(pnts[i].x);this._mesh._positions[0].push(pnts[i].y);this._mesh._positions[0].push(pnts[i].z);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}
else if(fieldName=="color")
{pnts=this._cf.color.node._vf.color;n=pnts.length;this._mesh._colors[0]=[];for(i=0;i<n;i++)
{this._mesh._colors[0].push(pnts[i].r);this._mesh._colors[0].push(pnts[i].g);this._mesh._colors[0].push(pnts[i].b);}
Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}}}));x3dom.registerNodeType("X3DComposedGeometryNode","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.X3DComposedGeometryNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'colorPerVertex',true);this.addField_SFBool(ctx,'normalPerVertex',true);this.addField_MFNode('attrib',x3dom.nodeTypes.X3DVertexAttributeNode);this.addField_SFNode('coord',x3dom.nodeTypes.X3DCoordinateNode);this.addField_SFNode('normal',x3dom.nodeTypes.Normal);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this.addField_SFNode('texCoord',x3dom.nodeTypes.X3DTextureCoordinateNode);},{handleAttribs:function()
{var i,n=this._cf.attrib.nodes.length;for(i=0;i<n;i++)
{var name=this._cf.attrib.nodes[i]._vf.name;switch(name.toLowerCase())
{case"position":this._mesh._positions[0]=this._cf.attrib.nodes[i]._vf.value.toGL();break;case"normal":this._mesh._normals[0]=this._cf.attrib.nodes[i]._vf.value.toGL();break;case"texcoord":this._mesh._texCoords[0]=this._cf.attrib.nodes[i]._vf.value.toGL();break;case"color":this._mesh._colors[0]=this._cf.attrib.nodes[i]._vf.value.toGL();break;default:this._mesh._dynamicFields[name]={};this._mesh._dynamicFields[name].numComponents=this._cf.attrib.nodes[i]._vf.numComponents;this._mesh._dynamicFields[name].value=this._cf.attrib.nodes[i]._vf.value.toGL();break;}}}}));x3dom.registerNodeType("IndexedLineSet","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.IndexedLineSet.superClass.call(this,ctx);this.addField_SFBool(ctx,'colorPerVertex',true);this.addField_MFNode('attrib',x3dom.nodeTypes.X3DVertexAttributeNode);this.addField_SFNode('coord',x3dom.nodeTypes.X3DCoordinateNode);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this.addField_MFInt32(ctx,'coordIndex',[]);this.addField_MFInt32(ctx,'colorIndex',[]);this._pickable=false;},{nodeChanged:function()
{var time0=new Date().getTime();var indexes=this._vf.coordIndex;var colorInd=this._vf.colorIndex;var hasColor=false,hasColorInd=false;var colPerVert=this._vf.colorPerVertex;if(colorInd.length>0)
{hasColorInd=true;}
var positions,colors;var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);positions=coordNode.getPoints();var numColComponents=3;var colorNode=this._cf.color.node;if(colorNode)
{hasColor=true;colors=colorNode._vf.color;if(x3dom.isa(colorNode,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
else{hasColor=false;}
this._mesh._indices[0]=[];this._mesh._positions[0]=[];this._mesh._colors[0]=[];var i,t,cnt,lineCnt;var p0,p1,c0,c1;if((hasColor&&hasColorInd))
{t=0;cnt=0;lineCnt=0;for(i=0;i<indexes.length;++i)
{if(indexes[i]===-1){t=0;continue;}
if(hasColorInd){x3dom.debug.assert(colorInd[i]!=-1);}
switch(t)
{case 0:p0=+indexes[i];if(hasColorInd&&colPerVert){c0=+colorInd[i];}
else{c0=p0;}
t=1;break;case 1:p1=+indexes[i];if(hasColorInd&&colPerVert){c1=+colorInd[i];}
else if(hasColorInd&&!colPerVert){c1=+colorInd[lineCnt];}
else{c1=p1;}
this._mesh._indices[0].push(cnt++,cnt++);this._mesh._positions[0].push(positions[p0].x);this._mesh._positions[0].push(positions[p0].y);this._mesh._positions[0].push(positions[p0].z);this._mesh._positions[0].push(positions[p1].x);this._mesh._positions[0].push(positions[p1].y);this._mesh._positions[0].push(positions[p1].z);if(hasColor){if(!colPerVert){c0=c1;}
this._mesh._colors[0].push(colors[c0].r);this._mesh._colors[0].push(colors[c0].g);this._mesh._colors[0].push(colors[c0].b);this._mesh._colors[0].push(colors[c1].r);this._mesh._colors[0].push(colors[c1].g);this._mesh._colors[0].push(colors[c1].b);}
t=2;lineCnt++;break;case 3:p0=p1;c0=c1;p1=+indexes[i];if(hasColorInd&&colPerVert){c1=+colorInd[i];}
else if(hasColorInd&&!colPerVert){c1=+colorInd[lineCnt];}
else{c1=p1;}
this._mesh._indices[0].push(cnt++,cnt++);this._mesh._positions[0].push(positions[p0].x);this._mesh._positions[0].push(positions[p0].y);this._mesh._positions[0].push(positions[p0].z);this._mesh._positions[0].push(positions[p1].x);this._mesh._positions[0].push(positions[p1].y);this._mesh._positions[0].push(positions[p1].z);if(hasColor){if(!colPerVert){c0=c1;}
this._mesh._colors[0].push(colors[c0].r);this._mesh._colors[0].push(colors[c0].g);this._mesh._colors[0].push(colors[c0].b);this._mesh._colors[0].push(colors[c1].r);this._mesh._colors[0].push(colors[c1].g);this._mesh._colors[0].push(colors[c1].b);}
lineCnt++;break;default:}}}
else
{t=0;for(i=0;i<indexes.length;++i)
{if(indexes[i]===-1){t=0;continue;}
switch(t){case 0:p0=+indexes[i];t=1;break;case 1:p1=+indexes[i];t=2;this._mesh._indices[0].push(p0,p1);break;case 2:p0=p1;p1=+indexes[i];this._mesh._indices[0].push(p0,p1);break;}}
this._mesh._positions[0]=positions.toGL();if(hasColor){this._mesh._colors[0]=colors.toGL();this._mesh._numColComponents=numColComponents;}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
{var pnts;var i,n;if(fieldName=="coord")
{pnts=this._cf.coord.node._vf.point;n=pnts.length;this._mesh._positions[0]=[];for(i=0;i<n;i++)
{this._mesh._positions[0].push(pnts[i].x);this._mesh._positions[0].push(pnts[i].y);this._mesh._positions[0].push(pnts[i].z);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}
else if(fieldName=="color")
{pnts=this._cf.color.node._vf.color;n=pnts.length;this._mesh._colors[0]=[];for(i=0;i<n;i++)
{this._mesh._colors[0].push(pnts[i].r);this._mesh._colors[0].push(pnts[i].g);this._mesh._colors[0].push(pnts[i].b);}
Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}}}));x3dom.registerNodeType("IndexedTriangleSet","Rendering",defineClass(x3dom.nodeTypes.X3DComposedGeometryNode,function(ctx){x3dom.nodeTypes.IndexedTriangleSet.superClass.call(this,ctx);this.addField_MFInt32(ctx,'index',[]);},{nodeChanged:function()
{var time0=new Date().getTime();this.handleAttribs();var normPerVert=this._vf.normalPerVertex;var indexes=this._vf.index;var hasNormal=false,hasTexCoord=false,hasColor=false;var positions,normals,texCoords,colors;var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);positions=coordNode._vf.point;var normalNode=this._cf.normal.node;if(normalNode){hasNormal=true;normals=normalNode._vf.vector;}
else{hasNormal=false;}
var texMode="",numTexComponents=2;var texCoordNode=this._cf.texCoord.node;if(texCoordNode){if(texCoordNode._vf.point){hasTexCoord=true;texCoords=texCoordNode._vf.point;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.TextureCoordinate3D)){numTexComponents=3;}}
else if(texCoordNode._vf.mode){texMode=texCoordNode._vf.mode;}}
else{hasTexCoord=false;}
var numColComponents=3;var colorNode=this._cf.color.node;if(colorNode){hasColor=true;colors=colorNode._vf.color;if(x3dom.isa(colorNode,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
else{hasColor=false;}
this._mesh._indices[0]=[];this._mesh._positions[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._colors[0]=[];var i,t,cnt,faceCnt,posMax;var p0,p1,p2,n0,n1,n2,t0,t1,t2,c0,c1,c2;while(positions.length%3>0){positions.push(positions.length-1);}
posMax=positions.length;if((positions.length>65535))
{t=0;cnt=0;faceCnt=0;this._mesh._multiIndIndices=[];this._mesh._posSize=positions.length;for(i=0;i<indexes.length;++i)
{if((i>0)&&(i%3===0)){t=0;faceCnt++;}
switch(t)
{case 0:p0=+indexes[i];n0=p0;t0=p0;c0=p0;t=1;break;case 1:p1=+indexes[i];n1=p1;t1=p1;c1=p1;t=2;break;case 2:p2=+indexes[i];n2=p2;t2=p2;c2=p2;t=3;this._mesh._indices[0].push(cnt++,cnt++,cnt++);this._mesh._positions[0].push(positions[p0].x);this._mesh._positions[0].push(positions[p0].y);this._mesh._positions[0].push(positions[p0].z);this._mesh._positions[0].push(positions[p1].x);this._mesh._positions[0].push(positions[p1].y);this._mesh._positions[0].push(positions[p1].z);this._mesh._positions[0].push(positions[p2].x);this._mesh._positions[0].push(positions[p2].y);this._mesh._positions[0].push(positions[p2].z);if(hasNormal){this._mesh._normals[0].push(normals[n0].x);this._mesh._normals[0].push(normals[n0].y);this._mesh._normals[0].push(normals[n0].z);this._mesh._normals[0].push(normals[n1].x);this._mesh._normals[0].push(normals[n1].y);this._mesh._normals[0].push(normals[n1].z);this._mesh._normals[0].push(normals[n2].x);this._mesh._normals[0].push(normals[n2].y);this._mesh._normals[0].push(normals[n2].z);}
else{this._mesh._multiIndIndices.push(p0,p1,p2);}
if(hasColor){this._mesh._colors[0].push(colors[c0].r);this._mesh._colors[0].push(colors[c0].g);this._mesh._colors[0].push(colors[c0].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c0].a);}
this._mesh._colors[0].push(colors[c1].r);this._mesh._colors[0].push(colors[c1].g);this._mesh._colors[0].push(colors[c1].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c1].a);}
this._mesh._colors[0].push(colors[c2].r);this._mesh._colors[0].push(colors[c2].g);this._mesh._colors[0].push(colors[c2].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c2].a);}}
if(hasTexCoord){this._mesh._texCoords[0].push(texCoords[t0].x);this._mesh._texCoords[0].push(texCoords[t0].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t0].z);}
this._mesh._texCoords[0].push(texCoords[t1].x);this._mesh._texCoords[0].push(texCoords[t1].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t1].z);}
this._mesh._texCoords[0].push(texCoords[t2].x);this._mesh._texCoords[0].push(texCoords[t2].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t2].z);}}
break;default:}}
if(!hasNormal){this._mesh.calcNormals(Math.PI);}
if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
this._mesh.splitMesh();}
else
{this._mesh._indices[0]=indexes.toGL();this._mesh._positions[0]=positions.toGL();if(hasNormal){this._mesh._normals[0]=normals.toGL();}
else{this._mesh.calcNormals(Math.PI);}
if(hasTexCoord){this._mesh._texCoords[0]=texCoords.toGL();this._mesh._numTexComponents=numTexComponents;}
else{this._mesh.calcTexCoords(texMode);}
if(hasColor){this._mesh._colors[0]=colors.toGL();this._mesh._numColComponents=numColComponents;}}
this._mesh._invalidate=true;this._mesh._numFaces=0;this._mesh._numCoords=0;for(i=0;i<this._mesh._indices.length;i++){this._mesh._numFaces+=this._mesh._indices[i].length/3;this._mesh._numCoords+=this._mesh._positions[i].length/3;}
var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
{var pnts;var i,n;if(fieldName=="coord")
{pnts=this._cf.coord.node._vf.point;n=pnts.length;this._mesh._positions[0]=[];for(i=0;i<n;i++)
{this._mesh._positions[0].push(pnts[i].x);this._mesh._positions[0].push(pnts[i].y);this._mesh._positions[0].push(pnts[i].z);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}
else if(fieldName=="color")
{pnts=this._cf.color.node._vf.color;n=pnts.length;this._mesh._colors[0]=[];for(i=0;i<n;i++)
{this._mesh._colors[0].push(pnts[i].r);this._mesh._colors[0].push(pnts[i].g);this._mesh._colors[0].push(pnts[i].b);}
Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}}}));x3dom.registerNodeType("IndexedTriangleStripSet","Rendering",defineClass(x3dom.nodeTypes.X3DComposedGeometryNode,function(ctx){x3dom.nodeTypes.IndexedTriangleStripSet.superClass.call(this,ctx);this.addField_MFInt32(ctx,'index',[]);},{nodeChanged:function(){x3dom.debug.logError("========== IndexedTriangleStripSet is not implemented ==========")}}));x3dom.registerNodeType("X3DGeometricPropertyNode","Rendering",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DGeometricPropertyNode.superClass.call(this,ctx);}));x3dom.registerNodeType("X3DCoordinateNode","Rendering",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.X3DCoordinateNode.superClass.call(this,ctx);},{fieldChanged:function(fieldName){Array.forEach(this._parentNodes,function(node){node.fieldChanged("coord");});},parentAdded:function(parent){if(parent._mesh&&parent._cf.coord.node!==this){parent.fieldChanged("coord");}}}));x3dom.registerNodeType("Coordinate","Rendering",defineClass(x3dom.nodeTypes.X3DCoordinateNode,function(ctx){x3dom.nodeTypes.Coordinate.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'point',[]);},{getPoints:function(){return this._vf.point;}}));x3dom.registerNodeType("Normal","Rendering",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.Normal.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'vector',[]);},{fieldChanged:function(fieldName){Array.forEach(this._parentNodes,function(node){node.fieldChanged("normal");});},parentAdded:function(parent){if(parent._mesh&&parent._cf.normal.node!==this){parent.fieldChanged("normal");}}}));x3dom.registerNodeType("X3DColorNode","Rendering",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.X3DColorNode.superClass.call(this,ctx);},{fieldChanged:function(fieldName){Array.forEach(this._parentNodes,function(node){node.fieldChanged("color");});},parentAdded:function(parent){if(parent._mesh&&parent._cf.color.node!==this){parent.fieldChanged("color");}}}));x3dom.registerNodeType("Color","Rendering",defineClass(x3dom.nodeTypes.X3DColorNode,function(ctx){x3dom.nodeTypes.Color.superClass.call(this,ctx);this.addField_MFColor(ctx,'color',[]);}));x3dom.registerNodeType("ColorRGBA","Rendering",defineClass(x3dom.nodeTypes.X3DColorNode,function(ctx){x3dom.nodeTypes.ColorRGBA.superClass.call(this,ctx);this.addField_MFColorRGBA(ctx,'color',[]);}));x3dom.registerNodeType("X3DAppearanceNode","Shape",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DAppearanceNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Appearance","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceNode,function(ctx){x3dom.nodeTypes.Appearance.superClass.call(this,ctx);this.addField_SFNode('material',x3dom.nodeTypes.X3DMaterialNode);this.addField_SFNode('texture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('textureTransform',x3dom.nodeTypes.X3DTextureTransformNode);this.addField_SFNode('blendMode',x3dom.nodeTypes.BlendMode);this.addField_SFNode('depthMode',x3dom.nodeTypes.DepthMode);this.addField_MFNode('shaders',x3dom.nodeTypes.X3DShaderNode);this._shader=null;},{nodeChanged:function(){if(!this._cf.material.node){this.addChild(x3dom.nodeTypes.Material.defaultNode());}
if(this._cf.shaders.nodes.length){this._shader=this._cf.shaders.nodes[0];}},texTransformMatrix:function(){if(this._cf.textureTransform.node===null){return x3dom.fields.SFMatrix4f.identity();}
else{return this._cf.textureTransform.node.texTransformMatrix();}}}));x3dom.nodeTypes.Appearance.defaultNode=function(){if(!x3dom.nodeTypes.Appearance._defaultNode){x3dom.nodeTypes.Appearance._defaultNode=new x3dom.nodeTypes.Appearance();x3dom.nodeTypes.Appearance._defaultNode.nodeChanged();}
return x3dom.nodeTypes.Appearance._defaultNode;};x3dom.registerNodeType("X3DAppearanceChildNode","Shape",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DAppearanceChildNode.superClass.call(this,ctx);}));x3dom.registerNodeType("BlendMode","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.BlendMode.superClass.call(this,ctx);this.addField_SFString(ctx,'srcFactor',"src_alpha");this.addField_SFString(ctx,'destFactor',"one_minus_src_alpha");this.addField_SFColor(ctx,'color',1,1,1);this.addField_SFFloat(ctx,'colorTransparency',0);this.addField_SFString(ctx,'alphaFunc',"none");this.addField_SFFloat(ctx,'alphaFuncValue',0);this.addField_SFString(ctx,'equation',"none");}));x3dom.registerNodeType("DepthMode","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.DepthMode.superClass.call(this,ctx);this.addField_SFBool(ctx,'enableDepthTest',true);this.addField_SFString(ctx,'depthFunc',"none");this.addField_SFBool(ctx,'readOnly',false);this.addField_SFFloat(ctx,'zNearRange',-1);this.addField_SFFloat(ctx,'zFarRange',-1);}));x3dom.registerNodeType("X3DMaterialNode","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.X3DMaterialNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Material","Shape",defineClass(x3dom.nodeTypes.X3DMaterialNode,function(ctx){x3dom.nodeTypes.Material.superClass.call(this,ctx);this.addField_SFFloat(ctx,'ambientIntensity',0.2);this.addField_SFColor(ctx,'diffuseColor',0.8,0.8,0.8);this.addField_SFColor(ctx,'emissiveColor',0,0,0);this.addField_SFFloat(ctx,'shininess',0.2);this.addField_SFColor(ctx,'specularColor',0,0,0);this.addField_SFFloat(ctx,'transparency',0);},{fieldChanged:function(fieldName){if(fieldName=="ambientIntensity"||fieldName=="diffuseColor"||fieldName=="emissiveColor"||fieldName=="shininess"||fieldName=="specularColor"||fieldName=="transparency")
{Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.material=true;});});}}}));x3dom.nodeTypes.Material.defaultNode=function(){if(!x3dom.nodeTypes.Material._defaultNode){x3dom.nodeTypes.Material._defaultNode=new x3dom.nodeTypes.Material();x3dom.nodeTypes.Material._defaultNode.nodeChanged();}
return x3dom.nodeTypes.Material._defaultNode;};x3dom.registerNodeType("X3DShapeNode","Shape",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DShapeNode.superClass.call(this,ctx);this.addField_SFNode('appearance',x3dom.nodeTypes.X3DAppearanceNode);this.addField_SFNode('geometry',x3dom.nodeTypes.X3DGeometryNode);this._objectID=0;this._dirty={positions:true,normals:true,texcoords:true,colors:true,indexes:true,texture:true,material:true,text:true,shader:true};},{collectDrawableObjects:function(transform,out){if(out!==null)
{out.push([transform,this]);}},transformMatrix:function(transform){{return transform;}},getVolume:function(min,max,invalidate){if(this._cf.geometry.node){return this._cf.geometry.node.getVolume(min,max,invalidate);}
else{return false;}},getCenter:function(){if(this._cf.geometry.node){return this._cf.geometry.node.getCenter();}
else{return new x3dom.fields.SFVec3f(0,0,0);}},doIntersect:function(line){return this._cf.geometry.node.doIntersect(line);},isSolid:function(){return this._cf.geometry.node._vf.solid;},isCCW:function(){return this._cf.geometry.node._vf.ccw;},setAllDirty:function(){this._dirty.positions=true;this._dirty.normals=true;this._dirty.texcoords=true;this._dirty.colors=true;this._dirty.indexes=true;this._dirty.texture=true;this._dirty.material=true;this._dirty.text=true;this._dirty.shader=true;}}));x3dom.registerNodeType("Shape","Shape",defineClass(x3dom.nodeTypes.X3DShapeNode,function(ctx){x3dom.nodeTypes.Shape.superClass.call(this,ctx);},{nodeChanged:function(){if(!this._cf.appearance.node){this.addChild(x3dom.nodeTypes.Appearance.defaultNode());}
if(!this._cf.geometry.node){x3dom.debug.logError("No geometry given in Shape/"+this._DEF);}
else if(!this._objectID&&this._cf.geometry.node._pickable){this._objectID=++x3dom.nodeTypes.Shape.objectID;x3dom.nodeTypes.Shape.idMap.nodeID[this._objectID]=this;}},parentRemoved:function(parent)
{if(this._parentNodes.length===0&&this._webgl)
{var doc=this.findX3DDoc();var gl=doc.ctx.ctx3d;var sp=this._webgl.shader;for(var cnt=0;this._webgl.texture!==undefined&&cnt<this._webgl.texture.length;cnt++)
{if(this._webgl.texture[cnt])
{gl.deleteTexture(this._webgl.texture[cnt]);}}
for(var q=0;q<this._webgl.positions.length;q++)
{if(sp.position!==undefined)
{gl.deleteBuffer(this._webgl.buffers[5*q+1]);gl.deleteBuffer(this._webgl.buffers[5*q+0]);}
if(sp.normal!==undefined)
{gl.deleteBuffer(this._webgl.buffers[5*q+2]);}
if(sp.texcoord!==undefined)
{gl.deleteBuffer(this._webgl.buffers[5*q+3]);}
if(sp.color!==undefined)
{gl.deleteBuffer(this._webgl.buffers[5*q+4]);}}
for(var df=0;df<this._webgl.dynamicFields.length;df++)
{var attrib=this._webgl.dynamicFields[df];if(sp[attrib.name]!==undefined)
{gl.deleteBuffer(attrib.buf);}}
this._webgl=null;}}}));x3dom.nodeTypes.Shape.objectID=0;x3dom.nodeTypes.Shape.idMap={nodeID:{},remove:function(obj){for(var prop in this.nodeID){if(this.nodeID.hasOwnProperty(prop)){var val=this.nodeID[prop];if(val._objectID&&obj._objectID&&val._objectID===obj._objectID)
{delete this.nodeID[prop];x3dom.debug.logInfo("Unreg "+val._objectID);}}}}};x3dom.registerNodeType("X3DLightNode","Lighting",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DLightNode.superClass.call(this,ctx);ctx.doc._nodeBag.lights.push(this);this._lightID=0;this._dirty=true;this.addField_SFFloat(ctx,'ambientIntensity',0);this.addField_SFColor(ctx,'color',1,1,1);this.addField_SFFloat(ctx,'intensity',1);this.addField_SFBool(ctx,'global',false);this.addField_SFBool(ctx,'on',true);this.addField_SFFloat(ctx,'shadowIntensity',0);},{getViewMatrix:function(vec){return x3dom.fields.SFMatrix4f.identity;},nodeChanged:function(){if(!this._lightID){this._lightID=++x3dom.nodeTypes.X3DLightNode.lightID;}},fieldChanged:function(fieldName)
{this._dirty=true;},parentRemoved:function(parent)
{if(this._parentNodes.length===0){var doc=this.findX3DDoc();for(var i=0,n=doc._nodeBag.lights.length;i<n;i++){if(doc._nodeBag.lights[i]===this){doc._nodeBag.lights.splice(i,1);}}}}}));x3dom.nodeTypes.X3DLightNode.lightID=0;x3dom.registerNodeType("DirectionalLight","Lighting",defineClass(x3dom.nodeTypes.X3DLightNode,function(ctx){x3dom.nodeTypes.DirectionalLight.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'direction',0,0,-1);},{getViewMatrix:function(vec){var dir=this._vf.direction.normalize();var orientation=x3dom.fields.Quaternion.rotateFromTo(new x3dom.fields.SFVec3f(0,0,-1),dir);return orientation.toMatrix().transpose().mult(x3dom.fields.SFMatrix4f.translation(vec.negate()));}}));x3dom.registerNodeType("PointLight","Lighting",defineClass(x3dom.nodeTypes.X3DLightNode,function(ctx){x3dom.nodeTypes.PointLight.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'attenuation',1,0,0);this.addField_SFVec3f(ctx,'location',0,0,0);this.addField_SFFloat(ctx,'radius',100);this._vf.global=true;},{getViewMatrix:function(vec){var pos=this._vf.location;var orientation=x3dom.fields.Quaternion.rotateFromTo(new x3dom.fields.SFVec3f(0,0,-1),vec);return orientation.toMatrix().transpose().mult(x3dom.fields.SFMatrix4f.translation(pos.negate()));}}));x3dom.registerNodeType("SpotLight","Lighting",defineClass(x3dom.nodeTypes.X3DLightNode,function(ctx){x3dom.nodeTypes.SpotLight.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'direction',0,0,-1);this.addField_SFVec3f(ctx,'attenuation',1,0,0);this.addField_SFVec3f(ctx,'location',0,0,0);this.addField_SFFloat(ctx,'radius',100);this.addField_SFFloat(ctx,'beamWidth',1.5707963);this.addField_SFFloat(ctx,'cutOffAngle',1.5707963);this._vf.global=true;},{getViewMatrix:function(vec){var pos=this._vf.location;var dir=this._vf.direction.normalize();var orientation=x3dom.fields.Quaternion.rotateFromTo(new x3dom.fields.SFVec3f(0,0,-1),dir);return orientation.toMatrix().transpose().mult(x3dom.fields.SFMatrix4f.translation(pos.negate()));}}));x3dom.registerNodeType("X3DFollowerNode","Followers",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DFollowerNode.superClass.call(this,ctx);ctx.doc._nodeBag.followers.push(this);this.addField_SFBool(ctx,'isActive',false);},{nodeChanged:function(){},fieldChanged:function(fieldName){},parentRemoved:function(parent)
{if(this._parentNodes.length===0){var doc=this.findX3DDoc();for(var i=0,n=doc._nodeBag.followers.length;i<n;i++){if(doc._nodeBag.followers[i]===this){doc._nodeBag.followers.splice(i,1);}}}},tick:function(t){return false;},stepResponse:function(t)
{if(t<=0){return 0;}
if(t>=this._vf.duration){return 1;}
return this.stepResponseCore(t/this._vf.duration);},stepResponseCore:function(T)
{return 0.5-0.5*Math.cos(T*Math.PI);}}));x3dom.registerNodeType("X3DChaserNode","Followers",defineClass(x3dom.nodeTypes.X3DFollowerNode,function(ctx){x3dom.nodeTypes.X3DChaserNode.superClass.call(this,ctx);this.addField_SFTime(ctx,'duration',0);this._initDone=false;this._stepTime=0;this._currTime=0;this._bufferEndTime=0;this._numSupports=60;},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("X3DDamperNode","Followers",defineClass(x3dom.nodeTypes.X3DFollowerNode,function(ctx){x3dom.nodeTypes.X3DDamperNode.superClass.call(this,ctx);this.addField_SFTime(ctx,'tau',0);this.addField_SFFloat(ctx,'tolerance',-1);this.addField_SFInt32(ctx,'order',0);this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;this._lastTick=0;},{nodeChanged:function(){},fieldChanged:function(fieldName)
{if(fieldName==="tolerance")
{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}}}));x3dom.registerNodeType("ColorChaser","Followers",defineClass(x3dom.nodeTypes.X3DChaserNode,function(ctx){x3dom.nodeTypes.ColorChaser.superClass.call(this,ctx);this.addField_SFColor(ctx,'initialDestination',0.8,0.8,0.8);this.addField_SFColor(ctx,'initialValue',0.8,0.8,0.8);this.addField_SFColor(ctx,'set_value',0,0,0);this.addField_SFColor(ctx,'set_destination',0,0,0);this._buffer=new x3dom.fields.MFColor();this._previousValue=new x3dom.fields.SFColor(0,0,0);this._value=new x3dom.fields.SFColor(0,0,0);},{nodeChanged:function()
{this.initialize();},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
else if(fieldName.indexOf("set_value")>=0)
{this.initialize();this._previousValue.setValues(this._vf.set_value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.set_value);}
this.postMessage('value_changed',this._vf.set_value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
{if(!this._initDone)
{this._initDone=true;this._vf.set_destination=this._vf.initialDestination;this._buffer.length=this._numSupports;this._buffer[0]=this._vf.initialDestination;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.initialValue;}
this._previousValue=this._vf.initialValue;this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],x3dom.fields.Eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}}},tick:function(now)
{this.initialize();this._currTime=now;if(!this._bufferEndTime)
{this._bufferEndTime=now;this._value=this._vf.initialValue;this.postMessage('value_changed',this._value);return true;}
var Frac=this.updateBuffer(now);var Output=this._previousValue;var DeltaIn=this._buffer[this._buffer.length-1].subtract(this._previousValue);var DeltaOut=DeltaIn.multiply(this.stepResponse((this._buffer.length-1+Frac)*this._stepTime));Output=Output.add(DeltaOut);for(var C=this._buffer.length-2;C>=0;C--)
{DeltaIn=this._buffer[C].subtract(this._buffer[C+1]);DeltaOut=DeltaIn.multiply(this.stepResponse((C+Frac)*this._stepTime));Output=Output.add(DeltaOut);}
if(!Output.equals(this._value,x3dom.fields.Eps)){this._value.setValues(Output);this.postMessage('value_changed',this._value);}
else{this.postMessage('isActive',false);}
return this._vf.isActive;},updateBuffer:function(now)
{var Frac=(now-this._bufferEndTime)/this._stepTime;var C;var NumToShift;var Alpha;if(Frac>=1)
{NumToShift=Math.floor(Frac);Frac-=NumToShift;if(NumToShift<this._buffer.length)
{this._previousValue=this._buffer[this._buffer.length-NumToShift];for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=this._buffer[C-NumToShift];}
for(C=0;C<NumToShift;C++)
{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift].multiply(Alpha).add(this._vf.set_destination.multiply((1-Alpha)));}}
else
{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.set_destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_destination;}}
this._bufferEndTime+=NumToShift*this._stepTime;}
return Frac;}}));x3dom.registerNodeType("ColorDamper","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.ColorDamper.superClass.call(this,ctx);this.addField_SFColor(ctx,'initialDestination',0.8,0.8,0.8);this.addField_SFColor(ctx,'initialValue',0.8,0.8,0.8);this.addField_SFColor(ctx,'set_value',0,0,0);this.addField_SFColor(ctx,'set_destination',0,0,0);this._value0=new x3dom.fields.SFColor(0,0,0);this._value1=new x3dom.fields.SFColor(0,0,0);this._value2=new x3dom.fields.SFColor(0,0,0);this._value3=new x3dom.fields.SFColor(0,0,0);this._value4=new x3dom.fields.SFColor(0,0,0);this._value5=new x3dom.fields.SFColor(0,0,0);this.initialize();},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{if(!this._value0.equals(this._vf.set_destination,this._eps)){this._value0=this._vf.set_destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
else if(fieldName.indexOf("set_value")>=0)
{this._value1.setValues(this._vf.set_value);this._value2.setValues(this._vf.set_value);this._value3.setValues(this._vf.set_value);this._value4.setValues(this._vf.set_value);this._value5.setValues(this._vf.set_value);this._lastTick=0;this.postMessage('value_changed',this._value5);if(!this._vf.isActive){this._lastTick=0;this.postMessage('isActive',true);}}},initialize:function()
{this._value0.setValues(this._vf.initialDestination);this._value1.setValues(this._vf.initialValue);this._value2.setValues(this._vf.initialValue);this._value3.setValues(this._vf.initialValue);this._value4.setValues(this._vf.initialValue);this._value5.setValues(this._vf.initialValue);this._lastTick=0;var active=!this._value0.equals(this._value1,this._eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}},distance:function(a,b)
{var diff=a.subtract(b);return Math.sqrt(diff.r*diff.r+diff.g*diff.g+diff.b*diff.b);},tick:function(now)
{if(!this._lastTick)
{this._lastTick=now;return false;}
var delta=now-this._lastTick;var alpha=Math.exp(-delta/this._vf.tau);this._value1=this._vf.order>0&&this._vf.tau?this._value0.add(this._value1.subtract(this._value0).multiply(alpha)):new x3dom.fields.SFColor(this._value0.r,this._value0.g,this._value0.b);this._value2=this._vf.order>1&&this._vf.tau?this._value1.add(this._value2.subtract(this._value1).multiply(alpha)):new x3dom.fields.SFColor(this._value1.r,this._value1.g,this._value1.b);this._value3=this._vf.order>2&&this._vf.tau?this._value2.add(this._value3.subtract(this._value2).multiply(alpha)):new x3dom.fields.SFColor(this._value2.r,this._value2.g,this._value2.b);this._value4=this._vf.order>3&&this._vf.tau?this._value3.add(this._value4.subtract(this._value3).multiply(alpha)):new x3dom.fields.SFColor(this._value3.r,this._value3.g,this._value3.b);this._value5=this._vf.order>4&&this._vf.tau?this._value4.add(this._value5.subtract(this._value4).multiply(alpha)):new x3dom.fields.SFColor(this._value4.r,this._value4.g,this._value4.b);var dist=this.distance(this._value1,this._value0);if(this._vf.order>1)
{var dist2=this.distance(this._value2,this._value1);if(dist2>dist){dist=dist2;}}
if(this._vf.order>2)
{var dist3=this.distance(this._value3,this._value2);if(dist3>dist){dist=dist3;}}
if(this._vf.order>3)
{var dist4=this.distance(this._value4,this._value3);if(dist4>dist){dist=dist4;}}
if(this._vf.order>4)
{var dist5=this.distance(this._value5,this._value4);if(dist5>dist){dist=dist5;}}
if(dist<this._eps)
{this._value1.setValues(this._value0);this._value2.setValues(this._value0);this._value3.setValues(this._value0);this._value4.setValues(this._value0);this._value5.setValues(this._value0);this.postMessage('value_changed',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
this.postMessage('value_changed',this._value5);this._lastTick=now;return true;}}));x3dom.registerNodeType("OrientationChaser","Followers",defineClass(x3dom.nodeTypes.X3DChaserNode,function(ctx){x3dom.nodeTypes.OrientationChaser.superClass.call(this,ctx);this.addField_SFRotation(ctx,'initialDestination',0,1,0,0);this.addField_SFRotation(ctx,'initialValue',0,1,0,0);this.addField_SFRotation(ctx,'set_value',0,1,0,0);this.addField_SFRotation(ctx,'set_destination',0,1,0,0);this._numSupports=30;this._buffer=new x3dom.fields.MFRotation();this._previousValue=new x3dom.fields.Quaternion(0,1,0,0);this._value=new x3dom.fields.Quaternion(0,1,0,0);},{nodeChanged:function()
{this.initialize();},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
else if(fieldName.indexOf("set_value")>=0)
{this.initialize();this._previousValue.setValues(this._vf.set_value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.set_value);}
this.postMessage('value_changed',this._vf.set_value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
{if(!this._initDone)
{this._initDone=true;this._vf.set_destination=this._vf.initialDestination;this._buffer.length=this._numSupports;this._buffer[0]=this._vf.initialDestination;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.initialValue;}
this._previousValue=this._vf.initialValue;this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],x3dom.fields.Eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}}},tick:function(now)
{this.initialize();this._currTime=now;if(!this._bufferEndTime)
{this._bufferEndTime=now;this._value=this._vf.initialValue;this.postMessage('value_changed',this._value);return true;}
var Frac=this.updateBuffer(now);var Output=this._previousValue;var DeltaIn=this._previousValue.inverse().multiply(this._buffer[this._buffer.length-1]);Output=Output.slerp(Output.multiply(DeltaIn),this.stepResponse((this._buffer.length-1+Frac)*this._stepTime));for(var C=this._buffer.length-2;C>=0;C--)
{DeltaIn=this._buffer[C+1].inverse().multiply(this._buffer[C]);Output=Output.slerp(Output.multiply(DeltaIn),this.stepResponse((C+Frac)*this._stepTime));}
if(!Output.equals(this._value,x3dom.fields.Eps)){Output=Output.normalize(Output);this._value.setValues(Output);this.postMessage('value_changed',this._value);}
else{this.postMessage('isActive',false);}
return this._vf.isActive;},updateBuffer:function(now)
{var Frac=(now-this._bufferEndTime)/this._stepTime;var C;var NumToShift;var Alpha;if(Frac>=1)
{NumToShift=Math.floor(Frac);Frac-=NumToShift;if(NumToShift<this._buffer.length)
{this._previousValue=this._buffer[this._buffer.length-NumToShift];for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=this._buffer[C-NumToShift];}
for(C=0;C<NumToShift;C++)
{Alpha=C/NumToShift;this._buffer[C]=this._vf.set_destination.slerp(this._buffer[NumToShift],Alpha);}}
else
{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.set_destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_destination;}}
this._bufferEndTime+=NumToShift*this._stepTime;}
return Frac;}}));x3dom.registerNodeType("OrientationDamper","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.OrientationDamper.superClass.call(this,ctx);this.addField_SFRotation(ctx,'initialDestination',0,1,0,0);this.addField_SFRotation(ctx,'initialValue',0,1,0,0);this.addField_SFRotation(ctx,'set_value',0,1,0,0);this.addField_SFRotation(ctx,'set_destination',0,1,0,0);this._value0=new x3dom.fields.Quaternion(0,1,0,0);this._value1=new x3dom.fields.Quaternion(0,1,0,0);this._value2=new x3dom.fields.Quaternion(0,1,0,0);this._value3=new x3dom.fields.Quaternion(0,1,0,0);this._value4=new x3dom.fields.Quaternion(0,1,0,0);this._value5=new x3dom.fields.Quaternion(0,1,0,0);this.initialize();},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{if(!this._value0.equals(this._vf.set_destination,this._eps)){this._value0=this._vf.set_destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
else if(fieldName.indexOf("set_value")>=0)
{this._value1.setValues(this._vf.set_value);this._value2.setValues(this._vf.set_value);this._value3.setValues(this._vf.set_value);this._value4.setValues(this._vf.set_value);this._value5.setValues(this._vf.set_value);this._lastTick=0;this.postMessage('value_changed',this._value5);if(!this._vf.isActive){this._lastTick=0;this.postMessage('isActive',true);}}},initialize:function()
{this._value0.setValues(this._vf.initialDestination);this._value1.setValues(this._vf.initialValue);this._value2.setValues(this._vf.initialValue);this._value3.setValues(this._vf.initialValue);this._value4.setValues(this._vf.initialValue);this._value5.setValues(this._vf.initialValue);this._lastTick=0;var active=!this._value0.equals(this._value1,this._eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}},tick:function(now)
{if(!this._lastTick)
{this._lastTick=now;return false;}
var delta=now-this._lastTick;var alpha=Math.exp(-delta/this._vf.tau);this._value1=this._vf.order>0&&this._vf.tau?this._value0.slerp(this._value1,alpha):new x3dom.fields.Quaternion(this._value0.x,this._value0.y,this._value0.z,this._value0.w);this._value2=this._vf.order>1&&this._vf.tau?this._value1.slerp(this._value2,alpha):new x3dom.fields.Quaternion(this._value1.x,this._value1.y,this._value1.z,this._value1.w);this._value3=this._vf.order>2&&this._vf.tau?this._value2.slerp(this._value3,alpha):new x3dom.fields.Quaternion(this._value2.x,this._value2.y,this._value2.z,this._value2.w);this._value4=this._vf.order>3&&this._vf.tau?this._value3.slerp(this._value4,alpha):new x3dom.fields.Quaternion(this._value3.x,this._value3.y,this._value3.z,this._value3.w);this._value5=this._vf.order>4&&this._vf.tau?this._value4.slerp(this._value5,alpha):new x3dom.fields.Quaternion(this._value4.x,this._value4.y,this._value4.z,this._value4.w);var dist=Math.abs(this._value1.inverse().multiply(this._value0).angle());if(this._vf.order>1)
{var dist2=Math.abs(this._value2.inverse().multiply(this._value1).angle());if(dist2>dist){dist=dist2;}}
if(this._vf.order>2)
{var dist3=Math.abs(this._value3.inverse().multiply(this._value2).angle());if(dist3>dist){dist=dist3;}}
if(this._vf.order>3)
{var dist4=Math.abs(this._value4.inverse().multiply(this._value3).angle());if(dist4>dist){dist=dist4;}}
if(this._vf.order>4)
{var dist5=Math.abs(this._value5.inverse().multiply(this._value4).angle());if(dist5>dist){dist=dist5;}}
if(dist<this._eps)
{this._value1.setValues(this._value0);this._value2.setValues(this._value0);this._value3.setValues(this._value0);this._value4.setValues(this._value0);this._value5.setValues(this._value0);this.postMessage('value_changed',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
this.postMessage('value_changed',this._value5);this._lastTick=now;return true;}}));x3dom.registerNodeType("PositionChaser","Followers",defineClass(x3dom.nodeTypes.X3DChaserNode,function(ctx){x3dom.nodeTypes.PositionChaser.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'initialDestination',0,0,0);this.addField_SFVec3f(ctx,'initialValue',0,0,0);this.addField_SFVec3f(ctx,'set_value',0,0,0);this.addField_SFVec3f(ctx,'set_destination',0,0,0);this._buffer=new x3dom.fields.MFVec3f();this._previousValue=new x3dom.fields.SFVec3f(0,0,0);this._value=new x3dom.fields.SFVec3f(0,0,0);},{nodeChanged:function()
{this.initialize();},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
else if(fieldName.indexOf("set_value")>=0)
{this.initialize();this._previousValue.setValues(this._vf.set_value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.set_value);}
this.postMessage('value_changed',this._vf.set_value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
{if(!this._initDone)
{this._initDone=true;this._vf.set_destination=this._vf.initialDestination;this._buffer.length=this._numSupports;this._buffer[0]=this._vf.initialDestination;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.initialValue;}
this._previousValue=this._vf.initialValue;this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],x3dom.fields.Eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}}},tick:function(now)
{this.initialize();this._currTime=now;if(!this._bufferEndTime)
{this._bufferEndTime=now;this._value=this._vf.initialValue;this.postMessage('value_changed',this._value);return true;}
var Frac=this.updateBuffer(now);var Output=this._previousValue;var DeltaIn=this._buffer[this._buffer.length-1].subtract(this._previousValue);var DeltaOut=DeltaIn.multiply(this.stepResponse((this._buffer.length-1+Frac)*this._stepTime));Output=Output.add(DeltaOut);for(var C=this._buffer.length-2;C>=0;C--)
{DeltaIn=this._buffer[C].subtract(this._buffer[C+1]);DeltaOut=DeltaIn.multiply(this.stepResponse((C+Frac)*this._stepTime));Output=Output.add(DeltaOut);}
if(!Output.equals(this._value,x3dom.fields.Eps)){this._value.setValues(Output);this.postMessage('value_changed',this._value);}
else{this.postMessage('isActive',false);}
return this._vf.isActive;},updateBuffer:function(now)
{var Frac=(now-this._bufferEndTime)/this._stepTime;var C;var NumToShift;var Alpha;if(Frac>=1)
{NumToShift=Math.floor(Frac);Frac-=NumToShift;if(NumToShift<this._buffer.length)
{this._previousValue=this._buffer[this._buffer.length-NumToShift];for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=this._buffer[C-NumToShift];}
for(C=0;C<NumToShift;C++)
{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift].multiply(Alpha).add(this._vf.set_destination.multiply((1-Alpha)));}}
else
{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.set_destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_destination;}}
this._bufferEndTime+=NumToShift*this._stepTime;}
return Frac;}}));x3dom.registerNodeType("PositionChaser2D","Followers",defineClass(x3dom.nodeTypes.X3DChaserNode,function(ctx){x3dom.nodeTypes.PositionChaser2D.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'initialDestination',0,0);this.addField_SFVec2f(ctx,'initialValue',0,0);this.addField_SFVec2f(ctx,'set_value',0,0);this.addField_SFVec2f(ctx,'set_destination',0,0);this._buffer=new x3dom.fields.MFVec2f();this._previousValue=new x3dom.fields.SFVec2f(0,0);this._value=new x3dom.fields.SFVec2f(0,0);},{nodeChanged:function()
{this.initialize();},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
else if(fieldName.indexOf("set_value")>=0)
{this.initialize();this._previousValue.setValues(this._vf.set_value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.set_value);}
this.postMessage('value_changed',this._vf.set_value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
{if(!this._initDone)
{this._initDone=true;this._vf.set_destination=this._vf.initialDestination;this._buffer.length=this._numSupports;this._buffer[0]=this._vf.initialDestination;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.initialValue;}
this._previousValue=this._vf.initialValue;this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],x3dom.fields.Eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}}},tick:function(now)
{this.initialize();this._currTime=now;if(!this._bufferEndTime)
{this._bufferEndTime=now;this._value=this._vf.initialValue;this.postMessage('value_changed',this._value);return true;}
var Frac=this.updateBuffer(now);var Output=this._previousValue;var DeltaIn=this._buffer[this._buffer.length-1].subtract(this._previousValue);var DeltaOut=DeltaIn.multiply(this.stepResponse((this._buffer.length-1+Frac)*this._stepTime));Output=Output.add(DeltaOut);for(var C=this._buffer.length-2;C>=0;C--)
{DeltaIn=this._buffer[C].subtract(this._buffer[C+1]);DeltaOut=DeltaIn.multiply(this.stepResponse((C+Frac)*this._stepTime));Output=Output.add(DeltaOut);}
if(!Output.equals(this._value,x3dom.fields.Eps)){this._value.setValues(Output);this.postMessage('value_changed',this._value);}
else{this.postMessage('isActive',false);}
return this._vf.isActive;},updateBuffer:function(now)
{var Frac=(now-this._bufferEndTime)/this._stepTime;var C;var NumToShift;var Alpha;if(Frac>=1)
{NumToShift=Math.floor(Frac);Frac-=NumToShift;if(NumToShift<this._buffer.length)
{this._previousValue=this._buffer[this._buffer.length-NumToShift];for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=this._buffer[C-NumToShift];}
for(C=0;C<NumToShift;C++)
{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift].multiply(Alpha).add(this._vf.set_destination.multiply((1-Alpha)));}}
else
{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.set_destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_destination;}}
this._bufferEndTime+=NumToShift*this._stepTime;}
return Frac;}}));x3dom.registerNodeType("PositionDamper","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.PositionDamper.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'initialDestination',0,0,0);this.addField_SFVec3f(ctx,'initialValue',0,0,0);this.addField_SFVec3f(ctx,'set_value',0,0,0);this.addField_SFVec3f(ctx,'set_destination',0,0,0);this._value0=new x3dom.fields.SFVec3f(0,0,0);this._value1=new x3dom.fields.SFVec3f(0,0,0);this._value2=new x3dom.fields.SFVec3f(0,0,0);this._value3=new x3dom.fields.SFVec3f(0,0,0);this._value4=new x3dom.fields.SFVec3f(0,0,0);this._value5=new x3dom.fields.SFVec3f(0,0,0);this.initialize();},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{if(!this._value0.equals(this._vf.set_destination,this._eps)){this._value0=this._vf.set_destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
else if(fieldName.indexOf("set_value")>=0)
{this._value1.setValues(this._vf.set_value);this._value2.setValues(this._vf.set_value);this._value3.setValues(this._vf.set_value);this._value4.setValues(this._vf.set_value);this._value5.setValues(this._vf.set_value);this._lastTick=0;this.postMessage('value_changed',this._value5);if(!this._vf.isActive){this._lastTick=0;this.postMessage('isActive',true);}}},initialize:function()
{this._value0.setValues(this._vf.initialDestination);this._value1.setValues(this._vf.initialValue);this._value2.setValues(this._vf.initialValue);this._value3.setValues(this._vf.initialValue);this._value4.setValues(this._vf.initialValue);this._value5.setValues(this._vf.initialValue);this._lastTick=0;var active=!this._value0.equals(this._value1,this._eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}},tick:function(now)
{if(!this._lastTick)
{this._lastTick=now;return false;}
var delta=now-this._lastTick;var alpha=Math.exp(-delta/this._vf.tau);this._value1=this._vf.order>0&&this._vf.tau?this._value0.add(this._value1.subtract(this._value0).multiply(alpha)):new x3dom.fields.SFVec3f(this._value0.x,this._value0.y,this._value0.z);this._value2=this._vf.order>1&&this._vf.tau?this._value1.add(this._value2.subtract(this._value1).multiply(alpha)):new x3dom.fields.SFVec3f(this._value1.x,this._value1.y,this._value1.z);this._value3=this._vf.order>2&&this._vf.tau?this._value2.add(this._value3.subtract(this._value2).multiply(alpha)):new x3dom.fields.SFVec3f(this._value2.x,this._value2.y,this._value2.z);this._value4=this._vf.order>3&&this._vf.tau?this._value3.add(this._value4.subtract(this._value3).multiply(alpha)):new x3dom.fields.SFVec3f(this._value3.x,this._value3.y,this._value3.z);this._value5=this._vf.order>4&&this._vf.tau?this._value4.add(this._value5.subtract(this._value4).multiply(alpha)):new x3dom.fields.SFVec3f(this._value4.x,this._value4.y,this._value4.z);var dist=this._value1.subtract(this._value0).length();if(this._vf.order>1)
{var dist2=this._value2.subtract(this._value1).length();if(dist2>dist){dist=dist2;}}
if(this._vf.order>2)
{var dist3=this._value3.subtract(this._value2).length();if(dist3>dist){dist=dist3;}}
if(this._vf.order>3)
{var dist4=this._value4.subtract(this._value3).length();if(dist4>dist){dist=dist4;}}
if(this._vf.order>4)
{var dist5=this._value5.subtract(this._value4).length();if(dist5>dist){dist=dist5;}}
if(dist<this._eps)
{this._value1.setValues(this._value0);this._value2.setValues(this._value0);this._value3.setValues(this._value0);this._value4.setValues(this._value0);this._value5.setValues(this._value0);this.postMessage('value_changed',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
this.postMessage('value_changed',this._value5);this._lastTick=now;return true;}}));x3dom.registerNodeType("PositionDamper2D","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.PositionDamper2D.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'initialDestination',0,0);this.addField_SFVec2f(ctx,'initialValue',0,0);this.addField_SFVec2f(ctx,'set_value',0,0);this.addField_SFVec2f(ctx,'set_destination',0,0);this._value0=new x3dom.fields.SFVec2f(0,0);this._value1=new x3dom.fields.SFVec2f(0,0);this._value2=new x3dom.fields.SFVec2f(0,0);this._value3=new x3dom.fields.SFVec2f(0,0);this._value4=new x3dom.fields.SFVec2f(0,0);this._value5=new x3dom.fields.SFVec2f(0,0);this.initialize();},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{if(!this._value0.equals(this._vf.set_destination,this._eps)){this._value0=this._vf.set_destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
else if(fieldName.indexOf("set_value")>=0)
{this._value1.setValues(this._vf.set_value);this._value2.setValues(this._vf.set_value);this._value3.setValues(this._vf.set_value);this._value4.setValues(this._vf.set_value);this._value5.setValues(this._vf.set_value);this._lastTick=0;this.postMessage('value_changed',this._value5);if(!this._vf.isActive){this._lastTick=0;this.postMessage('isActive',true);}}},initialize:function()
{this._value0.setValues(this._vf.initialDestination);this._value1.setValues(this._vf.initialValue);this._value2.setValues(this._vf.initialValue);this._value3.setValues(this._vf.initialValue);this._value4.setValues(this._vf.initialValue);this._value5.setValues(this._vf.initialValue);this._lastTick=0;var active=!this._value0.equals(this._value1,this._eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}},tick:function(now)
{if(!this._lastTick)
{this._lastTick=now;return false;}
var delta=now-this._lastTick;var alpha=Math.exp(-delta/this._vf.tau);this._value1=this._vf.order>0&&this._vf.tau?this._value0.add(this._value1.subtract(this._value0).multiply(alpha)):new x3dom.fields.SFVec2f(this._value0.x,this._value0.y,this._value0.z);this._value2=this._vf.order>1&&this._vf.tau?this._value1.add(this._value2.subtract(this._value1).multiply(alpha)):new x3dom.fields.SFVec2f(this._value1.x,this._value1.y,this._value1.z);this._value3=this._vf.order>2&&this._vf.tau?this._value2.add(this._value3.subtract(this._value2).multiply(alpha)):new x3dom.fields.SFVec2f(this._value2.x,this._value2.y,this._value2.z);this._value4=this._vf.order>3&&this._vf.tau?this._value3.add(this._value4.subtract(this._value3).multiply(alpha)):new x3dom.fields.SFVec2f(this._value3.x,this._value3.y,this._value3.z);this._value5=this._vf.order>4&&this._vf.tau?this._value4.add(this._value5.subtract(this._value4).multiply(alpha)):new x3dom.fields.SFVec2f(this._value4.x,this._value4.y,this._value4.z);var dist=this._value1.subtract(this._value0).length();if(this._vf.order>1)
{var dist2=this._value2.subtract(this._value1).length();if(dist2>dist){dist=dist2;}}
if(this._vf.order>2)
{var dist3=this._value3.subtract(this._value2).length();if(dist3>dist){dist=dist3;}}
if(this._vf.order>3)
{var dist4=this._value4.subtract(this._value3).length();if(dist4>dist){dist=dist4;}}
if(this._vf.order>4)
{var dist5=this._value5.subtract(this._value4).length();if(dist5>dist){dist=dist5;}}
if(dist<this._eps)
{this._value1.setValues(this._value0);this._value2.setValues(this._value0);this._value3.setValues(this._value0);this._value4.setValues(this._value0);this._value5.setValues(this._value0);this.postMessage('value_changed',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
this.postMessage('value_changed',this._value5);this._lastTick=now;return true;}}));x3dom.registerNodeType("ScalarChaser","Followers",defineClass(x3dom.nodeTypes.X3DChaserNode,function(ctx){x3dom.nodeTypes.ScalarChaser.superClass.call(this,ctx);this.addField_SFFloat(ctx,'initialDestination',0);this.addField_SFFloat(ctx,'initialValue',0);this.addField_SFFloat(ctx,'set_value',0);this.addField_SFFloat(ctx,'set_destination',0);this._buffer=[];this._previousValue=0;this._value=0;},{nodeChanged:function()
{this.initialize();},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
else if(fieldName.indexOf("set_value")>=0)
{this.initialize();this._previousValue=this._vf.set_value;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_value;}
this.postMessage('value_changed',this._vf.set_value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
{if(!this._initDone)
{this._initDone=true;this._vf.set_destination=this._vf.initialDestination;this._buffer.length=this._numSupports;this._buffer[0]=this._vf.initialDestination;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.initialValue;}
this._previousValue=this._vf.initialValue;this._stepTime=this._vf.duration/this._numSupports;var active=(Math.abs(this._buffer[0]-this._buffer[1])>=x3dom.fields.Eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}}},tick:function(now)
{this.initialize();this._currTime=now;if(!this._bufferEndTime)
{this._bufferEndTime=now;this._value=this._vf.initialValue;this.postMessage('value_changed',this._value);return true;}
var Frac=this.updateBuffer(now);var Output=this._previousValue;var DeltaIn=this._buffer[this._buffer.length-1]-this._previousValue;var DeltaOut=DeltaIn*(this.stepResponse((this._buffer.length-1+Frac)*this._stepTime));Output=Output+DeltaOut;for(var C=this._buffer.length-2;C>=0;C--)
{DeltaIn=this._buffer[C]-this._buffer[C+1];DeltaOut=DeltaIn*(this.stepResponse((C+Frac)*this._stepTime));Output=Output+DeltaOut;}
if(Math.abs(Output-this._value)>=x3dom.fields.Eps){this._value=Output;this.postMessage('value_changed',this._value);}
else{this.postMessage('isActive',false);}
return this._vf.isActive;},updateBuffer:function(now)
{var Frac=(now-this._bufferEndTime)/this._stepTime;var C;var NumToShift;var Alpha;if(Frac>=1)
{NumToShift=Math.floor(Frac);Frac-=NumToShift;if(NumToShift<this._buffer.length)
{this._previousValue=this._buffer[this._buffer.length-NumToShift];for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=this._buffer[C-NumToShift];}
for(C=0;C<NumToShift;C++)
{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift]*Alpha+this._vf.set_destination*(1-Alpha);}}
else
{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.set_destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.set_destination;}}
this._bufferEndTime+=NumToShift*this._stepTime;}
return Frac;}}));x3dom.registerNodeType("ScalarDamper","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.ScalarDamper.superClass.call(this,ctx);this.addField_SFFloat(ctx,'initialDestination',0);this.addField_SFFloat(ctx,'initialValue',0);this.addField_SFFloat(ctx,'set_value',0);this.addField_SFFloat(ctx,'set_destination',0);this._value0=0;this._value1=0;this._value2=0;this._value3=0;this._value4=0;this._value5=0;this.initialize();},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName.indexOf("set_destination")>=0)
{if(Math.abs(this._value0-this._vf.set_destination)>=this._eps){this._value0=this._vf.set_destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
else if(fieldName.indexOf("set_value")>=0)
{this._value1=this._vf.set_value;this._value2=this._vf.set_value;this._value3=this._vf.set_value;this._value4=this._vf.set_value;this._value5=this._vf.set_value;this._lastTick=0;this.postMessage('value_changed',this._value5);if(!this._vf.isActive){this._lastTick=0;this.postMessage('isActive',true);}}},initialize:function()
{this._value0=this._vf.initialDestination;this._value1=this._vf.initialValue;this._value2=this._vf.initialValue;this._value3=this._vf.initialValue;this._value4=this._vf.initialValue;this._value5=this._vf.initialValue;this._lastTick=0;var active=(Math.abs(this._value0-this._value1)>=this._eps);if(this._vf.isActive!==active){this.postMessage('isActive',active);}},tick:function(now)
{if(!this._lastTick)
{this._lastTick=now;return false;}
var delta=now-this._lastTick;var alpha=Math.exp(-delta/this._vf.tau);this._value1=this._vf.order>0&&this._vf.tau?this._value0+alpha*(this._value1-this._value0):this._value0;this._value2=this._vf.order>1&&this._vf.tau?this._value1+alpha*(this._value2-this._value1):this._value1;this._value3=this._vf.order>2&&this._vf.tau?this._value2+alpha*(this._value3-this._value2):this._value2;this._value4=this._vf.order>3&&this._vf.tau?this._value3+alpha*(this._value4-this._value3):this._value3;this._value5=this._vf.order>4&&this._vf.tau?this._value4+alpha*(this._value5-this._value4):this._value4;var dist=Math.abs(this._value1-this._value0);if(this._vf.order>1)
{var dist2=Math.abs(this._value2-this._value1);if(dist2>dist){dist=dist2;}}
if(this._vf.order>2)
{var dist3=Math.abs(this._value3-this._value2);if(dist3>dist){dist=dist3;}}
if(this._vf.order>3)
{var dist4=Math.abs(this._value4-this._value3);if(dist4>dist){dist=dist4;}}
if(this._vf.order>4)
{var dist5=Math.abs(this._value5-this._value4);if(dist5>dist){dist=dist5;}}
if(dist<this._eps)
{this._value1=this._value0;this._value2=this._value0;this._value3=this._value0;this._value4=this._value0;this._value5=this._value0;this.postMessage('value_changed',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
this.postMessage('value_changed',this._value5);this._lastTick=now;return true;}}));x3dom.registerNodeType("CoordinateDamper","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.CoordinateDamper.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'initialDestination',[]);this.addField_MFVec3f(ctx,'initialValue',[]);this.addField_MFVec3f(ctx,'set_value',[]);this.addField_MFVec3f(ctx,'set_destination',[]);x3dom.debug.logWarning("CoordinateDamper NYI");},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("TexCoordDamper2D","Followers",defineClass(x3dom.nodeTypes.X3DDamperNode,function(ctx){x3dom.nodeTypes.TexCoordDamper2D.superClass.call(this,ctx);this.addField_MFVec2f(ctx,'initialDestination',[]);this.addField_MFVec2f(ctx,'initialValue',[]);this.addField_MFVec2f(ctx,'set_value',[]);this.addField_MFVec2f(ctx,'set_destination',[]);x3dom.debug.logWarning("TexCoordDamper2D NYI");},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("X3DInterpolatorNode","Interpolation",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DInterpolatorNode.superClass.call(this,ctx);this.addField_MFFloat(ctx,'key',[]);this.addField_SFFloat(ctx,'set_fraction',0);},{linearInterp:function(t,interp){if(t<=this._vf.key[0]){return this._vf.keyValue[0];}
if(t>=this._vf.key[this._vf.key.length-1]){return this._vf.keyValue[this._vf.key.length-1];}
for(var i=0;i<this._vf.key.length-1;++i){if((this._vf.key[i]<t)&&(t<=this._vf.key[i+1])){return interp(this._vf.keyValue[i],this._vf.keyValue[i+1],(t-this._vf.key[i])/(this._vf.key[i+1]-this._vf.key[i]));}}
return this._vf.keyValue[0];}}));x3dom.registerNodeType("OrientationInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.OrientationInterpolator.superClass.call(this,ctx);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.keyValue=x3dom.fields.MFRotation.parse(ctx.xmlNode.getAttribute('keyValue'));}else{this._vf.keyValue=new x3dom.fields.MFRotation();}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){return a.slerp(b,t);});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("PositionInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.PositionInterpolator.superClass.call(this,ctx);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.keyValue=x3dom.fields.MFVec3f.parse(ctx.xmlNode.getAttribute('keyValue'));}else{this._vf.keyValue=new x3dom.fields.MFVec3f();}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){return a.multiply(1.0-t).add(b.multiply(t));});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("NormalInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.NormalInterpolator.superClass.call(this,ctx);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.keyValue=x3dom.fields.MFVec3f.parse(ctx.xmlNode.getAttribute('keyValue'));}else{this._vf.keyValue=new x3dom.fields.MFVec3f();}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){return a.multiply(1.0-t).add(b.multiply(t)).normalize();});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("ColorInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.ColorInterpolator.superClass.call(this,ctx);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.keyValue=x3dom.fields.MFColor.parse(ctx.xmlNode.getAttribute('keyValue'));}else{this._vf.keyValue=new x3dom.fields.MFColor();}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){return a.multiply(1.0-t).add(b.multiply(t));});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("ScalarInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.ScalarInterpolator.superClass.call(this,ctx);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.keyValue=Array.map(ctx.xmlNode.getAttribute('keyValue').split(/\s+/),function(n){return+n;});}else{this._vf.keyValue=new x3dom.fields.MFFloat();}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){return(1.0-t)*a+t*b;});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("CoordinateInterpolator","Interpolation",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.CoordinateInterpolator.superClass.call(this,ctx);this._vf.keyValue=[];if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){var arr=x3dom.fields.MFVec3f.parse(ctx.xmlNode.getAttribute('keyValue'));var key=this._vf.key.length>0?this._vf.key.length:1;var len=arr.length/key;for(var i=0;i<key;i++){var val=new x3dom.fields.MFVec3f();for(var j=0;j<len;j++){val.push(arr[i*len+j]);}
this._vf.keyValue.push(val);}}
this._fieldWatchers.fraction=this._fieldWatchers.set_fraction=[function(msg){var value=this.linearInterp(msg,function(a,b,t){var val=new x3dom.fields.MFVec3f();for(var i=0;i<a.length;i++){val.push(a[i].multiply(1.0-t).add(b[i].multiply(t)));}
return val;});this.postMessage('value_changed',value);}];}));x3dom.registerNodeType("TimeSensor","Time",defineClass(x3dom.nodeTypes.X3DSensorNode,function(ctx){x3dom.nodeTypes.TimeSensor.superClass.call(this,ctx);ctx.doc._nodeBag.timer.push(this);this.addField_SFTime(ctx,'cycleInterval',1);this.addField_SFBool(ctx,'enabled',true);this.addField_SFBool(ctx,'loop',false);this.addField_SFTime(ctx,'startTime',0);this.addField_SFTime(ctx,'stopTime',0);this.addField_SFTime(ctx,'pauseTime',0);this.addField_SFTime(ctx,'resumeTime',0);this.addField_SFTime(ctx,'cycleTime',0);this.addField_SFFloat(ctx,'fraction_changed',0);this.addField_SFBool(ctx,'isActive',false);this.addField_SFTime(ctx,'time',0);this.addField_SFBool(ctx,'first',true);this.addField_SFFloat(ctx,'firstCycle',0.0);this._prevCycle=-1;},{onframe:function(ts)
{if(!this._vf.enabled){return;}
var doRun=(ts>=this._vf.startTime);var doPaused=(ts>=this._vf.pauseTime)&&(this._vf.pauseTime>this._vf.resumeTime);var cycleFrac,cycle,fraction,elapsed;var isActive=(ts>=this._vf.startTime);if(isActive&&this._vf.cycleInterval>0){cycleFrac=(ts-this._vf.startTime)/this._vf.cycleInterval;cycle=Math.floor(cycleFrac);if(this._vf.first==true){firstCycle=cycle;}
this._vf.first=false;if(((cycle-firstCycle)>0)&&(this._vf.loop==false)){fraction=1.0;}else{fraction=cycleFrac-cycle;if(fraction<x3dom.fields.Eps){if(ts>this._vf.startTime){fraction=1.0;}}}}
if(isActive){if(!this._vf.isActive){this.postMessage('isActive',true);}
this.postMessage('fraction_changed',fraction);this.postMessage('time',ts);if(this._prevCycle!=cycle){this._prevCycle=cycle;this.postMessage('cycleTime',ts);if(!this._vf.loop){this.postMessage('isActive',false);}
return;}}},fieldChanged:function(fieldName)
{if(fieldName=="enabled"){if(!this._vf.enabled&&this._vf.isActive){this.postMessage('isActive',false);}}},parentRemoved:function(parent)
{if(this._parentNodes.length===0){var doc=this.findX3DDoc();for(var i=0,n=doc._nodeBag.timer.length;i<n;i++){if(doc._nodeBag.timer[i]===this){doc._nodeBag.timer.splice(i,1);}}}}}));x3dom.registerNodeType("X3DTimeDependentNode","Time",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DTimeDependentNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'loop',false);}));x3dom.registerNodeType("Anchor","Networking",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Anchor.superClass.call(this,ctx);this.addField_MFString(ctx,'url',[]);},{doIntersect:function(line){var isect=false;for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){isect=this._childNodes[i].doIntersect(line)||isect;}}
return isect;},handleTouch:function(){window.location=this._nameSpace.getURL(this._vf.url[0]);}}));x3dom.registerNodeType("Inline","Networking",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Inline.superClass.call(this,ctx);this.addField_MFString(ctx,'url',[]);this.addField_SFBool(ctx,'load',true);this.addField_MFString(ctx,'nameSpaceName',[]);this.addField_SFBool(ctx,'mapDEFToID',false);this.currentInline=ctx.xmlNode;},{fieldChanged:function(fieldName)
{if(fieldName=="url"){var xhr=this.nodeChanged();xhr=null;}},nodeChanged:function()
{var that=this;var xhr=new window.XMLHttpRequest();if(xhr.overrideMimeType){xhr.overrideMimeType('text/xml');}
this._nameSpace.doc.downloadCount+=1;xhr.onreadystatechange=function(){if(xhr.readyState==4){delete xhr['onreadystatechange'];if(navigator.appName!="Microsoft Internet Explorer"){if(xhr.responseXML.documentElement.localName=='parsererror'){that._nameSpace.doc.downloadCount-=1;x3dom.debug.logError('XML parser failed on '+that._vf.url+':\n'+xhr.responseXML.documentElement.textContent);return xhr;}}}else{return xhr;}
if(xhr.status!==200){that._nameSpace.doc.downloadCount-=1;x3dom.debug.logError('XMLHttpRequest requires a web server running!');return xhr;}
x3dom.debug.logInfo('Inline: downloading '+that._vf.url+' done.');if(navigator.appName!="Microsoft Internet Explorer"){var xml=xhr.responseXML;}else{var xml=new DOMParser().parseFromString(xhr.responseText,"text/xml");}
var inlScene=xml.getElementsByTagName('Scene')[0]||xml.getElementsByTagName('scene')[0];var newScene;var nameSpace;if(inlScene){nameSpace=new x3dom.NodeNameSpace("",that._nameSpace.doc);nameSpace.setBaseURL(that._vf.url[0]);newScene=nameSpace.setupTree(inlScene);if(that._vf.nameSpaceName.length!=0){Array.forEach(inlScene.childNodes,function(childDomNode){if(childDomNode instanceof Element){setNamespace(that._vf.nameSpaceName,childDomNode,that._vf.mapDEFToID);that.currentInline.appendChild(childDomNode);}});}}else{x3dom.debug.logWarning('no Scene in '+xml.localName);}
var global=x3dom.getGlobal();while(that._childNodes.length!==0){global['_remover']=that.removeChild(that._childNodes[0]);}
delete global['_remover'];that.addChild(newScene);that._nameSpace.doc.downloadCount-=1;that._nameSpace.doc.needRender=true;x3dom.debug.logInfo('Inline: added '+that._vf.url+' to scene.');newScene=null;nameSpace=null;xml=null;inlScene=null;};xhr.open('GET',encodeURI(this._nameSpace.getURL(this._vf.url[0])),true);xhr.send(null);return xhr;}}));function setNamespace(prefix,childDomNode,mapDEFToID){if(childDomNode instanceof Element){if(childDomNode.hasAttribute('id')){childDomNode.setAttribute('id',prefix.toString().replace(' ','')+'__'+childDomNode.getAttribute('id'));}else if(childDomNode.hasAttribute('DEF')&&mapDEFToID){childDomNode.setAttribute('id',prefix.toString().replace(' ','')+'__'+childDomNode.getAttribute('DEF'));}}
if(childDomNode.hasChildNodes()){Array.forEach(childDomNode.childNodes,function(children){setNamespace(prefix,children,mapDEFToID);});}}
x3dom.registerNodeType("X3DBackgroundNode","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DBackgroundNode.superClass.call(this,ctx);this._dirty=true;},{getSkyColor:function(){return new x3dom.fields.SFColor(0,0,0);},getTransparency:function(){return 0;},getTexUrl:function(){return[];}}));x3dom.registerNodeType("X3DFogNode","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DFogNode.superClass.call(this,ctx);},{}));x3dom.registerNodeType("Fog","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DFogNode,function(ctx){x3dom.nodeTypes.Fog.superClass.call(this,ctx);this.addField_SFColor(ctx,'color',1,1,1);this.addField_SFString(ctx,'fogType',"LINEAR");this.addField_SFFloat(ctx,'visibilityRange',0);},{}));x3dom.registerNodeType("Background","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBackgroundNode,function(ctx){x3dom.nodeTypes.Background.superClass.call(this,ctx);var trans=ctx.autoGen?1:0;this.addField_MFColor(ctx,'skyColor',[new x3dom.fields.SFColor(0,0,0)]);this.addField_MFFloat(ctx,'skyAngle',[]);this.addField_MFColor(ctx,'groundColor',[]);this.addField_MFFloat(ctx,'groundAngle',[]);this.addField_SFFloat(ctx,'transparency',trans);this.addField_MFString(ctx,'backUrl',[]);this.addField_MFString(ctx,'bottomUrl',[]);this.addField_MFString(ctx,'frontUrl',[]);this.addField_MFString(ctx,'leftUrl',[]);this.addField_MFString(ctx,'rightUrl',[]);this.addField_MFString(ctx,'topUrl',[]);},{fieldChanged:function(fieldName)
{if(fieldName.indexOf("Url")>0){this._dirty=true;}
else if(fieldName==="set_bind"){this.bind(this._vf.set_bind);}},getSkyColor:function(){return this._vf.skyColor;},getGroundColor:function(){return this._vf.groundColor;},getTransparency:function(){return this._vf.transparency;},getTexUrl:function(){return[this._nameSpace.getURL(this._vf.backUrl[0]),this._nameSpace.getURL(this._vf.frontUrl[0]),this._nameSpace.getURL(this._vf.bottomUrl[0]),this._nameSpace.getURL(this._vf.topUrl[0]),this._nameSpace.getURL(this._vf.leftUrl[0]),this._nameSpace.getURL(this._vf.rightUrl[0])];}}));x3dom.registerNodeType("X3DViewpointNode","Navigation",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DViewpointNode.superClass.call(this,ctx);},{}));x3dom.registerNodeType("X3DNavigationInfoNode","Navigation",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DNavigationInfoNode.superClass.call(this,ctx);},{}));x3dom.registerNodeType("Viewpoint","Navigation",defineClass(x3dom.nodeTypes.X3DViewpointNode,function(ctx){x3dom.nodeTypes.Viewpoint.superClass.call(this,ctx);this.addField_SFFloat(ctx,'fieldOfView',0.785398);this.addField_SFVec3f(ctx,'position',0,0,10);this.addField_SFRotation(ctx,'orientation',0,0,0,1);this.addField_SFVec3f(ctx,'centerOfRotation',0,0,0);this.addField_SFFloat(ctx,'zNear',0.1);this.addField_SFFloat(ctx,'zFar',100000);this._viewMatrix=x3dom.fields.SFMatrix4f.translation(this._vf.position).mult(this._vf.orientation.toMatrix()).inverse();this._projMatrix=null;this._lastAspect=1.0;},{fieldChanged:function(fieldName){if(fieldName=="position"||fieldName=="orientation"){this.resetView();}
else if(fieldName=="fieldOfView"||fieldName=="zNear"||fieldName=="zFar"){this._projMatrix=null;}
else if(fieldName==="set_bind"){this.bind(this._vf.set_bind);}},activate:function(prev){if(prev){this._nameSpace.doc._viewarea.animateTo(this,prev);}
x3dom.nodeTypes.X3DViewpointNode.prototype.activate.call(this,prev);this._nameSpace.doc._viewarea._needNavigationMatrixUpdate=true;},deactivate:function(prev){x3dom.nodeTypes.X3DViewpointNode.prototype.deactivate.call(this,prev);},getCenterOfRotation:function(){return this._vf.centerOfRotation;},getViewMatrix:function(){return this._viewMatrix;},getFieldOfView:function(){return this._vf.fieldOfView;},setView:function(newView){var mat=this.getCurrentTransform();mat=mat.inverse();this._viewMatrix=mat.mult(newView);},resetView:function(){this._viewMatrix=x3dom.fields.SFMatrix4f.translation(this._vf.position).mult(this._vf.orientation.toMatrix()).inverse();},getTransformation:function(){return this.getCurrentTransform();},getProjectionMatrix:function(aspect)
{if(this._projMatrix==null)
{var fovy=this._vf.fieldOfView;var zfar=this._vf.zFar;var znear=this._vf.zNear;var f=1/Math.tan(fovy/2);this._projMatrix=new x3dom.fields.SFMatrix4f(f/aspect,0,0,0,0,f,0,0,0,0,(znear+zfar)/(znear-zfar),2*znear*zfar/(znear-zfar),0,0,-1,0);this._lastAspect=aspect;}
else if(this._lastAspect!==aspect)
{this._projMatrix._00=(1/Math.tan(this._vf.fieldOfView/2))/aspect;this._lastAspect=aspect;}
return this._projMatrix;}}));x3dom.registerNodeType("NavigationInfo","Navigation",defineClass(x3dom.nodeTypes.X3DNavigationInfoNode,function(ctx){x3dom.nodeTypes.NavigationInfo.superClass.call(this,ctx);this.addField_SFBool(ctx,'headlight',true);this.addField_MFString(ctx,'type',["EXAMINE","ANY"]);this.addField_MFFloat(ctx,'avatarSize',[0.25,1.6,0.75]);this.addField_SFFloat(ctx,'speed',1.0);this.addField_SFFloat(ctx,'visibilityLimit',0.0);this.addField_SFTime(ctx,'transitionTime',1.0);this.addField_MFString(ctx,'transitionType',["LINEAR"]);x3dom.debug.logInfo("NavType: "+this._vf.type[0].toLowerCase());},{fieldChanged:function(fieldName){},getType:function(){return this._vf.type[0].toLowerCase();},setType:function(type,viewarea){var navType=type.toLowerCase();switch(navType){case'game':if(this._vf.type[0].toLowerCase()!==navType){if(viewarea)
viewarea.initMouseState();else
this._nameSpace.doc._viewarea.initMouseState();}
break;default:break;}
this._vf.type[0]=navType;x3dom.debug.logInfo("Switch to "+navType+" mode.");}}));x3dom.registerNodeType("Billboard","Navigation",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Billboard.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'axisOfRotation',0,1,0);this._eye=new x3dom.fields.SFVec3f(0,0,0);this._eyeViewUp=new x3dom.fields.SFVec3f(0,0,0);this._eyeLook=new x3dom.fields.SFVec3f(0,0,0);this._viewAlignedMat=x3dom.fields.SFMatrix4f.identity();},{collectDrawableObjects:function(transform,out)
{if(!this._vf.render){return;}
var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var ok=this.getVolume(min,max,true);var rotMat=x3dom.fields.SFMatrix4f.identity();var mid=(max.add(min).multiply(0.5)).add(new x3dom.fields.SFVec3f(0,0,0));var billboard_to_viewer=this._eye.subtract(mid);if(this._vf.axisOfRotation.equals(new x3dom.fields.SFVec3f(0,0,0),x3dom.fields.Eps)){var rot1=x3dom.fields.Quaternion.rotateFromTo(billboard_to_viewer,new x3dom.fields.SFVec3f(0,0,1));rotMat=rot1.toMatrix().transpose();var yAxis=rotMat.multMatrixPnt(new x3dom.fields.SFVec3f(0,1,0)).normalize();var zAxis=rotMat.multMatrixPnt(new x3dom.fields.SFVec3f(0,0,1)).normalize();if(!this._eyeViewUp.equals(new x3dom.fields.SFVec3f(0,0,0),x3dom.fields.Eps)){var rot2=x3dom.fields.Quaternion.rotateFromTo(this._eyeLook,zAxis);var rotatedyAxis=rot2.toMatrix().transpose().multMatrixVec(yAxis);var rot3=x3dom.fields.Quaternion.rotateFromTo(this._eyeViewUp,rotatedyAxis);rotMat=rot2.toMatrix().transpose().mult(rotMat);rotMat=rot3.toMatrix().transpose().mult(rotMat);}}
else{var normalPlane=this._vf.axisOfRotation.cross(billboard_to_viewer);normalPlane=normalPlane.normalize();if(this._eye.z<0){normalPlane=normalPlane.multiply(-1);}
var degreesToRotate=Math.asin(normalPlane.dot(new x3dom.fields.SFVec3f(0,0,1)));if(this._eye.z<0){degreesToRotate+=Math.PI;}
rotMat=x3dom.fields.SFMatrix4f.parseRotation(this._vf.axisOfRotation.x+", "+this._vf.axisOfRotation.y+", "+this._vf.axisOfRotation.z+", "+degreesToRotate*(-1));}
for(var i=0;i<this._childNodes.length;i++){if(this._childNodes[i]){var childTransform=this._childNodes[i].transformMatrix(transform.mult(rotMat));this._childNodes[i].collectDrawableObjects(childTransform,out);}}
if(out!==null){out.Billboards.push([transform,this]);}}}));x3dom.registerNodeType("Collision","Navigation",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Collision.superClass.call(this,ctx);this.addField_SFBool(ctx,"enabled",true);this.addField_SFNode("proxy",x3dom.nodeTypes.X3DGroupingNode);},{collectDrawableObjects:function(transform,out)
{for(var i=0;i<this._childNodes.length;i++)
{if(this._childNodes[i]&&(this._childNodes[i]!==this._cf.proxy.node))
{var childTransform=this._childNodes[i].transformMatrix(transform);this._childNodes[i].collectDrawableObjects(childTransform,out);}}}}));x3dom.registerNodeType("LOD","Navigation",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.LOD.superClass.call(this,ctx);this.addField_SFBool(ctx,"forceTransitions",false);this.addField_SFVec3f(ctx,'center',0,0,0);this.addField_MFFloat(ctx,"range",[]);this._eye=new x3dom.fields.SFVec3f(0,0,0);},{collectDrawableObjects:function(transform,out)
{var i=0,n=this._childNodes.length;var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var ok=this.getVolume(min,max,true);var mid=(max.add(min).multiply(0.5)).add(this._vf.center);var len=mid.subtract(this._eye).length();while(i<this._vf.range.length&&len>this._vf.range[i]){i++;}
if(i&&i>=n){i=n-1;}
if(n&&this._childNodes[i])
{var childTransform=this._childNodes[i].transformMatrix(transform);this._childNodes[i].collectDrawableObjects(childTransform,out);}
if(out!==null)
{out.LODs.push([transform,this]);}}}));x3dom.registerNodeType("Text","Text",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Text.superClass.call(this,ctx);this.addField_MFString(ctx,'string',[]);this.addField_MFFloat(ctx,'length',[]);this.addField_SFFloat(ctx,'maxExtent',0.0);this.addField_SFNode('fontStyle',x3dom.nodeTypes.X3DFontStyleNode);},{nodeChanged:function(){if(!this._cf.fontStyle.node){this.addChild(x3dom.nodeTypes.FontStyle.defaultNode());}},fieldChanged:function(fieldName){if(fieldName=='string'||fieldName=='family'||fieldName=='horizontal'||fieldName=='justify'||fieldName=='language'||fieldName=='leftToRight'||fieldName=='size'||fieldName=='spacing'||fieldName=='style'||fieldName=='topToBottom'){Array.forEach(this._parentNodes,function(node){node._dirty.texture=true;node._dirty.text=true;});}}}));x3dom.registerNodeType("X3DFontStyleNode","Text",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DFontStyleNode.superClass.call(this,ctx);}));x3dom.registerNodeType("FontStyle","Text",defineClass(x3dom.nodeTypes.X3DFontStyleNode,function(ctx){x3dom.nodeTypes.FontStyle.superClass.call(this,ctx);this.addField_MFString(ctx,'family',['SERIF']);this.addField_SFBool(ctx,'horizontal',true);this.addField_MFString(ctx,'justify',['BEGIN']);this.addField_SFString(ctx,'language',"");this.addField_SFBool(ctx,'leftToRight',true);this.addField_SFFloat(ctx,'size',1.0);this.addField_SFFloat(ctx,'spacing',1.0);this.addField_SFString(ctx,'style',"PLAIN");this.addField_SFBool(ctx,'topToBottom',true);},{nodeChanged:function(){},fieldChanged:function(fieldName){if(fieldName=='family'||fieldName=='horizontal'||fieldName=='justify'||fieldName=='language'||fieldName=='leftToRight'||fieldName=='size'||fieldName=='spacing'||fieldName=='style'||fieldName=='topToBottom'){Array.forEach(this._parentNodes,function(node){node.fieldChanged(fieldName);});}}}));x3dom.nodeTypes.FontStyle.defaultNode=function(){if(!x3dom.nodeTypes.FontStyle._defaultNode){x3dom.nodeTypes.FontStyle._defaultNode=new x3dom.nodeTypes.FontStyle();x3dom.nodeTypes.FontStyle._defaultNode.nodeChanged();}
return x3dom.nodeTypes.FontStyle._defaultNode;};x3dom.registerNodeType("X3DSoundNode","Sound",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DSoundNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Sound","Sound",defineClass(x3dom.nodeTypes.X3DSoundNode,function(ctx){x3dom.nodeTypes.Sound.superClass.call(this,ctx);this.addField_SFNode('source',x3dom.nodeTypes.X3DSoundSourceNode);},{nodeChanged:function()
{if(this._cf.source.node||!this._xmlNode){return;}
x3dom.debug.logInfo("No AudioClip child node given, searching for &lt;audio&gt; elements...");var that=this;try{Array.forEach(this._xmlNode.childNodes,function(childDomNode){if(childDomNode.nodeType===1)
{x3dom.debug.logInfo("### Found &lt;"+childDomNode.nodeName+"&gt; tag.");if(childDomNode.localName.toLowerCase()==="audio")
{var loop=childDomNode.getAttribute("loop");loop=loop?(loop.toLowerCase()==="loop"):false;var newNode=childDomNode.cloneNode(false);childDomNode.parentNode.removeChild(childDomNode);childDomNode=null;if(navigator.appName!="Microsoft Internet Explorer"){document.body.appendChild(newNode);}
var startAudio=function(){newNode.play();};var audioDone=function(){if(loop){newNode.play();}};newNode.addEventListener("canplaythrough",startAudio,true);newNode.addEventListener("ended",audioDone,true);}}});}
catch(e){}}}));x3dom.registerNodeType("X3DSoundSourceNode","Sound",defineClass(x3dom.nodeTypes.X3DTimeDependentNode,function(ctx){x3dom.nodeTypes.X3DSoundSourceNode.superClass.call(this,ctx);}));x3dom.registerNodeType("AudioClip","Sound",defineClass(x3dom.nodeTypes.X3DSoundSourceNode,function(ctx){x3dom.nodeTypes.AudioClip.superClass.call(this,ctx);this.addField_MFString(ctx,'url',[]);this.addField_SFBool(ctx,'enabled',true);this.addField_SFBool(ctx,'loop',false);this._audio=null;},{nodeChanged:function()
{this._audio=document.createElement('audio');this._audio.setAttribute('autobuffer','true');if(navigator.appName!="Microsoft Internet Explorer"){document.body.appendChild(this._audio);}
for(var i=0;i<this._vf.url.length;i++)
{var audioUrl=this._nameSpace.getURL(this._vf.url[i]);x3dom.debug.logInfo('Adding sound file: '+audioUrl);var src=document.createElement('source');src.setAttribute('src',audioUrl);this._audio.appendChild(src);}
var that=this;var startAudio=function()
{that._audio.play();};var audioDone=function()
{if(that._vf.loop===true)
{that._audio.play();}};this._audio.addEventListener("canplaythrough",startAudio,true);this._audio.addEventListener("ended",audioDone,true);},fieldChanged:function(fieldName)
{if(fieldName==="enabled")
{if(this._vf.enabled===true)
{this._audio.play();}
else
{this._audio.pause();}}
else if(fieldName==="loop")
{if(this._vf.loop===true)
{this._audio.play();}}
else if(fieldName==="url")
{this._audio.pause();while(this._audio.hasChildNodes())
{this._audio.removeChild(this._audio.firstChild);}
for(var i=0;i<this._vf.url.length;i++)
{var audioUrl=this._nameSpace.getURL(this._vf.url[i]);x3dom.debug.logInfo('Adding sound file: '+audioUrl);var src=document.createElement('source');src.setAttribute('src',audioUrl);this._audio.appendChild(src);}}}}));x3dom.registerNodeType("X3DTextureTransformNode","Texturing",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.X3DTextureTransformNode.superClass.call(this,ctx);}));x3dom.registerNodeType("TextureTransform","Texturing",defineClass(x3dom.nodeTypes.X3DTextureTransformNode,function(ctx){x3dom.nodeTypes.TextureTransform.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'center',0,0);this.addField_SFFloat(ctx,'rotation',0);this.addField_SFVec2f(ctx,'scale',1,1);this.addField_SFVec2f(ctx,'translation',0,0);var negCenter=new x3dom.fields.SFVec3f(-this._vf.center.x,-this._vf.center.y,1);var posCenter=new x3dom.fields.SFVec3f(this._vf.center.x,this._vf.center.y,0);var trans3=new x3dom.fields.SFVec3f(this._vf.translation.x,this._vf.translation.y,0);var scale3=new x3dom.fields.SFVec3f(this._vf.scale.x,this._vf.scale.y,0);this._trafo=x3dom.fields.SFMatrix4f.translation(negCenter).mult(x3dom.fields.SFMatrix4f.scale(scale3)).mult(x3dom.fields.SFMatrix4f.rotationZ(this._vf.rotation)).mult(x3dom.fields.SFMatrix4f.translation(posCenter.add(trans3)));},{fieldChanged:function(fieldName){var negCenter=new x3dom.fields.SFVec3f(-this._vf.center.x,-this._vf.center.y,1);var posCenter=new x3dom.fields.SFVec3f(this._vf.center.x,this._vf.center.y,0);var trans3=new x3dom.fields.SFVec3f(this._vf.translation.x,this._vf.translation.y,0);var scale3=new x3dom.fields.SFVec3f(this._vf.scale.x,this._vf.scale.y,0);this._trafo=x3dom.fields.SFMatrix4f.translation(negCenter).mult(x3dom.fields.SFMatrix4f.scale(scale3)).mult(x3dom.fields.SFMatrix4f.rotationZ(this._vf.rotation)).mult(x3dom.fields.SFMatrix4f.translation(posCenter.add(trans3)));},texTransformMatrix:function(){return this._trafo;}}));x3dom.registerNodeType("TextureProperties","Texturing",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.TextureProperties.superClass.call(this,ctx);this.addField_SFFloat(ctx,'anisotropicDegree',1.0);this.addField_SFColorRGBA(ctx,'borderColor',0,0,0,0);this.addField_SFInt32(ctx,'borderWidth',0);this.addField_SFString(ctx,'boundaryModeS',"REPEAT");this.addField_SFString(ctx,'boundaryModeT',"REPEAT");this.addField_SFString(ctx,'boundaryModeR',"REPEAT");this.addField_SFString(ctx,'magnificationFilter',"FASTEST");this.addField_SFString(ctx,'minificationFilter',"FASTEST");this.addField_SFString(ctx,'textureCompression',"FASTEST");this.addField_SFFloat(ctx,'texturePriority',0);this.addField_SFBool(ctx,'generateMipMaps',false);}));x3dom.registerNodeType("X3DTextureNode","Texturing",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.X3DTextureNode.superClass.call(this,ctx);this.addField_SFInt32(ctx,'origChannelCount',0);this.addField_MFString(ctx,'url',[]);this.addField_SFBool(ctx,'repeatS',true);this.addField_SFBool(ctx,'repeatT',true);this.addField_SFNode('textureProperties',x3dom.nodeTypes.TextureProperties);this.addField_SFBool(ctx,'scale',true);this.addField_SFInt32(ctx,'priority',10);this._needPerFrameUpdate=false;this._isCanvas=false;},{invalidateGLObject:function()
{Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.texture=true;});});this._nameSpace.doc.needRender=true;},parentAdded:function(parent)
{Array.forEach(parent._parentNodes,function(shape){shape._dirty.texture=true;});},parentRemoved:function(parent)
{parent._cf.texture.node=null;Array.forEach(parent._parentNodes,function(shape){shape._dirty.texture=true;});},nodeChanged:function()
{},fieldChanged:function(fieldName)
{if(fieldName=="url")
{this._complete=false;Array.forEach(this._parentNodes,function(app){app.nodeChanged();Array.forEach(app._parentNodes,function(shape){shape._dirty.texture=true;});});}},getTexture:function(pos){if(pos===0){return this;}
return null;},size:function(){return 1;}}));x3dom.registerNodeType("MultiTexture","Texturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.MultiTexture.superClass.call(this,ctx);this.addField_MFNode('texture',x3dom.nodeTypes.X3DTextureNode);},{getTexture:function(pos){if(pos>=0&&pos<this._cf.texture.nodes.length){return this._cf.texture.nodes[pos];}
return null;},size:function(){return this._cf.texture.nodes.length;}}));x3dom.registerNodeType("Texture","Texturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.Texture.superClass.call(this,ctx);this.addField_SFBool(ctx,'hideChildren',true);this._video=null;this._intervalID=0;this._canvas=null;},{nodeChanged:function()
{if(this._vf.url.length||!this._xmlNode){return;}
x3dom.debug.logInfo("No Texture URL given, searching for &lt;img&gt; elements...");var that=this;try{Array.forEach(this._xmlNode.childNodes,function(childDomNode){if(childDomNode.nodeType===1){var url=childDomNode.getAttribute("src");if(url){that._vf.url.push(url);x3dom.debug.logInfo(that._vf.url[that._vf.url.length-1]);if(childDomNode.localName==="video"){that._needPerFrameUpdate=true;that._video=document.createElement('video');that._video.setAttribute('autobuffer','true');var p=document.getElementsByTagName('body')[0];p.appendChild(that._video);that._video.style.display="none";}}
else if(childDomNode.localName.toLowerCase()==="canvas"){that._needPerFrameUpdate=true;that._isCanvas=true;that._canvas=childDomNode;}
if(that._vf.hideChildren){childDomNode.style.display="none";childDomNode.style.visibility="hidden";}
x3dom.debug.logInfo("### Found &lt;"+childDomNode.nodeName+"&gt; tag.");}});}
catch(e){}}}));x3dom.registerNodeType("RenderedTexture","Texturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.RenderedTexture.superClass.call(this,ctx);ctx.doc._nodeBag.renderTextures.push(this);this.addField_SFNode('viewpoint',x3dom.nodeTypes.X3DViewpointNode);this.addField_SFNode('background',x3dom.nodeTypes.X3DBackgroundNode);this.addField_SFNode('fog',x3dom.nodeTypes.X3DFogNode);this.addField_SFNode('scene',x3dom.nodeTypes.X3DNode);this.addField_MFNode('excludeNodes',x3dom.nodeTypes.X3DNode);this.addField_MFInt32(ctx,'dimensions',[128,128,4]);this.addField_SFString(ctx,'update','NONE');x3dom.debug.assert(this._vf.dimensions.length>=3);this._clearParents=true;},{nodeChanged:function()
{this._clearParents=true;},fieldChanged:function(fieldName)
{if(fieldName=="excludeNodes"){this._clearParents=true;}},getViewMatrix:function()
{if(this._clearParents&&this._cf.excludeNodes.nodes.length){var that=this;Array.forEach(this._cf.excludeNodes.nodes,function(node){for(var i=0,n=node._parentNodes.length;i<n;i++){if(node._parentNodes[i]===that){node._parentNodes.splice(i,1);node.parentRemoved(that);}}});this._clearParents=false;}
var vbP=this._nameSpace.doc._scene.getViewpoint();var view=this._cf.viewpoint.node;if(view===null||view===vbP){return this._nameSpace.doc._viewarea.getViewMatrix();}
else{var mat_viewpoint=view.getCurrentTransform();return mat_viewpoint.mult(view.getViewMatrix());}},getProjectionMatrix:function()
{var vbP=this._nameSpace.doc._scene.getViewpoint();var view=this._cf.viewpoint.node;if(view===null||view===vbP){return this._nameSpace.doc._viewarea.getProjectionMatrix();}
else{var w=this._vf.dimensions[0],h=this._vf.dimensions[1];return view.getProjectionMatrix(w/h);}},getWCtoCCMatrix:function()
{var view=this.getViewMatrix();var proj=this.getProjectionMatrix();return proj.mult(view);},parentRemoved:function(parent)
{if(this._parentNodes.length===0){var doc=this.findX3DDoc();for(var i=0,n=doc._nodeBag.renderTextures.length;i<n;i++){if(doc._nodeBag.renderTextures[i]===this){doc._nodeBag.renderTextures.splice(i,1);}}}
if(this._cf.scene.node){this._cf.scene.node.parentRemoved(this);}}}));x3dom.registerNodeType("PixelTexture","Texturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.PixelTexture.superClass.call(this,ctx);this.addField_SFImage(ctx,'image',0,0,0);},{fieldChanged:function(fieldName)
{if(fieldName=="image"){this.invalidateGLObject();}}}));x3dom.registerNodeType("ImageTexture","Texturing",defineClass(x3dom.nodeTypes.Texture,function(ctx){x3dom.nodeTypes.ImageTexture.superClass.call(this,ctx);},{}));x3dom.registerNodeType("MovieTexture","Texturing",defineClass(x3dom.nodeTypes.Texture,function(ctx){x3dom.nodeTypes.MovieTexture.superClass.call(this,ctx);this.addField_SFBool(ctx,'loop',false);this.addField_SFFloat(ctx,'speed',1.0);},{}));x3dom.registerNodeType("X3DEnvironmentTextureNode","CubeMapTexturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.X3DEnvironmentTextureNode.superClass.call(this,ctx);},{getTexUrl:function(){return[];},getTexSize:function(){return-1;}}));x3dom.registerNodeType("ComposedCubeMapTexture","CubeMapTexturing",defineClass(x3dom.nodeTypes.X3DEnvironmentTextureNode,function(ctx){x3dom.nodeTypes.ComposedCubeMapTexture.superClass.call(this,ctx);this.addField_SFNode('back',x3dom.nodeTypes.Texture);this.addField_SFNode('front',x3dom.nodeTypes.Texture);this.addField_SFNode('bottom',x3dom.nodeTypes.Texture);this.addField_SFNode('top',x3dom.nodeTypes.Texture);this.addField_SFNode('left',x3dom.nodeTypes.Texture);this.addField_SFNode('right',x3dom.nodeTypes.Texture);},{getTexUrl:function(){return[this._nameSpace.getURL(this._cf.back.node._vf.url[0]),this._nameSpace.getURL(this._cf.front.node._vf.url[0]),this._nameSpace.getURL(this._cf.bottom.node._vf.url[0]),this._nameSpace.getURL(this._cf.top.node._vf.url[0]),this._nameSpace.getURL(this._cf.left.node._vf.url[0]),this._nameSpace.getURL(this._cf.right.node._vf.url[0])];}}));x3dom.registerNodeType("GeneratedCubeMapTexture","CubeMapTexturing",defineClass(x3dom.nodeTypes.X3DEnvironmentTextureNode,function(ctx){x3dom.nodeTypes.GeneratedCubeMapTexture.superClass.call(this,ctx);this.addField_SFInt32(ctx,'size',128);this.addField_SFString(ctx,'update','NONE');x3dom.debug.logWarning("GeneratedCubeMapTexture NYI");},{getTexSize:function(){return this._vf.size;}}));x3dom.registerNodeType("X3DTextureCoordinateNode","Texturing",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.X3DTextureCoordinateNode.superClass.call(this,ctx);},{fieldChanged:function(fieldName){Array.forEach(this._parentNodes,function(node){node.fieldChanged("texCoord");});},parentAdded:function(parent){if(parent._mesh&&parent._cf.texCoord.node!==this){parent.fieldChanged("texCoord");}}}));x3dom.registerNodeType("TextureCoordinate3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTextureCoordinateNode,function(ctx){x3dom.nodeTypes.TextureCoordinate3D.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'point',[]);}));x3dom.registerNodeType("TextureCoordinate","Texturing",defineClass(x3dom.nodeTypes.X3DTextureCoordinateNode,function(ctx){x3dom.nodeTypes.TextureCoordinate.superClass.call(this,ctx);this.addField_MFVec2f(ctx,'point',[]);}));x3dom.registerNodeType("TextureCoordinateGenerator","Texturing",defineClass(x3dom.nodeTypes.X3DTextureCoordinateNode,function(ctx){x3dom.nodeTypes.TextureCoordinateGenerator.superClass.call(this,ctx);this.addField_SFString(ctx,'mode',"SPHERE");this.addField_MFFloat(ctx,'parameter',[]);}));x3dom.registerNodeType("Uniform","Shaders",defineClass(x3dom.nodeTypes.Field,function(ctx){x3dom.nodeTypes.Uniform.superClass.call(this,ctx);}));x3dom.registerNodeType("SurfaceShaderTexture","Shaders",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.SurfaceShaderTexture.superClass.call(this,ctx);this.addField_SFInt32(ctx,'textureCoordinatesId',0);this.addField_SFString(ctx,'channelMask',"DEFAULT");this.addField_SFBool(ctx,'isSRGB',false);this.addField_SFNode('texture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('textureTransform',x3dom.nodeTypes.X3DTextureTransformNode);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("X3DShaderNode","Shaders",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.X3DShaderNode.superClass.call(this,ctx);this.addField_SFString(ctx,'language',"");}));x3dom.registerNodeType("CommonSurfaceShader","Shaders",defineClass(x3dom.nodeTypes.X3DShaderNode,function(ctx){x3dom.nodeTypes.CommonSurfaceShader.superClass.call(this,ctx);this.addField_SFInt32(ctx,'tangentTextureCoordinatesId',-1);this.addField_SFInt32(ctx,'binormalTextureCoordinatesId',-1);this.addField_SFVec3f(ctx,'emissiveFactor',0,0,0);this.addField_SFInt32(ctx,'emissiveTextureId',-1);this.addField_SFInt32(ctx,'emissiveTextureCoordinatesId',0);this.addField_SFString(ctx,'emissiveTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'ambientFactor',0.2,0.2,0.2);this.addField_SFInt32(ctx,'ambientTextureId',-1);this.addField_SFInt32(ctx,'ambientTextureCoordinatesId',0);this.addField_SFString(ctx,'ambientTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'diffuseFactor',0.8,0.8,0.8);this.addField_SFInt32(ctx,'diffuseTextureId',-1);this.addField_SFInt32(ctx,'diffuseTextureCoordinatesId',0);this.addField_SFString(ctx,'diffuseTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'specularFactor',0,0,0);this.addField_SFInt32(ctx,'specularTextureId',-1);this.addField_SFInt32(ctx,'specularTextureCoordinatesId',0);this.addField_SFString(ctx,'specularTextureChannelMask','rgb');this.addField_SFFloat(ctx,'shininessFactor',0.2);this.addField_SFInt32(ctx,'shininessTextureId',-1);this.addField_SFInt32(ctx,'shininessTextureCoordinatesId',0);this.addField_SFString(ctx,'shininessTextureChannelMask','a');this.addField_SFString(ctx,'normalFormat','UNORM');this.addField_SFString(ctx,'normalSpace','TANGENT');this.addField_SFInt32(ctx,'normalTextureId',-1);this.addField_SFInt32(ctx,'normalTextureCoordinatesId',0);this.addField_SFString(ctx,'normalTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'reflectionFactor',0,0,0);this.addField_SFInt32(ctx,'reflectionTextureId',-1);this.addField_SFInt32(ctx,'reflectionTextureCoordinatesId',0);this.addField_SFString(ctx,'reflectionTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'transmissionFactor',0,0,0);this.addField_SFInt32(ctx,'transmissionTextureId',-1);this.addField_SFInt32(ctx,'transmissionTextureCoordinatesId',0);this.addField_SFString(ctx,'transmissionTextureChannelMask','rgb');this.addField_SFVec3f(ctx,'environmentFactor',1,1,1);this.addField_SFInt32(ctx,'environmentTextureId',-1);this.addField_SFInt32(ctx,'environmentTextureCoordinatesId',0);this.addField_SFString(ctx,'environmentTextureChannelMask','rgb');this.addField_SFFloat(ctx,'relativeIndexOfRefraction',1);this.addField_SFFloat(ctx,'fresnelBlend',0);this.addField_SFNode('emissiveTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('ambientTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('diffuseTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('specularTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('shininessTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('normalTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('reflectionTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('transmissionTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('environmentTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFVec3f(ctx,'normalScale',2,2,2);this.addField_SFVec3f(ctx,'normalBias',-1,-1,-1);this.addField_SFFloat(ctx,'alphaFactor',1);this.addField_SFBool(ctx,'invertAlphaTexture',false);this.addField_SFInt32(ctx,'alphaTextureId',-1);this.addField_SFInt32(ctx,'alphaTextureCoordinatesId',0);this.addField_SFString(ctx,'alphaTextureChannelMask','a');this.addField_SFNode('alphaTexture',x3dom.nodeTypes.X3DTextureNode);this._dirty={};},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{},getDiffuseMap:function()
{if(this._cf.diffuseTexture.node){return this._cf.diffuseTexture.node._cf.texture.node;}else{return null;}},getNormalMap:function()
{if(this._cf.normalTexture.node){return this._cf.normalTexture.node._cf.texture.node;}else{return null;}},getAmbientMap:function()
{if(this._cf.ambientTexture.node){return this._cf.ambientTexture.node._cf.texture.node;}else{return null;}},getSpecularMap:function()
{if(this._cf.specularTexture.node){return this._cf.specularTexture.node._cf.texture.node;}else{return null;}},getShininessMap:function()
{if(this._cf.shininessTexture.node){return this._cf.shininessTexture.node._cf.texture.node;}else{return null;}},getAlphaMap:function()
{if(this._cf.alphaTexture.node){return this._cf.alphaTexture.node._cf.texture.node;}else{return null;}}}));x3dom.registerNodeType("ComposedShader","Shaders",defineClass(x3dom.nodeTypes.X3DShaderNode,function(ctx){x3dom.nodeTypes.ComposedShader.superClass.call(this,ctx);this.addField_MFNode('fields',x3dom.nodeTypes.Field);this.addField_MFNode('parts',x3dom.nodeTypes.ShaderPart);this._vertex=null;this._fragment=null;x3dom.debug.logInfo("Current ComposedShader node implementation limitations:\n"+"Vertex attributes (if given in the standard X3D fields 'coord', 'color', "+"'normal', 'texCoord'), matrices and texture are provided as follows...\n"+"    attribute vec3 position;\n"+"    attribute vec3 normal;\n"+"    attribute vec2 texcoord;\n"+"    attribute vec3 color;\n"+"    uniform mat4 modelViewProjectionMatrix;\n"+"    uniform mat4 modelViewMatrix;\n"+"    uniform mat4 normalMatrix;\n"+"    uniform mat4 viewMatrix;\n"+"    uniform sampler2D tex;\n");},{nodeChanged:function()
{var i,n=this._cf.parts.nodes.length;for(i=0;i<n;i++)
{if(this._cf.parts.nodes[i]._vf.type.toLowerCase()=='vertex'){this._vertex=this._cf.parts.nodes[i];}
else if(this._cf.parts.nodes[i]._vf.type.toLowerCase()=='fragment'){this._fragment=this._cf.parts.nodes[i];}}
var ctx={};n=this._cf.fields.nodes.length;for(i=0;i<n;i++)
{var fieldName=this._cf.fields.nodes[i]._vf.name;ctx.xmlNode=this._cf.fields.nodes[i]._xmlNode;ctx.xmlNode.setAttribute(fieldName,this._cf.fields.nodes[i]._vf.value);var funcName="this.addField_"+this._cf.fields.nodes[i]._vf.type+"(ctx, name);";var func=new Function('ctx','name',funcName);func.call(this,ctx,fieldName);}
Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.shader=true;});});},fieldChanged:function(fieldName)
{var i,n=this._cf.fields.nodes.length;for(i=0;i<n;i++)
{var field=this._cf.fields.nodes[i]._vf.name;if(field===fieldName)
{var msg=this._cf.fields.nodes[i]._vf.value;try{this._vf[field].setValueByStr(msg);}
catch(exc1){try{switch((typeof(this._vf[field])).toString()){case"number":this._vf[field]=+msg;break;case"boolean":this._vf[field]=(msg.toLowerCase()==="true");break;case"string":this._vf[field]=msg;break;}}
catch(exc2){x3dom.debug.logError("setValueByStr() NYI for "+typeof(this._vf[field]));}}
break;}}},parentAdded:function()
{this._parentNodes[0].nodeChanged();}}));x3dom.registerNodeType("ShaderPart","Shaders",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.ShaderPart.superClass.call(this,ctx);this.addField_MFString(ctx,'url',[]);this.addField_SFString(ctx,'type',"VERTEX");x3dom.debug.assert(this._vf.type.toLowerCase()=='vertex'||this._vf.type.toLowerCase()=='fragment');if(!this._vf.url.length&&ctx.xmlNode){var that=this;try{that._vf.url.push(ctx.xmlNode.childNodes[1].nodeValue);ctx.xmlNode.removeChild(ctx.xmlNode.childNodes[1]);}
catch(e){Array.forEach(ctx.xmlNode.childNodes,function(childDomNode){if(childDomNode.nodeType===4){that._vf.url.push(childDomNode.data);}
childDomNode.parentNode.removeChild(childDomNode);});}}},{nodeChanged:function()
{},fieldChanged:function(fieldName)
{},parentAdded:function()
{this._parentNodes[0].nodeChanged();}}));x3dom.registerNodeType("X3DVertexAttributeNode","Shaders",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.X3DVertexAttributeNode.superClass.call(this,ctx);this.addField_SFString(ctx,'name',"");}));x3dom.registerNodeType("FloatVertexAttribute","Shaders",defineClass(x3dom.nodeTypes.X3DVertexAttributeNode,function(ctx){x3dom.nodeTypes.FloatVertexAttribute.superClass.call(this,ctx);this.addField_SFInt32(ctx,'numComponents',4);this.addField_MFFloat(ctx,'value',[]);},{fieldChanged:function(fieldName){}}));x3dom.registerNodeType("Plane","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Plane.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'size',2,2);this.addField_SFVec2f(ctx,'subdivision',1,1);var sx=this._vf.size.x,sy=this._vf.size.y;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var geoCacheID='Plane_'+sx+'-'+sy+'-'+subx+'-'+suby;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Plane from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var x=0,y=0;var xstep=sx/subx;var ystep=sy/suby;sx/=2;sy/=2;for(y=0;y<=suby;y++){for(x=0;x<=subx;x++){this._mesh._positions[0].push(x*xstep-sx);this._mesh._positions[0].push(y*ystep-sy);this._mesh._positions[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push(x/subx);this._mesh._texCoords[0].push(y/suby);}}
for(y=1;y<=suby;y++){for(x=0;x<subx;x++){this._mesh._indices[0].push((y-1)*(subx+1)+x);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);this._mesh._indices[0].push(y*(subx+1)+x+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){if(fieldName==="size"){this._mesh._positions[0]=[];var sx=this._vf.size.x,sy=this._vf.size.y;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var x=0,y=0;var xstep=sx/subx;var ystep=sy/suby;sx/=2;sy/=2;for(y=0;y<=suby;y++){for(x=0;x<=subx;x++){this._mesh._positions[0].push(x*xstep-sx);this._mesh._positions[0].push(y*ystep-sy);this._mesh._positions[0].push(0);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else if(fieldName==="subdivision"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var sx=this._vf.size.x,sy=this._vf.size.y;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var x=0,y=0;var xstep=sx/subx;var ystep=sy/suby;sx/=2;sy/=2;for(y=0;y<=suby;y++){for(x=0;x<=subx;x++){this._mesh._positions[0].push(x*xstep-sx);this._mesh._positions[0].push(y*ystep-sy);this._mesh._positions[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push(x/subx);this._mesh._texCoords[0].push(y/suby);}}
for(y=1;y<=suby;y++){for(x=0;x<subx;x++){this._mesh._indices[0].push((y-1)*(subx+1)+x);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);this._mesh._indices[0].push(y*(subx+1)+x+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("ElevationGrid","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.ElevationGrid.superClass.call(this,ctx);this.addField_SFBool(ctx,'colorPerVertex',true);this.addField_SFBool(ctx,'normalPerVertex',true);this.addField_SFFloat(ctx,'creaseAngle',0);this.addField_MFNode('attrib',x3dom.nodeTypes.X3DVertexAttributeNode);this.addField_SFNode('normal',x3dom.nodeTypes.Normal);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this.addField_SFNode('texCoord',x3dom.nodeTypes.X3DTextureCoordinateNode);this.addField_MFFloat(ctx,'height',[]);this.addField_SFInt32(ctx,'xDimension',0);this.addField_SFFloat(ctx,'xSpacing',1.0);this.addField_SFInt32(ctx,'zDimension',0);this.addField_SFFloat(ctx,'zSpacing',1.0);},{nodeChanged:function()
{this._mesh._indices[0]=[];this._mesh._positions[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._colors[0]=[];var x=0,y=0;var subx=this._vf.xDimension-1;var suby=this._vf.zDimension-1;var h=this._vf.height;x3dom.debug.assert((h.length===this._vf.xDimension*this._vf.zDimension));var normals=null,texCoords=null,colors=null;if(this._cf.normal.node){normals=this._cf.normal.node._vf.vector;}
var numTexComponents=2;if(this._cf.texCoord.node){if(this._cf.texCoord.node._vf.point){texCoords=this._cf.texCoord.node._vf.point;if(x3dom.isa(this._cf.texCoord.node,x3dom.nodeTypes.TextureCoordinate3D)){numTexComponents=3;}}}
var numColComponents=3;if(this._cf.color.node){colors=this._cf.color.node._vf.color;if(x3dom.isa(this._cf.color.node,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
var c=0;for(y=0;y<=suby;y++)
{for(x=0;x<=subx;x++)
{this._mesh._positions[0].push(x*this._vf.xSpacing);this._mesh._positions[0].push(h[c]);this._mesh._positions[0].push(y*this._vf.zSpacing);if(normals){this._mesh._normals[0].push(normals[c].x);this._mesh._normals[0].push(normals[c].y);this._mesh._normals[0].push(normals[c].z);}
else{}
if(texCoords){this._mesh._texCoords[0].push(texCoords[c].x);this._mesh._texCoords[0].push(texCoords[c].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[c].z);}}
else{this._mesh._texCoords[0].push(x/subx);this._mesh._texCoords[0].push(y/suby);}
if(colors){this._mesh._colors[0].push(colors[c].r);this._mesh._colors[0].push(colors[c].g);this._mesh._colors[0].push(colors[c].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c].a);}}
c++;}}
for(y=1;y<=suby;y++){for(x=0;x<subx;x++){this._mesh._indices[0].push((y-1)*(subx+1)+x);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);this._mesh._indices[0].push(y*(subx+1)+x);this._mesh._indices[0].push(y*(subx+1)+x+1);this._mesh._indices[0].push((y-1)*(subx+1)+x+1);}}
this._mesh.calcNormals(Math.PI);this._mesh._invalidate=true;this._mesh._numTexComponents=numTexComponents;this._mesh._numColComponents=numColComponents;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;},fieldChanged:function(fieldName)
{if(fieldName=="height")
{var i,n=this._mesh._positions[0].length/3;var h=this._vf.height;for(i=0;i<n;i++){this._mesh._positions[0][3*i+1]=h[i];}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}}));x3dom.registerNodeType("Box","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Box.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'size',2,2,2);var sx=this._vf.size.x,sy=this._vf.size.y,sz=this._vf.size.z;var geoCacheID='Box_'+sx+'-'+sy+'-'+sz;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Box from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{sx/=2;sy/=2;sz/=2;this._mesh._positions[0]=[-sx,-sy,-sz,-sx,sy,-sz,sx,sy,-sz,sx,-sy,-sz,-sx,-sy,sz,-sx,sy,sz,sx,sy,sz,sx,-sy,sz,-sx,-sy,-sz,-sx,-sy,sz,-sx,sy,sz,-sx,sy,-sz,sx,-sy,-sz,sx,-sy,sz,sx,sy,sz,sx,sy,-sz,-sx,sy,-sz,-sx,sy,sz,sx,sy,sz,sx,sy,-sz,-sx,-sy,-sz,-sx,-sy,sz,sx,-sy,sz,sx,-sy,-sz];this._mesh._normals[0]=[0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,-1,0,0,-1,0,0,-1,0,0,-1,0];this._mesh._texCoords[0]=[1,0,1,1,0,1,0,0,0,0,0,1,1,1,1,0,0,0,1,0,1,1,0,1,1,0,0,0,0,1,1,1,0,1,0,0,1,0,1,1,0,0,0,1,1,1,1,0];this._mesh._indices[0]=[0,1,2,2,3,0,4,7,5,5,7,6,8,9,10,10,11,8,12,14,13,14,12,15,16,17,18,18,19,16,20,22,21,22,20,23];this._mesh._invalidate=true;this._mesh._numFaces=12;this._mesh._numCoords=24;x3dom.geoCache[geoCacheID]=this._mesh;}},{fieldChanged:function(fieldName){if(fieldName==="size"){var sx=this._vf.size.x/2,sy=this._vf.size.y/2,sz=this._vf.size.z/2;this._mesh._positions[0]=[-sx,-sy,-sz,-sx,sy,-sz,sx,sy,-sz,sx,-sy,-sz,-sx,-sy,sz,-sx,sy,sz,sx,sy,sz,sx,-sy,sz,-sx,-sy,-sz,-sx,-sy,sz,-sx,sy,sz,-sx,sy,-sz,sx,-sy,-sz,sx,-sy,sz,sx,sy,sz,sx,sy,-sz,-sx,sy,-sz,-sx,sy,sz,sx,sy,sz,sx,sy,-sz,-sx,-sy,-sz,-sx,-sy,sz,sx,-sy,sz,sx,-sy,-sz];Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}}));x3dom.registerNodeType("Sphere","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Sphere.superClass.call(this,ctx);this.addField_SFFloat(ctx,'radius',ctx?1:10000);this.addField_SFVec2f(ctx,'subdivision',24,24);var qfactor=1.0;var r=this._vf.radius;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var geoCacheID='Sphere_'+r;if(x3dom.geoCache[geoCacheID]!=undefined){x3dom.debug.logInfo("Using Sphere from Cache");this._mesh=x3dom.geoCache[geoCacheID];}else{if(ctx){qfactor=ctx.doc.properties.getProperty("PrimitiveQuality","Medium");}
if(!x3dom.isNumber(qfactor)){switch(qfactor.toLowerCase()){case"low":qfactor=0.3;break;case"medium":qfactor=0.5;break;case"high":qfactor=1.0;break;}}else{qfactor=parseFloat(qfactor);}
this._quality=qfactor;var latNumber,longNumber;var latitudeBands=Math.floor(subx*qfactor);var longitudeBands=Math.floor(suby*qfactor);var theta,sinTheta,cosTheta;var phi,sinPhi,cosPhi;var x,y,z,u,v;for(latNumber=0;latNumber<=latitudeBands;latNumber++){theta=(latNumber*Math.PI)/latitudeBands;sinTheta=Math.sin(theta);cosTheta=Math.cos(theta);for(longNumber=0;longNumber<=longitudeBands;longNumber++){phi=(longNumber*2.0*Math.PI)/longitudeBands;sinPhi=Math.sin(phi);cosPhi=Math.cos(phi);x=-cosPhi*sinTheta;y=-cosTheta;z=-sinPhi*sinTheta;u=0.25-((1.0*longNumber)/longitudeBands);v=latNumber/latitudeBands;this._mesh._positions[0].push(r*x);this._mesh._positions[0].push(r*y);this._mesh._positions[0].push(r*z);this._mesh._normals[0].push(x);this._mesh._normals[0].push(y);this._mesh._normals[0].push(z);this._mesh._texCoords[0].push(u);this._mesh._texCoords[0].push(v);}}
var first,second;for(latNumber=0;latNumber<latitudeBands;latNumber++){for(longNumber=0;longNumber<longitudeBands;longNumber++){first=(latNumber*(longitudeBands+1))+longNumber;second=first+longitudeBands+1;this._mesh._indices[0].push(first);this._mesh._indices[0].push(second);this._mesh._indices[0].push(first+1);this._mesh._indices[0].push(second);this._mesh._indices[0].push(second+1);this._mesh._indices[0].push(first+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{fieldChanged:function(fieldName){if(fieldName==="radius"){this._mesh._positions[0]=[];this._mesh._normals[0]=[];var r=this._vf.radius;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var qfactor=this._quality;var latNumber,longNumber;var latitudeBands=Math.floor(subx*qfactor);var longitudeBands=Math.floor(suby*qfactor);var theta,sinTheta,cosTheta;var phi,sinPhi,cosPhi;var x,y,z;for(latNumber=0;latNumber<=latitudeBands;latNumber++){theta=(latNumber*Math.PI)/latitudeBands;sinTheta=Math.sin(theta);cosTheta=Math.cos(theta);for(longNumber=0;longNumber<=longitudeBands;longNumber++){phi=(longNumber*2.0*Math.PI)/longitudeBands;sinPhi=Math.sin(phi);cosPhi=Math.cos(phi);x=-cosPhi*sinTheta;y=-cosTheta;z=-sinPhi*sinTheta;this._mesh._positions[0].push(r*x);this._mesh._positions[0].push(r*y);this._mesh._positions[0].push(r*z);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else if(fieldName==="subdivision"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var r=this._vf.radius;var subx=this._vf.subdivision.x,suby=this._vf.subdivision.y;var qfactor=this._quality;var latNumber,longNumber;var latitudeBands=Math.floor(subx*qfactor);var longitudeBands=Math.floor(suby*qfactor);var theta,sinTheta,cosTheta;var phi,sinPhi,cosPhi;var x,y,z,u,v;for(latNumber=0;latNumber<=latitudeBands;latNumber++){theta=(latNumber*Math.PI)/latitudeBands;sinTheta=Math.sin(theta);cosTheta=Math.cos(theta);for(longNumber=0;longNumber<=longitudeBands;longNumber++){phi=(longNumber*2.0*Math.PI)/longitudeBands;sinPhi=Math.sin(phi);cosPhi=Math.cos(phi);x=-cosPhi*sinTheta;y=-cosTheta;z=-sinPhi*sinTheta;u=0.25-((1.0*longNumber)/longitudeBands);v=latNumber/latitudeBands;this._mesh._positions[0].push(r*x);this._mesh._positions[0].push(r*y);this._mesh._positions[0].push(r*z);this._mesh._normals[0].push(x);this._mesh._normals[0].push(y);this._mesh._normals[0].push(z);this._mesh._texCoords[0].push(u);this._mesh._texCoords[0].push(v);}}
var first,second;for(latNumber=0;latNumber<latitudeBands;latNumber++){for(longNumber=0;longNumber<longitudeBands;longNumber++){first=(latNumber*(longitudeBands+1))+longNumber;second=first+longitudeBands+1;this._mesh._indices[0].push(first);this._mesh._indices[0].push(second);this._mesh._indices[0].push(first+1);this._mesh._indices[0].push(second);this._mesh._indices[0].push(second+1);this._mesh._indices[0].push(first+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("Torus","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Torus.superClass.call(this,ctx);this.addField_SFFloat(ctx,'innerRadius',0.5);this.addField_SFFloat(ctx,'outerRadius',1.0);this.addField_SFVec2f(ctx,'subdivision',24,24);var innerRadius=this._vf.innerRadius;var outerRadius=this._vf.outerRadius;var rings=this._vf.subdivision.x,sides=this._vf.subdivision.y;var geoCacheID='Torus_'+innerRadius+'_'+outerRadius;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Torus from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var ringDelta=2.0*Math.PI/rings;var sideDelta=2.0*Math.PI/sides;var p=[],n=[],t=[],i=[];var a,b,theta,phi;for(a=0,theta=0;a<=rings;a++,theta+=ringDelta)
{var cosTheta=Math.cos(theta);var sinTheta=Math.sin(theta);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
{var cosPhi=Math.cos(phi);var sinPhi=Math.sin(phi);var dist=outerRadius+innerRadius*cosPhi;this._mesh._normals[0].push(cosTheta*cosPhi,-sinTheta*cosPhi,sinPhi);this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,innerRadius*sinPhi);this._mesh._texCoords[0].push(-a/rings,b/sides);}}
for(a=0;a<sides;a++)
{for(b=0;b<rings;b++)
{this._mesh._indices[0].push(b*(sides+1)+a);this._mesh._indices[0].push(b*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a);this._mesh._indices[0].push(b*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{fieldChanged:function(fieldName){if(fieldName==="innerRadius"||fieldName==="outerRadius"){this._mesh._positions[0]=[];var innerRadius=this._vf.innerRadius;var outerRadius=this._vf.outerRadius;var rings=this._vf.subdivision.x,sides=this._vf.subdivision.y;var ringDelta=2.0*Math.PI/rings;var sideDelta=2.0*Math.PI/sides;var a,b,theta,phi;for(a=0,theta=0;a<=rings;a++,theta+=ringDelta)
{var cosTheta=Math.cos(theta);var sinTheta=Math.sin(theta);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
{var cosPhi=Math.cos(phi);var sinPhi=Math.sin(phi);var dist=outerRadius+innerRadius*cosPhi;this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,innerRadius*sinPhi);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else if(fieldName==="subdivision"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var innerRadius=this._vf.innerRadius;var outerRadius=this._vf.outerRadius;var rings=this._vf.subdivision.x,sides=this._vf.subdivision.y;var ringDelta=2.0*Math.PI/rings;var sideDelta=2.0*Math.PI/sides;var a,b,theta,phi;for(a=0,theta=0;a<=rings;a++,theta+=ringDelta)
{var cosTheta=Math.cos(theta);var sinTheta=Math.sin(theta);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
{var cosPhi=Math.cos(phi);var sinPhi=Math.sin(phi);var dist=outerRadius+innerRadius*cosPhi;this._mesh._normals[0].push(cosTheta*cosPhi,-sinTheta*cosPhi,sinPhi);this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,innerRadius*sinPhi);this._mesh._texCoords[0].push(-a/rings,b/sides);}}
for(a=0;a<sides;a++)
{for(b=0;b<rings;b++)
{this._mesh._indices[0].push(b*(sides+1)+a);this._mesh._indices[0].push(b*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a);this._mesh._indices[0].push(b*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a+1);this._mesh._indices[0].push((b+1)*(sides+1)+a);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("Cone","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Cone.superClass.call(this,ctx);this.addField_SFFloat(ctx,'bottomRadius',1.0);this.addField_SFFloat(ctx,'height',2.0);this.addField_SFBool(ctx,'bottom',true);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'side',true);var sides=this._vf.subdivision;var geoCacheID='Cone_'+this._vf.bottomRadius+'_'+this._vf.height+'_'+this._vf.bottom+'_'+this._vf.side;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Cone from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var bottomRadius=this._vf.bottomRadius,height=this._vf.height;var beta,x,z;var delta=2.0*Math.PI/sides;var incl=bottomRadius/height;var nlen=1.0/Math.sqrt(1.0+incl*incl);var j=0;var k=0;if(this._vf.side)
{for(j=0,k=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(0,height/2,0);this._mesh._normals[0].push(x/nlen,incl/nlen,z/nlen);this._mesh._texCoords[0].push(1.0-j/sides,1);this._mesh._positions[0].push(x*bottomRadius,-height/2,z*bottomRadius);this._mesh._normals[0].push(x/nlen,incl/nlen,z/nlen);this._mesh._texCoords[0].push(1.0-j/sides,0);if(j>0)
{this._mesh._indices[0].push(k+0);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+3);k+=2;}}}
if(this._vf.bottom&&bottomRadius>0)
{var base=this._mesh._positions[0].length/3;for(j=sides-1;j>=0;j--)
{beta=j*delta;x=bottomRadius*Math.sin(beta);z=-bottomRadius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);this._mesh._normals[0].push(0,-1,0);this._mesh._texCoords[0].push(x/bottomRadius/2+0.5,z/bottomRadius/2+0.5);}
var h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(h);this._mesh._indices[0].push(base);h=base+j;this._mesh._indices[0].push(h);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{fieldChanged:function(fieldName){if(fieldName==="bottomRadius"||fieldName==="height"){this._mesh._positions[0]=[];var bottomRadius=this._vf.bottomRadius,height=this._vf.height;var sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var incl=bottomRadius/height;var nlen=1.0/Math.sqrt(1.0+incl*incl);if(this._vf.side)
{for(var j=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(0,height/2,0);this._mesh._positions[0].push(x*bottomRadius,-height/2,z*bottomRadius);}}
if(this._vf.bottom&&bottomRadius>0)
{var base=this._mesh._positions[0].length/3;for(var j=sides-1;j>=0;j--)
{beta=j*delta;x=bottomRadius*Math.sin(beta);z=-bottomRadius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else if(fieldName==="subdivision"||fieldName==="bottom"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var bottomRadius=this._vf.bottomRadius,height=this._vf.height;var sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var incl=bottomRadius/height;var nlen=1.0/Math.sqrt(1.0+incl*incl);var j=0;var k=0;if(this._vf.side)
{for(j=0,k=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(0,height/2,0);this._mesh._normals[0].push(x/nlen,incl/nlen,z/nlen);this._mesh._texCoords[0].push(1.0-j/sides,1);this._mesh._positions[0].push(x*bottomRadius,-height/2,z*bottomRadius);this._mesh._normals[0].push(x/nlen,incl/nlen,z/nlen);this._mesh._texCoords[0].push(1.0-j/sides,0);if(j>0)
{this._mesh._indices[0].push(k+0);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+3);k+=2;}}}
if(this._vf.bottom&&bottomRadius>0)
{var base=this._mesh._positions[0].length/3;for(j=sides-1;j>=0;j--)
{beta=j*delta;x=bottomRadius*Math.sin(beta);z=-bottomRadius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);this._mesh._normals[0].push(0,-1,0);this._mesh._texCoords[0].push(x/bottomRadius/2+0.5,z/bottomRadius/2+0.5);}
var h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(h);this._mesh._indices[0].push(base);h=base+j;this._mesh._indices[0].push(h);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("Cylinder","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Cylinder.superClass.call(this,ctx);this.addField_SFFloat(ctx,'radius',1.0);this.addField_SFFloat(ctx,'height',2.0);this.addField_SFBool(ctx,'bottom',true);this.addField_SFBool(ctx,'top',true);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'side',true);var sides=this._vf.subdivision;var geoCacheID='Cylinder_'+this._vf.radius+'_'+this._vf.height+'_'+this._vf.bottom+'_'+this._vf.top+'_'+this._vf.side;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Cylinder from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var radius=this._vf.radius;var height=this._vf.height;var beta,x,z;var delta=2.0*Math.PI/sides;var j=0;var k=0;if(this._vf.side)
{for(j=0,k=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(x*radius,-height/2,z*radius);this._mesh._normals[0].push(x,0,z);this._mesh._texCoords[0].push(1.0-j/sides,0);this._mesh._positions[0].push(x*radius,height/2,z*radius);this._mesh._normals[0].push(x,0,z);this._mesh._texCoords[0].push(1.0-j/sides,1);if(j>0)
{this._mesh._indices[0].push(k+0);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+3);k+=2;}}}
if(radius>0)
{var h,base=this._mesh._positions[0].length/3;if(this._vf.top)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,height/2,z);this._mesh._normals[0].push(0,1,0);this._mesh._texCoords[0].push(x/radius/2+0.5,-z/radius/2+0.5);}
h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(base);this._mesh._indices[0].push(h);h=base+j;this._mesh._indices[0].push(h);}
base=this._mesh._positions[0].length/3;}
if(this._vf.bottom)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);this._mesh._normals[0].push(0,-1,0);this._mesh._texCoords[0].push(x/radius/2+0.5,z/radius/2+0.5);}
h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(h);this._mesh._indices[0].push(base);h=base+j;this._mesh._indices[0].push(h);}}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{fieldChanged:function(fieldName){if(fieldName==="radius"||fieldName==="height"){this._mesh._positions[0]=[];var radius=this._vf.radius,height=this._vf.height;var sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var j=0;if(this._vf.side)
{for(j=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(x*radius,-height/2,z*radius);this._mesh._positions[0].push(x*radius,height/2,z*radius);}}
if(radius>0)
{var h,base=this._mesh._positions[0].length/3;if(this._vf.top)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,height/2,z);}}}
if(this._vf.bottom)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else if(fieldName==="subdivision"||fieldName==="bottom"||fieldName==="top"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var radius=this._vf.radius,height=this._vf.height;var sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var j=0;var k=0;if(this._vf.side)
{for(j=0,k=0;j<=sides;j++)
{beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);this._mesh._positions[0].push(x*radius,-height/2,z*radius);this._mesh._normals[0].push(x,0,z);this._mesh._texCoords[0].push(1.0-j/sides,0);this._mesh._positions[0].push(x*radius,height/2,z*radius);this._mesh._normals[0].push(x,0,z);this._mesh._texCoords[0].push(1.0-j/sides,1);if(j>0)
{this._mesh._indices[0].push(k+0);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+2);this._mesh._indices[0].push(k+1);this._mesh._indices[0].push(k+3);k+=2;}}}
if(radius>0)
{var h,base=this._mesh._positions[0].length/3;if(this._vf.top)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,height/2,z);this._mesh._normals[0].push(0,1,0);this._mesh._texCoords[0].push(x/radius/2+0.5,-z/radius/2+0.5);}
h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(base);this._mesh._indices[0].push(h);h=base+j;this._mesh._indices[0].push(h);}
base=this._mesh._positions[0].length/3;}
if(this._vf.bottom)
{for(j=sides-1;j>=0;j--)
{beta=j*delta;x=radius*Math.sin(beta);z=-radius*Math.cos(beta);this._mesh._positions[0].push(x,-height/2,z);this._mesh._normals[0].push(0,-1,0);this._mesh._texCoords[0].push(x/radius/2+0.5,z/radius/2+0.5);}
h=base+1;for(j=2;j<sides;j++)
{this._mesh._indices[0].push(h);this._mesh._indices[0].push(base);h=base+j;this._mesh._indices[0].push(h);}}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("ImageGeometry","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.ImageGeometry.superClass.call(this,ctx);var coordPrio=-5;var normalPrio=-4;for(var i=0;i<ctx.xmlNode.childNodes.length;i++){if('imagetexture'==ctx.xmlNode.childNodes[i].localName){if('coord'==ctx.xmlNode.childNodes[i].getAttribute('containerField')){ctx.xmlNode.childNodes[i].setAttribute('priority',coordPrio);coordPrio+=10;}else if('normal'==ctx.xmlNode.childNodes[i].getAttribute('containerField')){ctx.xmlNode.childNodes[i].setAttribute('priority',normalPrio);normalPrio+=10;}else if('texCoord'==ctx.xmlNode.childNodes[i].getAttribute('containerField')){ctx.xmlNode.childNodes[i].setAttribute('priority','-3');}else if('color'==ctx.xmlNode.childNodes[i].getAttribute('containerField')){ctx.xmlNode.childNodes[i].setAttribute('priority','-2');}}}
this.addField_SFVec3f(ctx,'position',0,0,0);this.addField_SFVec3f(ctx,'size',0,0,0);this.addField_MFFloat(ctx,'vertexCount',[0]);this.addField_MFString(ctx,'primType',['TRIANGLES']);this.addField_SFFloat(ctx,'numColorComponents',3);this.addField_SFNode('index',x3dom.nodeTypes.X3DTextureNode);this.addField_MFNode('coord',x3dom.nodeTypes.X3DTextureNode);this.addField_MFNode('normal',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('texCoord',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('color',x3dom.nodeTypes.X3DTextureNode);this._mesh._numColComponents=this._vf.numColorComponents;if(x3dom.caps.BACKEND=='webgl'&&x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS>0){var geoCacheID='ImageGeometry';if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using ImageGeometry-Mesh from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{for(var y=0;y<256;y++)
{for(var x=0;x<256;x++)
{var idx=y*256+x;if(idx==65535)break;this._mesh._positions[0].push(x/256,y/256,0);this._mesh._indices[0].push(idx);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}}},{nodeChanged:function()
{Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node._dirty.normals=true;node._dirty.texcoords=true;});},getMin:function()
{return this._vf.position.subtract(this._vf.size.multiply(0.5));},getMax:function()
{return this._vf.position.add(this._vf.size.multiply(0.5));},getVolume:function(min,max,invalidate)
{min.setValues(this.getMin());max.setValues(this.getMax());return true;},getCenter:function()
{return this._vf.position;},numCoordinateTextures:function()
{return this._cf.coord.nodes.length;},getIndexTexture:function()
{if(this._cf.index.node){return this._cf.index.node;}else{return null;}},getIndexTextureURL:function()
{if(this._cf.index.node){return this._cf.index.node._vf.url;}else{return null;}},getCoordinateTexture:function(pos)
{if(this._cf.coord.nodes[pos]){return this._cf.coord.nodes[pos];}else{return null;}},getCoordinateTextureURL:function(pos)
{if(this._cf.coord.nodes[pos]){return this._cf.coord.nodes[pos]._vf.url;}else{return null;}},getNormalTexture:function(pos)
{if(this._cf.normal.nodes[pos]){return this._cf.normal.nodes[pos];}else{return null;}},getNormalTextureURL:function(pos)
{if(this._cf.normal.nodes[pos]){return this._cf.normal.nodes[pos]._vf.url;}else{return null;}},getTexCoordTexture:function()
{if(this._cf.texCoord.node){return this._cf.texCoord.node;}else{return null;}},getTexCoordTextureURL:function()
{if(this._cf.texCoord.node){return this._cf.texCoord.node._vf.url;}else{return null;}},getColorTexture:function()
{if(this._cf.color.node){return this._cf.color.node;}else{return null;}},getColorTextureURL:function()
{if(this._cf.color.node){return this._cf.color.node._vf.url;}else{return null;}}}));x3dom.registerNodeType("IndexedFaceSet","Geometry3D",defineClass(x3dom.nodeTypes.X3DComposedGeometryNode,function(ctx){x3dom.nodeTypes.IndexedFaceSet.superClass.call(this,ctx);this.addField_SFFloat(ctx,'creaseAngle',0);this.addField_MFInt32(ctx,'coordIndex',[]);this.addField_MFInt32(ctx,'normalIndex',[]);this.addField_MFInt32(ctx,'colorIndex',[]);this.addField_MFInt32(ctx,'texCoordIndex',[]);this.addField_SFBool(ctx,'convex',true);},{nodeChanged:function()
{var time0=new Date().getTime();this.handleAttribs();var indexes=this._vf.coordIndex;var normalInd=this._vf.normalIndex;var texCoordInd=this._vf.texCoordIndex;var colorInd=this._vf.colorIndex;var hasNormal=false,hasNormalInd=false;var hasTexCoord=false,hasTexCoordInd=false;var hasColor=false,hasColorInd=false;var colPerVert=this._vf.colorPerVertex;var normPerVert=this._vf.normalPerVertex;if(normalInd.length>0)
{hasNormalInd=true;}
if(texCoordInd.length>0)
{hasTexCoordInd=true;}
if(colorInd.length>0)
{hasColorInd=true;}
var positions,normals,texCoords,colors;var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);positions=coordNode.getPoints();var normalNode=this._cf.normal.node;if(normalNode)
{hasNormal=true;normals=normalNode._vf.vector;}
else{hasNormal=false;}
var texMode="",numTexComponents=2;var texCoordNode=this._cf.texCoord.node;if(texCoordNode)
{if(texCoordNode._vf.point){hasTexCoord=true;texCoords=texCoordNode._vf.point;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.TextureCoordinate3D)){numTexComponents=3;}}
else if(texCoordNode._vf.mode){texMode=texCoordNode._vf.mode;}}
else{hasTexCoord=false;}
this._mesh._numTexComponents=numTexComponents;var numColComponents=3;var colorNode=this._cf.color.node;if(colorNode)
{hasColor=true;colors=colorNode._vf.color;if(x3dom.isa(colorNode,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
else{hasColor=false;}
this._mesh._numColComponents=numColComponents;this._mesh._indices[0]=[];this._mesh._positions[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._colors[0]=[];var i,t,cnt,faceCnt;var p0,p1,p2,n0,n1,n2,t0,t1,t2,c0,c1,c2;if((this._vf.creaseAngle<=x3dom.fields.Eps)||(positions.length/3>65535)||(hasNormal&&hasNormalInd)||(hasTexCoord&&hasTexCoordInd)||(hasColor&&hasColorInd))
{if(this._vf.convex){t=0;cnt=0;faceCnt=0;this._mesh._multiIndIndices=[];this._mesh._posSize=positions.length;for(i=0;i<indexes.length;++i)
{if(indexes[i]==-1){t=0;faceCnt++;continue;}
if(hasNormalInd){x3dom.debug.assert(normalInd[i]!=-1);}
if(hasTexCoordInd){x3dom.debug.assert(texCoordInd[i]!=-1);}
if(hasColorInd){x3dom.debug.assert(colorInd[i]!=-1);}
switch(t)
{case 0:p0=+indexes[i];if(hasNormalInd&&normPerVert){n0=+normalInd[i];}
else if(hasNormalInd&&!normPerVert){n0=+normalInd[faceCnt];}
else{n0=p0;}
if(hasTexCoordInd){t0=+texCoordInd[i];}
else{t0=p0;}
if(hasColorInd&&colPerVert){c0=+colorInd[i];}
else if(hasColorInd&&!colPerVert){c0=+colorInd[faceCnt];}
else{c0=p0;}
t=1;break;case 1:p1=+indexes[i];if(hasNormalInd&&normPerVert){n1=+normalInd[i];}
else if(hasNormalInd&&!normPerVert){n1=+normalInd[faceCnt];}
else{n1=p1;}
if(hasTexCoordInd){t1=+texCoordInd[i];}
else{t1=p1;}
if(hasColorInd&&colPerVert){c1=+colorInd[i];}
else if(hasColorInd&&!colPerVert){c1=+colorInd[faceCnt];}
else{c1=p1;}
t=2;break;case 2:p2=+indexes[i];if(hasNormalInd&&normPerVert){n2=+normalInd[i];}
else if(hasNormalInd&&!normPerVert){n2=+normalInd[faceCnt];}
else{n2=p2;}
if(hasTexCoordInd){t2=+texCoordInd[i];}
else{t2=p2;}
if(hasColorInd&&colPerVert){c2=+colorInd[i];}
else if(hasColorInd&&!colPerVert){c2=+colorInd[faceCnt];}
else{c2=p2;}
t=3;this._mesh._indices[0].push(cnt++,cnt++,cnt++);this._mesh._positions[0].push(positions[p0].x);this._mesh._positions[0].push(positions[p0].y);this._mesh._positions[0].push(positions[p0].z);this._mesh._positions[0].push(positions[p1].x);this._mesh._positions[0].push(positions[p1].y);this._mesh._positions[0].push(positions[p1].z);this._mesh._positions[0].push(positions[p2].x);this._mesh._positions[0].push(positions[p2].y);this._mesh._positions[0].push(positions[p2].z);if(hasNormal){this._mesh._normals[0].push(normals[n0].x);this._mesh._normals[0].push(normals[n0].y);this._mesh._normals[0].push(normals[n0].z);this._mesh._normals[0].push(normals[n1].x);this._mesh._normals[0].push(normals[n1].y);this._mesh._normals[0].push(normals[n1].z);this._mesh._normals[0].push(normals[n2].x);this._mesh._normals[0].push(normals[n2].y);this._mesh._normals[0].push(normals[n2].z);}
else{this._mesh._multiIndIndices.push(p0,p1,p2);}
if(hasColor){this._mesh._colors[0].push(colors[c0].r);this._mesh._colors[0].push(colors[c0].g);this._mesh._colors[0].push(colors[c0].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c0].a);}
this._mesh._colors[0].push(colors[c1].r);this._mesh._colors[0].push(colors[c1].g);this._mesh._colors[0].push(colors[c1].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c1].a);}
this._mesh._colors[0].push(colors[c2].r);this._mesh._colors[0].push(colors[c2].g);this._mesh._colors[0].push(colors[c2].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c2].a);}}
if(hasTexCoord){this._mesh._texCoords[0].push(texCoords[t0].x);this._mesh._texCoords[0].push(texCoords[t0].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t0].z);}
this._mesh._texCoords[0].push(texCoords[t1].x);this._mesh._texCoords[0].push(texCoords[t1].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t1].z);}
this._mesh._texCoords[0].push(texCoords[t2].x);this._mesh._texCoords[0].push(texCoords[t2].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t2].z);}}
break;case 3:p1=p2;t1=t2;if(normPerVert){n1=n2;}
if(colPerVert){c1=c2;}
p2=+indexes[i];if(hasNormalInd&&normPerVert){n2=+normalInd[i];}else if(hasNormalInd&&!normPerVert){}else{n2=p2;}
if(hasTexCoordInd){t2=+texCoordInd[i];}else{t2=p2;}
if(hasColorInd&&colPerVert){c2=+colorInd[i];}else if(hasColorInd&&!colPerVert){}else{c2=p2;}
this._mesh._indices[0].push(cnt++,cnt++,cnt++);this._mesh._positions[0].push(positions[p0].x);this._mesh._positions[0].push(positions[p0].y);this._mesh._positions[0].push(positions[p0].z);this._mesh._positions[0].push(positions[p1].x);this._mesh._positions[0].push(positions[p1].y);this._mesh._positions[0].push(positions[p1].z);this._mesh._positions[0].push(positions[p2].x);this._mesh._positions[0].push(positions[p2].y);this._mesh._positions[0].push(positions[p2].z);if(hasNormal){this._mesh._normals[0].push(normals[n0].x);this._mesh._normals[0].push(normals[n0].y);this._mesh._normals[0].push(normals[n0].z);this._mesh._normals[0].push(normals[n1].x);this._mesh._normals[0].push(normals[n1].y);this._mesh._normals[0].push(normals[n1].z);this._mesh._normals[0].push(normals[n2].x);this._mesh._normals[0].push(normals[n2].y);this._mesh._normals[0].push(normals[n2].z);}
else{this._mesh._multiIndIndices.push(p0,p1,p2);}
if(hasColor){this._mesh._colors[0].push(colors[c0].r);this._mesh._colors[0].push(colors[c0].g);this._mesh._colors[0].push(colors[c0].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c0].a);}
this._mesh._colors[0].push(colors[c1].r);this._mesh._colors[0].push(colors[c1].g);this._mesh._colors[0].push(colors[c1].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c1].a);}
this._mesh._colors[0].push(colors[c2].r);this._mesh._colors[0].push(colors[c2].g);this._mesh._colors[0].push(colors[c2].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c2].a);}}
if(hasTexCoord){this._mesh._texCoords[0].push(texCoords[t0].x);this._mesh._texCoords[0].push(texCoords[t0].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t0].z);}
this._mesh._texCoords[0].push(texCoords[t1].x);this._mesh._texCoords[0].push(texCoords[t1].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t1].z);}
this._mesh._texCoords[0].push(texCoords[t2].x);this._mesh._texCoords[0].push(texCoords[t2].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t2].z);}}
break;default:}}}else{var linklist=new x3dom.DoublyLinkedList();var data=new Object();cnt=0;for(var i=0;i<indexes.length;++i)
{if(indexes[i]==-1){var multi_index_data=x3dom.EarClipping.getMultiIndexes(linklist);for(var j=0;j<multi_index_data.indices.length;j++)
{this._mesh._indices[0].push(cnt);cnt++;this._mesh._positions[0].push(multi_index_data.point[j].x,multi_index_data.point[j].y,multi_index_data.point[j].z);if(hasNormal){this._mesh._normals[0].push(multi_index_data.normals[j].x,multi_index_data.normals[j].y,multi_index_data.normals[j].z);}
if(hasColor){this._mesh._colors[0].push(multi_index_data.colors[j].r,multi_index_data.colors[j].g,multi_index_data.colors[j].b);if(numColComponents===4){this._mesh._colors[0].push(multi_index_data.colors[j].a);}}
if(hasTexCoord){this._mesh._texCoords[0].push(multi_index_data.texCoords[j].x,multi_index_data.texCoords[j].y);if(numTexComponents===3){this._mesh._texCoords[0].push(multi_index_data.texCoords[j].z);}}}
linklist=new x3dom.DoublyLinkedList();faceCnt++;continue;}
if(hasNormal){if(hasNormalInd&&normPerVert){data.normals=normals[normalInd[i]];}else if(hasNormalInd&&!normPerVert){data.normals=normals[normalInd[faceCnt]];}else{data.normals=normals[indexes[i]];}}
if(hasColor){if(hasColorInd&&colPerVert){data.colors=colors[colorInd[i]];}else if(hasColorInd&&!colPerVert){data.colors=colors[colorInd[faceCnt]];}else{data.colors=colors[indexes[i]];}}
if(hasTexCoord){if(hasTexCoordInd){data.texCoords=texCoords[texCoordInd[i]];}else{data.texCoords=texCoords[indexes[i]];}}
linklist.appendNode(new x3dom.DoublyLinkedList.ListNode(positions[indexes[i]],indexes[i],data.normals,data.colors,data.texCoords));}}
if(!hasNormal){this._mesh.calcNormals(this._vf.creaseAngle);}
if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
this._mesh.splitMesh();}
else
{t=0;if(this._vf.convex){for(i=0;i<indexes.length;++i)
{if(indexes[i]==-1){t=0;continue;}
switch(t){case 0:n0=+indexes[i];t=1;break;case 1:n1=+indexes[i];t=2;break;case 2:n2=+indexes[i];t=3;this._mesh._indices[0].push(n0,n1,n2);break;case 3:n1=n2;n2=+indexes[i];this._mesh._indices[0].push(n0,n1,n2);break;}}}else{var linklist=new x3dom.DoublyLinkedList();for(var i=0;i<indexes.length;++i)
{if(indexes[i]==-1){var linklist_indces=x3dom.EarClipping.getIndexes(linklist);for(var j=0;j<linklist_indces.length;j++){this._mesh._indices[0].push(linklist_indces[j]);}
linklist=new x3dom.DoublyLinkedList();continue;}
linklist.appendNode(new x3dom.DoublyLinkedList.ListNode(positions[indexes[i]],indexes[i]));}}
this._mesh._positions[0]=positions.toGL();if(hasNormal){this._mesh._normals[0]=normals.toGL();}
else{this._mesh.calcNormals(this._vf.creaseAngle);}
if(hasTexCoord){this._mesh._texCoords[0]=texCoords.toGL();this._mesh._numTexComponents=numTexComponents;}
else{this._mesh.calcTexCoords(texMode);}
if(hasColor){this._mesh._colors[0]=colors.toGL();this._mesh._numColComponents=numColComponents;}}
this._mesh._invalidate=true;this._mesh._numFaces=0;this._mesh._numCoords=0;for(i=0;i<this._mesh._indices.length;i++){this._mesh._numFaces+=this._mesh._indices[i].length/3;this._mesh._numCoords+=this._mesh._positions[i].length/3;}
var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
{var pnts=this._cf.coord.node._vf.point;var i,n=pnts.length;if((this._vf.creaseAngle<=x3dom.fields.Eps)||(n/3>65535))
{x3dom.debug.logWarning("Ipol with creaseAngle == 0, too many coords, or multi-index!");this.nodeChanged();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});return;}
if(fieldName=="coord")
{pnts=this._cf.coord.node._vf.point;n=pnts.length;this._mesh._positions[0]=[];for(i=0;i<n;i++)
{this._mesh._positions[0].push(pnts[i].x);this._mesh._positions[0].push(pnts[i].y);this._mesh._positions[0].push(pnts[i].z);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}
else if(fieldName=="color")
{pnts=this._cf.color.node._vf.color;n=pnts.length;this._mesh._colors[0]=[];for(i=0;i<n;i++)
{this._mesh._colors[0].push(pnts[i].r);this._mesh._colors[0].push(pnts[i].g);this._mesh._colors[0].push(pnts[i].b);}
Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
else if(fieldName=="normal")
{pnts=this._cf.normal.node._vf.vector;n=pnts.length;this._mesh._normals[0]=[];for(var i=0;i<n;i++)
{this._mesh._normals[0].push(pnts[i].x);this._mesh._normals[0].push(pnts[i].y);this._mesh._normals[0].push(pnts[i].z);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}
else if(fieldName=="texCoord")
{pnts=this._cf.texCoord.node._vf.point;n=pnts.length;this._mesh._texCoords[0]=[];for(i=0;i<n;i++)
{this._mesh._texCoords[0].push(pnts[i].x);this._mesh._texCoords[0].push(pnts[i].y);}
this._mesh._invalidate=true;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("GeoCoordinate","Geospatial",defineClass(x3dom.nodeTypes.X3DCoordinateNode,function(ctx){x3dom.nodeTypes.GeoCoordinate.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'point',[]);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.GeoOrigin);},{elipsoideParameters:{'AA':['Airy 1830','6377563.396','299.3249646'],'AM':['Modified Airy','6377340.189','299.3249646'],'AN':['Australian National','6378160','298.25'],'BN':['Bessel 1841 (Namibia)','6377483.865','299.1528128'],'BR':['Bessel 1841 (Ethiopia Indonesia...)','6377397.155','299.1528128'],'CC':['Clarke 1866','6378206.4','294.9786982'],'CD':['Clarke 1880','6378249.145','293.465'],'EA':['Everest (India 1830)','6377276.345','300.8017'],'EB':['Everest (Sabah & Sarawak)','6377298.556','300.8017'],'EC':['Everest (India 1956)','6377301.243','300.8017'],'ED':['Everest (W. Malaysia 1969)','6377295.664','300.8017'],'EE':['Everest (W. Malaysia & Singapore 1948)','6377304.063','300.8017'],'EF':['Everest (Pakistan)','6377309.613','300.8017'],'FA':['Modified Fischer 1960','6378155','298.3'],'HE':['Helmert 1906','6378200','298.3'],'HO':['Hough 1960','6378270','297'],'ID':['Indonesian 1974','6378160','298.247'],'IN':['International 1924','6378388','297'],'KA':['Krassovsky 1940','6378245','298.3'],'RF':['Geodetic Reference System 1980 (GRS 80)','6378137','298.257222101'],'SA':['South American 1969','6378160','298.25'],'WD':['WGS 72','6378135','298.26'],'WE':['WGS 84','6378137','298.257223563']},nodeChanged:function(){},fieldChanged:function(fieldName){Array.forEach(this._parentNodes,function(node){node.fieldChanged("coord");});},isLogitudeFirst:function(geoSystem){for(var i=0;i<geoSystem.length;++i)
if(geoSystem[i]=='longitude_first')
return true;return false;},getElipsoide:function(geoSystem)
{for(var i=0;i<geoSystem.length;++i)
{var code=geoSystem[i];if(this.elipsoideParameters[code])
return this.elipsoideParameters[code];}
return this.elipsoideParameters['WE'];},getReferenceFrame:function(geoSystem)
{for(var i=0;i<geoSystem.length;++i)
{var code=geoSystem[i];if(code=='GD'||code=='GDC')
return'GD';if(code=='GC'||code=='GCC')
return'GC';if(code=='UTM')
return'UTM';else
x3dom.debug.logError('Unknown GEO system: ['+geoSystem+']');}
return this.elipsoideParameters['WE'];},UTMtoGC:function(geoSystem,coords){x3dom.debug.logError('Not implemented GeoCoordinate: UTM');},GDtoGC:function(geoSystem,coords){var output=new x3dom.fields.MFVec3f();var elipsoide=this.getElipsoide(geoSystem);var radius=elipsoide[1];var eccentricity=elipsoide[2];var longitudeFirst=this.isLogitudeFirst(geoSystem);var A=radius;var A2=radius*radius;var F=1.0/eccentricity;var C=A*(1.0-F);var C2=C*C;var Eps2=F*(2.0-F);var Eps25=0.25*Eps2;var radiansPerDegree=0.0174532925199432957692;for(var i=0;i<coords.length;++i)
{var current=new x3dom.fields.SFVec3f();var source_lat=radiansPerDegree*(longitudeFirst==true?coords[i].y:coords[i].x);var source_lon=radiansPerDegree*(longitudeFirst==true?coords[i].x:coords[i].y);var slat=Math.sin(source_lat);var slat2=slat*slat;var clat=Math.cos(source_lat);var Rn=A/((0.25-Eps25*slat2+0.9999944354799/4.0)+(0.25-Eps25*slat2)/(0.25-Eps25*slat2+0.9999944354799/4.0));var RnPh=Rn+coords[i].z;current.x=RnPh*clat*Math.cos(source_lon);current.y=RnPh*clat*Math.sin(source_lon);current.z=((C2/A2)*Rn+coords[i].z)*slat;output.push(current);}
return output;},GEOtoGC:function(geoSystem,geoOrigin,coords)
{var referenceFrame=this.getReferenceFrame(geoSystem);if(referenceFrame=='GD')
return this.GDtoGC(geoSystem,coords);else if(referenceFrame=='UTM')
return this.UTMtoGC(geoSystem,coords);else if(referenceFrame=='GC')
{if(geoOrigin.node)
{var copy=new x3dom.fields.MFVec3f();for(var i=0;i<coords.length;++i)
{var current=new x3dom.fields.SFVec3f();current.x=coords[i].x;current.y=coords[i].y;current.z=coords[i].z;copy.push(current);}
return copy;}
else
return coords;}
else
x3dom.debug.logError('Unknown geoSystem: '+geoSystem[0]);},OriginToGC:function(geoOrigin)
{var geoCoords=geoOrigin.node._vf.geoCoords;var geoSystem=geoOrigin.node._vf.geoSystem;var point=new x3dom.fields.SFVec3f;point.x=geoCoords.x;point.y=geoCoords.y;point.z=geoCoords.z;var temp=new x3dom.fields.MFVec3f;temp.push(point);var origin=this.GEOtoGC(geoSystem,geoOrigin,temp);return origin[0];},GEOtoX3D:function(geoSystem,geoOrigin,coords)
{var gc=this.GEOtoGC(geoSystem,geoOrigin,coords);if(geoOrigin.node)
{var origin=this.OriginToGC(geoOrigin);var matrix=x3dom.fields.SFMatrix4f.translation(origin);matrix=matrix.inverse();for(var i=0;i<coords.length;++i)
gc[i]=matrix.multMatrixPnt(gc[i]);}
return gc;},getPoints:function()
{return this.GEOtoX3D(this._vf.geoSystem,this._cf.geoOrigin,this._vf.point);}}));x3dom.registerNodeType("GeoElevationGrid","Geospatial",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.GeoElevationGrid.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_SFVec3d(ctx,'geoGridOrigin',0,0,0);this.addField_MFDouble(ctx,'height',0,0);this.addField_SFBool(ctx,'ccw',true);this.addField_SFInt32(ctx,'xDimension',0);this.addField_SFDouble(ctx,'xSpacing',1.0);this.addField_SFFloat(ctx,'yScale',1);this.addField_SFInt32(ctx,'zDimension',0);this.addField_SFDouble(ctx,'zSpacing',1.0);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.GeoOrigin);this.addField_SFBool(ctx,'lit',true);},{generateNormals:function(coords,xDimension,zDimension)
{var normals=new x3dom.fields.MFVec3f();for(var z=0;z<zDimension;++z)
for(var x=0;x<xDimension;++x)
{var current=coords[(z*xDimension)+x];var normal=new x3dom.fields.SFVec3f(0,0,0);var left=(x>0)?coords[(((z)*xDimension)+(x-1))].subtract(current):null;var right=(x<xDimension-1)?coords[(((z)*xDimension)+(x+1))].subtract(current):null;var lower=(z>0)?coords[(((z-1)*xDimension)+(x))].subtract(current):null;var upper=(z<zDimension-1)?coords[(((z+1)*xDimension)+(x))].subtract(current):null;if(lower&&left)
normal=normal.add(left.cross(lower));if(left&&upper)
normal=normal.add(upper.cross(left));if(upper&&right)
normal=normal.add(right.cross(upper));if(right&&lower)
normal=normal.add(lower.cross(right));normals.push(normal.normalize());}
return normals;},nodeChanged:function()
{var geoSystem=this._vf.geoSystem;var geoOrigin=this._cf.geoOrigin;var height=this._vf.height;var yScale=this._vf.yScale;var xDimension=this._vf.xDimension;var zDimension=this._vf.zDimension;var xSpacing=this._vf.xSpacing;var zSpacing=this._vf.zSpacing;var geoGridOrigin=this._vf.geoGridOrigin;if(height.length!==(xDimension*zDimension))
x3dom.debug.logError('GeoElevationGrid: height.length('+height.length+') != x/zDimension('+xDimension+'*'+zDimension+')');var longitude_first=x3dom.nodeTypes.GeoCoordinate.prototype.isLogitudeFirst(geoSystem);var ccw=this._vf.ccw;var delta_x=1/(xDimension-1);var delta_z=1/(zDimension-1);var positions=new x3dom.fields.MFVec3f();var texCoords=new x3dom.fields.MFVec2f();for(var z=0;z<zDimension;++z)
for(var x=0;x<xDimension;++x)
{var tex_coord=new x3dom.fields.SFVec2f(x*delta_x,z*delta_z);texCoords.push(tex_coord);var coord=new x3dom.fields.SFVec3f();if(longitude_first)
{coord.x=x*xSpacing;coord.y=z*zSpacing;}
else
{coord.x=z*zSpacing;coord.y=x*xSpacing;}
coord.z=height[(z*xDimension)+x]*yScale;coord=coord.add(geoGridOrigin);positions.push(coord);}
var indices=new x3dom.fields.MFInt32();for(var z=0;z<(zDimension-1);z++)
{for(var x=0;x<(xDimension-1);x++)
{var p0=x+(z*xDimension);var p1=x+(z*xDimension)+1;var p2=x+((z+1)*xDimension)+1;var p3=x+((z+1)*xDimension);if(ccw)
{indices.push(p0);indices.push(p1);indices.push(p2);indices.push(p0);indices.push(p2);indices.push(p3);}
else
{indices.push(p0);indices.push(p3);indices.push(p2);indices.push(p0);indices.push(p2);indices.push(p1);}}}
var transformed=x3dom.nodeTypes.GeoCoordinate.prototype.GEOtoX3D(geoSystem,geoOrigin,positions);var normals=this.generateNormals(transformed,xDimension,zDimension);this._mesh._normals[0]=normals.toGL();this._mesh._indices[0]=indices.toGL();this._mesh._positions[0]=transformed.toGL();this._mesh._texCoords[0]=texCoords.toGL();this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoLOD","Geospatial",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.GeoLOD.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_MFString(ctx,'rootUrl',[]);this.addField_MFString(ctx,'child1Url',[]);this.addField_MFString(ctx,'child2Url',[]);this.addField_MFString(ctx,'child3Url',[]);this.addField_MFString(ctx,'child4Url',[]);this.addField_SFVec3d(ctx,'center',0,0,0);this.addField_SFFloat(ctx,'range',10);this.addField_SFString(ctx,'referenceBindableDescription',[]);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('rootNode',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('privateChild1Node',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('privateChild2Node',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('privateChild3Node',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('privateChild4Node',x3dom.nodeTypes.ChildGroup);this.addField_SFNode('privateRootNode',x3dom.nodeTypes.ChildGroup);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoLocation","Geospatial",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.GeoLocation.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_SFVec3d(ctx,'geoCoords',0,0,0);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.ChildGroup);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoMetadata","Geospatial",defineClass(x3dom.nodeTypes.X3DInfoNode,function(ctx){x3dom.nodeTypes.GeoMetadata.superClass.call(this,ctx);this.addField_MFString(ctx,'url',[]);this.addField_MFNode('data',x3dom.nodeTypes.InfoNode);this.addField_MFString(ctx,'summary',[]);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoOrigin","Geospatial",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.GeoOrigin.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_SFVec3d(ctx,'geoCoords',0,0,0);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoPositionInterpolator","Geospatial",defineClass(x3dom.nodeTypes.X3DInterpolatorNode,function(ctx){x3dom.nodeTypes.GeoPositionInterpolator.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_MFVec3d(ctx,'keyValue',[]);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.LinearInterpolator);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoProximitySensor","Geospatial",defineClass(x3dom.nodeTypes.X3DEnvironmentalSensorNode,function(ctx){x3dom.nodeTypes.GeoProximitySensor.superClass.call(this,ctx);this.addField_SFVec3d(ctx,'geoCenter',0,0,0);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.EnvironmentSensor);this.addField_MFString(ctx,'geoSystem',['GD','WE']);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoTouchSensor","Geospatial",defineClass(x3dom.nodeTypes.X3DTouchSensorNode,function(ctx){x3dom.nodeTypes.GeoTouchSensor.superClass.call(this,ctx);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.TouchSensor);this.addField_MFString(ctx,'geoSystem',['GD','WE']);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoTransform","Geospatial",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.GeoTransform.superClass.call(this,ctx);this.addField_SFVec3d(ctx,'geoCenter',0,0,0);this.addField_SFRotation(ctx,'rotation',0,0,1,0);this.addField_SFVec3f(ctx,'scale',1,1,1);this.addField_SFRotation(ctx,'scaleOrientation',0,0,1,0);this.addField_SFVec3f(ctx,'translation',0,0,0);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.Transform);this.addField_MFString(ctx,'geoSystem',['GD','WE']);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("GeoViewpoint","Geospatial",defineClass(x3dom.nodeTypes.X3DViewpointNode,function(ctx){x3dom.nodeTypes.GeoViewpoint.superClass.call(this,ctx);this.addField_MFString(ctx,'geoSystem',['GD','WE']);this.addField_SFFloat(ctx,'fieldOfView',0.785398);this.addField_SFRotation(ctx,'orientation',0,0,1,0);this.addField_SFVec3d(ctx,'position',0,0,100000);this.addField_SFBool(ctx,'headlight',true);this.addField_MFString(ctx,'navType','EXAMINE');this.addField_SFFloat(ctx,'speedFactor',1.0);this.addField_SFNode('geoOrigin',x3dom.nodeTypes.ViewBindable);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("Arc2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Arc2D.superClass.call(this,ctx);this.addField_SFFloat(ctx,'endAngle',1.570796);this.addField_SFFloat(ctx,'radius',1);this.addField_SFFloat(ctx,'startAngle',0);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'lit',false);var r=this._vf.radius;var start=this._vf.startAngle;var end=this._vf.endAngle;var geoCacheID='Arc2D_'+r;if(x3dom.geoCache[geoCacheID]!=undefined){x3dom.debug.logInfo("Using Arc2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}else{var anzahl=this._vf.subdivision;var t=(end-start)/anzahl;var theta=start;for(var i=0;i<=anzahl+1;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);theta+=t;}
for(var j=0;j<anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(j+1);}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){this._mesh._positions[0]=[];this._mesh._indices[0]=[];var r=this._vf.radius;var start=this._vf.startAngle;var end=this._vf.endAngle;var anzahl=this._vf.subdivision;var t=(end-start)/anzahl;var theta=start;for(var i=0;i<=anzahl+1;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);theta+=t;}
for(var j=0;j<anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(j+1);}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}));x3dom.registerNodeType("ArcClose2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.ArcClose2D.superClass.call(this,ctx);this.addField_SFString(ctx,'closureType',"PIE");this.addField_SFFloat(ctx,'endAngle',1.570796);this.addField_SFFloat(ctx,'radius',1);this.addField_SFFloat(ctx,'startAngle',0);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'solid',false);this.addField_SFBool(ctx,'lit',true);var r=this._vf.radius;var start=this._vf.startAngle;var end=this._vf.endAngle;var geoCacheID='ArcClose2D_'+r+start+end+this._vf.closureType;if(x3dom.geoCache[geoCacheID]!=undefined){x3dom.debug.logInfo("Using ArcClose2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}else{var anzahl=this._vf.subdivision;var t=(end-start)/anzahl;var theta=start;if(this._vf.closureType=='PIE'){this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push(0.5);this._mesh._texCoords[0].push(0.5);for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));theta+=t;}
for(var j=1;j<=anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(0);this._mesh._indices[0].push(j+1);}}else{for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));theta+=t;}
var x=(this._mesh._positions[0][0]+this._mesh._positions[0][this._mesh._positions[0].length-3])/2;var y=(this._mesh._positions[0][1]+this._mesh._positions[0][this._mesh._positions[0].length-2])/2;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));for(var j=0;j<anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(anzahl+1);this._mesh._indices[0].push(j+1);}}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){if(fieldName==="radius"){this._mesh._positions[0]=[];var r=this._vf.radius;var start=this._vf.startAngle;var end=this._vf.endAngle;var anzahl=this._vf.subdivision;var t=(end-start)/anzahl;var theta=start;if(this._vf.closureType=='PIE'){this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);theta+=t;}}else{for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);theta+=t;}
var x=(this._mesh._positions[0][0]+this._mesh._positions[0][this._mesh._positions[0].length-3])/2;var y=(this._mesh._positions[0][1]+this._mesh._positions[0][this._mesh._positions[0].length-2])/2;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else{this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var r=this._vf.radius;var start=this._vf.startAngle;var end=this._vf.endAngle;var anzahl=this._vf.subdivision;var t=(end-start)/anzahl;var theta=start;if(this._vf.closureType=='PIE'){this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push(0.5);this._mesh._texCoords[0].push(0.5);for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));theta+=t;}
for(var j=1;j<=anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(0);this._mesh._indices[0].push(j+1);}}else{for(var i=0;i<=anzahl;i++){var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));theta+=t;}
var x=(this._mesh._positions[0][0]+this._mesh._positions[0][this._mesh._positions[0].length-3])/2;var y=(this._mesh._positions[0][1]+this._mesh._positions[0][this._mesh._positions[0].length-2])/2;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x+r)/(2*r));this._mesh._texCoords[0].push((y+r)/(2*r));for(var j=0;j<anzahl;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(anzahl+1);this._mesh._indices[0].push(j+1);}}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("Circle2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Circle2D.superClass.call(this,ctx);this.addField_SFFloat(ctx,'radius',1);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'lit',false);var r=this._vf.radius;var geoCacheID='Circle2D_'+r;if(x3dom.geoCache[geoCacheID]!=undefined){x3dom.debug.logInfo("Using Circle2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}else{var anzahl=this._vf.subdivision;for(var i=0;i<=anzahl;i++){var theta=i*((2*Math.PI)/anzahl);var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
for(i=0;i<anzahl;i++){this._mesh._indices[0].push(i);if((i+1)==anzahl){this._mesh._indices[0].push(0);}else{this._mesh._indices[0].push(i+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){var r=this._vf.radius;var anzahl=this._vf.subdivision;this._mesh._positions[0]=[];this._mesh._indices[0]=[];for(var i=0;i<=anzahl;i++){var theta=i*((2*Math.PI)/anzahl);var x=Math.cos(theta)*r;var y=Math.sin(theta)*r;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
for(i=0;i<anzahl;i++){this._mesh._indices[0].push(i);if((i+1)==anzahl){this._mesh._indices[0].push(0);}else{this._mesh._indices[0].push(i+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}));x3dom.registerNodeType("Disk2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Disk2D.superClass.call(this,ctx);this.addField_SFFloat(ctx,'innerRadius',0);this.addField_SFFloat(ctx,'outerRadius',1);this.addField_SFFloat(ctx,'subdivision',32);this.addField_SFBool(ctx,'solid',false);this.addField_SFBool(ctx,'lit',true);var ir=this._vf.innerRadius;var or=this._vf.outerRadius;var geoCacheID='Disk2D_'+ir+or;if(x3dom.geoCache[geoCacheID]!=undefined){x3dom.debug.logInfo("Using Disk2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}else{var anzahl=this._vf.subdivision;for(var i=0;i<=anzahl;i++){var theta=i*((2*Math.PI)/anzahl);var ox=Math.cos(theta)*or;var oy=Math.sin(theta)*or;var ix=Math.cos(theta)*ir;var iy=Math.sin(theta)*ir;this._mesh._positions[0].push(ox);this._mesh._positions[0].push(oy);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((ox+or)/(2*or));this._mesh._texCoords[0].push((oy+or)/(2*or));this._mesh._positions[0].push(ix);this._mesh._positions[0].push(iy);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((ix+or)/(2*or));this._mesh._texCoords[0].push((iy+or)/(2*or));}
for(i=0;i<anzahl*2;i=i+2){if(i==(anzahl*2)-2){this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+1);this._mesh._indices[0].push(1);this._mesh._indices[0].push(1);this._mesh._indices[0].push(i);this._mesh._indices[0].push(0);}else{this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+1);this._mesh._indices[0].push(i+3);this._mesh._indices[0].push(i+3);this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+2);}}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var ir=this._vf.innerRadius;var or=this._vf.outerRadius;var anzahl=this._vf.subdivision;for(var i=0;i<=anzahl;i++){var theta=i*((2*Math.PI)/anzahl);var ox=Math.cos(theta)*or;var oy=Math.sin(theta)*or;var ix=Math.cos(theta)*ir;var iy=Math.sin(theta)*ir;this._mesh._positions[0].push(ox);this._mesh._positions[0].push(oy);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((ox+or)/(2*or));this._mesh._texCoords[0].push((oy+or)/(2*or));this._mesh._positions[0].push(ix);this._mesh._positions[0].push(iy);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((ix+or)/(2*or));this._mesh._texCoords[0].push((iy+or)/(2*or));}
for(i=0;i<anzahl*2;i=i+2){if(i==(anzahl*2)-2){this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+1);this._mesh._indices[0].push(1);this._mesh._indices[0].push(1);this._mesh._indices[0].push(i);this._mesh._indices[0].push(0);}else{this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+1);this._mesh._indices[0].push(i+3);this._mesh._indices[0].push(i+3);this._mesh._indices[0].push(i);this._mesh._indices[0].push(i+2);}}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}));x3dom.registerNodeType("Polyline2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Polyline2D.superClass.call(this,ctx);this.addField_MFVec2f(ctx,'lineSegments',[]);this.addField_SFBool(ctx,'lit',false);var x=this._vf.lineSegments[0].x;var y=this._vf.lineSegments[0].y;var geoCacheID='Polyline2D_'+x+'-'+y;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Polyline2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{for(var i=0;i<this._vf.lineSegments.length;i++){x=this._vf.lineSegments[i].x;y=this._vf.lineSegments[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
for(var j=0;j<this._vf.lineSegments.length-1;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(j+1);}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){var x;var y;this._mesh._positions[0]=[];this._mesh._indices[0]=[];for(var i=0;i<this._vf.lineSegments.length;i++){x=this._vf.lineSegments[i].x;y=this._vf.lineSegments[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
for(var j=0;j<this._vf.lineSegments.length-1;j++){this._mesh._indices[0].push(j);this._mesh._indices[0].push(j+1);}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/2;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}));x3dom.registerNodeType("Polypoint2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Polypoint2D.superClass.call(this,ctx);this.addField_MFVec2f(ctx,'point',[]);this.addField_SFBool(ctx,'lit',false);var x=this._vf.point[0].x;var y=this._vf.point[0].y;var geoCacheID='Polypoint2D_'+x+'-'+y;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Polypoint2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{for(var i=0;i<this._vf.point.length;i++){x=this._vf.point[i].x;y=this._vf.point[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){var x;var y;this._mesh._positions[0]=[];this._mesh._indices[0]=[];for(var i=0;i<this._vf.point.length;i++){x=this._vf.point[i].x;y=this._vf.point[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}}));x3dom.registerNodeType("Rectangle2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.Rectangle2D.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'size',2,2);this.addField_SFBool(ctx,'solid',false);this.addField_SFBool(ctx,'lit',true);this.addField_SFVec2f(ctx,'subdivision',1,1);var sx=this._vf.size.x,sy=this._vf.size.y;var partx=this._vf.subdivision.x,party=this._vf.subdivision.y;var geoCacheID='Rectangle2D_'+sx+'-'+sy;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using Rectangle2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var xstep=sx/partx;var ystep=sy/party;sx/=2;sy/=2;for(var i=0;i<=partx;i++){for(var j=0;j<=party;j++){this._mesh._positions[0].push(i*xstep-sx,j*ystep-sy,0);this._mesh._normals[0].push(0,0,1);this._mesh._texCoords[0].push(i/partx,j/party);}}
for(var i=1;i<=party;i++){for(var j=0;j<partx;j++){this._mesh._indices[0].push((i-1)*(partx+1)+j);this._mesh._indices[0].push((i-1)*(partx+1)+j+1);this._mesh._indices[0].push(i*(partx+1)+j);this._mesh._indices[0].push(i*(partx+1)+j);this._mesh._indices[0].push((i-1)*(partx+1)+j+1);this._mesh._indices[0].push(i*(partx+1)+j+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){if(fieldName=="size")
{this._mesh._positions[0]=[];var size=this._vf.size;var sx=size.x/2;var sy=size.y/2;var partx=this._vf.subdivision.x,party=this._vf.subdivision.y;var xstep=sx/partx;var ystep=sy/party;sx/=2;sy/=2;for(var i=0;i<=partx;i++){for(var j=0;j<=party;j++){this._mesh._positions[0].push(i*xstep-sx,j*ystep-sy,0);}}
this._mesh._invalidate=true;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;});}else{this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var sx=this._vf.size.x/2;var sy=this._vf.size.y/2;var partx=this._vf.subdivision.x,party=this._vf.subdivision.y;var xstep=sx/partx;var ystep=sy/party;sx/=2;sy/=2;for(var i=0;i<=partx;i++){for(var j=0;j<=party;j++){this._mesh._positions[0].push(i*xstep-sx,j*ystep-sy,0);this._mesh._normals[0].push(0,0,1);this._mesh._texCoords[0].push(i/partx,j/party);}}
for(var i=1;i<=party;i++){for(var j=0;j<partx;j++){this._mesh._indices[0].push((i-1)*(partx+1)+j);this._mesh._indices[0].push((i-1)*(partx+1)+j+1);this._mesh._indices[0].push(i*(partx+1)+j);this._mesh._indices[0].push(i*(partx+1)+j);this._mesh._indices[0].push((i-1)*(partx+1)+j+1);this._mesh._indices[0].push(i*(partx+1)+j+1);}}
this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));x3dom.registerNodeType("TriangleSet2D","Geometry2D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.TriangleSet2D.superClass.call(this,ctx);this.addField_MFVec2f(ctx,'vertices',[]);this.addField_SFBool(ctx,'solid',false);this.addField_SFBool(ctx,'lit',true);this.addField_MFVec2f(ctx,'lineSegments',[]);this.addField_SFBool(ctx,'lit',false);var x=this._vf.vertices[0].x;var y=this._vf.vertices[0].y;var geoCacheID='TriangleSet2D_'+x+'-'+y;if(x3dom.geoCache[geoCacheID]!=undefined)
{x3dom.debug.logInfo("Using TriangleSet2D from Cache");this._mesh=x3dom.geoCache[geoCacheID];}
else
{var minx=this._vf.vertices[0].x;var miny=this._vf.vertices[0].y;var maxx=this._vf.vertices[0].x;var maxy=this._vf.vertices[0].y;for(var i=0;i<this._vf.vertices.length;i++){if(this._vf.vertices[i].x<minx){minx=this._vf.vertices[i].x}
if(this._vf.vertices[i].y<miny){miny=this._vf.vertices[i].y}
if(this._vf.vertices[i].x>maxx){maxx=this._vf.vertices[i].x}
if(this._vf.vertices[i].y>maxy){maxy=this._vf.vertices[i].y}}
for(var i=0;i<this._vf.vertices.length;i++){x=this._vf.vertices[i].x;y=this._vf.vertices[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x-minx)/(maxx-minx));this._mesh._texCoords[0].push((y-miny)/(maxy-miny));}
for(var j=0;j<this._vf.vertices.length;j++){this._mesh._indices[0].push(j);}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}},{nodeChanged:function(){},fieldChanged:function(fieldName){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var minx=this._vf.vertices[0].x;var miny=this._vf.vertices[0].y;var maxx=this._vf.vertices[0].x;var maxy=this._vf.vertices[0].y;for(var i=0;i<this._vf.vertices.length;i++){if(this._vf.vertices[i].x<minx){minx=this._vf.vertices[i].x}
if(this._vf.vertices[i].y<miny){miny=this._vf.vertices[i].y}
if(this._vf.vertices[i].x>maxx){maxx=this._vf.vertices[i].x}
if(this._vf.vertices[i].y>maxy){maxy=this._vf.vertices[i].y}}
for(var i=0;i<this._vf.vertices.length;i++){var x=this._vf.vertices[i].x;var y=this._vf.vertices[i].y;this._mesh._positions[0].push(x);this._mesh._positions[0].push(y);this._mesh._positions[0].push(0.0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(0);this._mesh._normals[0].push(1);this._mesh._texCoords[0].push((x-minx)/(maxx-minx));this._mesh._texCoords[0].push((y-miny)/(maxy-miny));}
for(var j=0;j<this._vf.vertices.length;j++){this._mesh._indices[0].push(j);}
this._mesh._numTexComponents=2;this._mesh._invalidate=true;this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}));x3dom.registerNodeType("X3DVolumeDataNode","VolumeRendering",defineClass(x3dom.nodeTypes.X3DShapeNode,function(ctx){x3dom.nodeTypes.X3DVolumeDataNode.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'dimensions',1,1,1);this.addField_MFNode('voxels',x3dom.nodeTypes.X3DTexture3DNode);x3dom.debug.logWarning('VolumeRendering component NYI!!!');},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("X3DVolumeRenderStyleNode","VolumeRendering",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.X3DVolumeRenderStyleNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'enabled',true);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("X3DComposableVolumeRenderStyleNode","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode.superClass.call(this,ctx);this.addField_SFNode('surfaceNormals',x3dom.nodeTypes.X3DTexture3DNode);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("BlendedVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.BlendedVolumeStyle.superClass.call(this,ctx);this.addField_SFNode('renderStyle',x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode);this.addField_SFNode('voxels',x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode);this.addField_SFFloat(ctx,'weightConstant1',0.5);this.addField_SFFloat(ctx,'weightConstant2',0.5);this.addField_SFString(ctx,'weightFunction1',"CONSTANT");this.addField_SFString(ctx,'weightFunction2',"CONSTANT");this.addField_SFNode('weightTransferFunction1',x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode);this.addField_SFNode('weightTransferFunction2',x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("BoundaryEnhancementVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.BoundaryEnhancementVolumeStyle.superClass.call(this,ctx);this.addField_SFFloat(ctx,'retainedOpacity',1);this.addField_SFFloat(ctx,'boundaryOpacity',0);this.addField_SFFloat(ctx,'opacityFactor',1);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("CartoonVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.CartoonVolumeStyle.superClass.call(this,ctx);this.addField_SFColor(ctx,'parallelColor',0,0,0);this.addField_SFColor(ctx,'orthogonalColor',1,1,1);this.addField_SFInt32(ctx,'colorSteps',4);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("ComposedVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.ComposedVolumeStyle.superClass.call(this,ctx);this.addField_SFBool(ctx,'ordered',false);this.addField_MFNode('renderStyle',x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("EdgeEnhancementVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.EdgeEnhancementVolumeStyle.superClass.call(this,ctx);this.addField_SFColor(ctx,'edgeColor',0,0,0);this.addField_SFFloat(ctx,'gradientThreshold',0.4);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("ISOSurfaceVolumeData","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeDataNode,function(ctx){x3dom.nodeTypes.ISOSurfaceVolumeData.superClass.call(this,ctx);this.addField_MFNode('renderStyle',x3dom.nodeTypes.X3DVolumeRenderStyleNode);this.addField_SFNode('gradients',x3dom.nodeTypes.X3DTexture3DNode);this.addField_MFFloat(ctx,'surfaceValues',[]);this.addField_SFFloat(ctx,'contourStepSize',0);this.addField_SFFloat(ctx,'surfaceTolerance',0);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("OpacityMapVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.OpacityMapVolumeStyle.superClass.call(this,ctx);this.addField_SFNode('transferFunction',x3dom.nodeTypes.X3DTextureNode);this.addField_SFString(ctx,'type',"simple");},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("ProjectionVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.ProjectionVolumeStyle.superClass.call(this,ctx);this.addField_SFFloat(ctx,'intensityThreshold',0);this.addField_SFString(ctx,'type',"MAX");},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("SegmentedVolumeData","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeDataNode,function(ctx){x3dom.nodeTypes.SegmentedVolumeData.superClass.call(this,ctx);this.addField_MFNode('renderStyle',x3dom.nodeTypes.X3DVolumeDataNode);this.addField_MFBool(ctx,'segmentEnabled',[]);this.addField_SFNode('segmentIdentifiers',x3dom.nodeTypes.X3DVolumeDataNode);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("ShadedVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.ShadedVolumeStyle.superClass.call(this,ctx);this.addField_SFNode('material',x3dom.nodeTypes.X3DMaterialNode);this.addField_SFBool(ctx,'lighting',false);this.addField_SFBool(ctx,'shadows',false);this.addField_SFString(ctx,'phaseFunction',"Henyey-Greenstein");},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("SilhouetteEnhancementVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.SilhouetteEnhancementVolumeStyle.superClass.call(this,ctx);this.addField_SFFloat(ctx,'silhouetteBoundaryOpacity',0);this.addField_SFFloat(ctx,'silhouetteRetainedOpacity',1);this.addField_SFFloat(ctx,'silhouetteSharpness',0.5);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("StippleVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.StippleVolumeStyle.superClass.call(this,ctx);this.addField_SFFloat(ctx,'distanceFactor',1);this.addField_SFFloat(ctx,'interiorFactor',1);this.addField_SFFloat(ctx,'lightingFactor',1);this.addField_SFFloat(ctx,'gradientThreshold',0.4);this.addField_SFFloat(ctx,'gradientRetainedOpacity',1);this.addField_SFFloat(ctx,'gradientBoundaryOpacity',0);this.addField_SFFloat(ctx,'gradientOpacityFactor',1);this.addField_SFFloat(ctx,'silhouetteRetainedOpacity',1);this.addField_SFFloat(ctx,'silhouetteBoundaryOpacity',0);this.addField_SFFloat(ctx,'silhouetteOpacityFactor',1);this.addField_SFFloat(ctx,'resolutionFactor',1);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("ToneMappedVolumeStyle","VolumeRendering",defineClass(x3dom.nodeTypes.X3DComposableVolumeRenderStyleNode,function(ctx){x3dom.nodeTypes.ToneMappedVolumeStyle.superClass.call(this,ctx);this.addField_SFColor(ctx,'coolColor',0,0,1);this.addField_SFColor(ctx,'warmColor',1,1,0);},{nodeChanged:function(){},fieldChanged:function(fieldName){}}));x3dom.registerNodeType("VolumeData","VolumeRendering",defineClass(x3dom.nodeTypes.X3DVolumeDataNode,function(ctx){x3dom.nodeTypes.VolumeData.superClass.call(this,ctx);this.addField_SFNode('renderStyle',x3dom.nodeTypes.X3DVolumeRenderStyleNode);},{nodeChanged:function()
{if(!this._cf.appearance.node){this.addChild(x3dom.nodeTypes.Appearance.defaultNode());}
if(!this._cf.geometry.node){this.addChild(new x3dom.nodeTypes.Box());this._cf.geometry.node._vf.size=new x3dom.fields.SFVec3f(this._vf.dimensions.x,this._vf.dimensions.y,this._vf.dimensions.z);this._cf.geometry.node.fieldChanged("size");}},fieldChanged:function(fieldName){}}));x3dom.versionInfo={version:'1.3.1-dev',revision:'a9a69cec98d5b6804d5c54aebafd6e12420a961e',date:'Sun Feb 19 20:27:29 2012 +0100'};
