diff --git a/public/X3DOMTutorial/addnode.html b/public/X3DOMTutorial/addnode.html
new file mode 100644
index 0000000000000000000000000000000000000000..8332affba5a09d7b1e0a18cb860882c295bc0b00
--- /dev/null
+++ b/public/X3DOMTutorial/addnode.html
@@ -0,0 +1,88 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+	<title>Add/Remove Nodes example</title>
+	<link rel="stylesheet" type="text/css" href="./x3dom.css">
+</head>
+
+<body>
+	<h1>Add/Remove Nodes Example</h1>
+	<p>
+		simple example which shows how to add/remove nodes using a simple DOM appendChild()/removeChild() function
+	</p>
+	<x3d id="boxes" showstat="true" x="0px" y="0px" width="600px" height="300px">
+		<scene render="true" bboxcenter="0,0,0" bboxsize="-1,-1,-1" pickmode="idBuf" dopickpass="true">
+			<viewpoint position="4.88104 4.59865 7.4181" orientation="-0.69017 0.723467 -0.0161809 0.735134"
+				fieldofview="0.785398" centerofrotation="0,0,0" znear="-1" zfar="-1"></viewpoint>
+			<background def="bgnd" transparency="0" skycolor="1 1 1" groundcolor="" groundangle="" skyangle="" backurl=""
+				bottomurl="" fronturl="" lefturl="" righturl="" topurl=""></background>
+			<transform id="root" translation="0 0 0" render="true" bboxcenter="0,0,0" bboxsize="-1,-1,-1" center="0,0,0"
+				rotation="0,0,0,0" scale="1,1,1" scaleorientation="0,0,0,0">
+				<shape render="true" bboxcenter="0,0,0" bboxsize="-1,-1,-1" ispickable="true">
+					<appearance sorttype="auto">
+						<material ambientintensity="0.2" diffusecolor="0.8,0.8,0.8" emissivecolor="0,0,0" shininess="0.2"
+							specularcolor="0,0,0"></material>
+					</appearance>
+					<box solid="true" ccw="true" usegeocache="true" lit="true" size="2,2,2"></box>
+				</shape>
+				<transform translation="1.5160652180202305 1.489243873860687 -2.648085524328053"
+					scale="1.2286848302464932 0.7494203578680754 1.357877661474049" render="true" bboxcenter="0,0,0"
+					bboxsize="-1,-1,-1" center="0,0,0" rotation="0,0,0,0" scaleorientation="0,0,0,0">
+					<shape render="true" bboxcenter="0,0,0" bboxsize="-1,-1,-1" ispickable="true">
+						<appearance sorttype="auto">
+							<material ambientintensity="0.2" diffusecolor="0.8,0.8,0.8" emissivecolor="0,0,0" shininess="0.2"
+								specularcolor="0,0,0"></material>
+						</appearance>
+						<box solid="true" ccw="true" usegeocache="true" lit="true" size="2,2,2"></box>
+					</shape>
+				</transform>
+			</transform>
+		</scene>
+		<div class="x3dom-progress" style="display: none;"><strong>Loading: 0</strong><span style="width: 25%;"> </span>
+		</div>
+	</x3d>
+	<p>Dynamic childtree update</p>
+	<input type="button" value="Add Child" onclick="addNode();">
+	<input type="button" value="Remove Child" onclick="removeNode();">
+	<script type="text/javascript">
+		function addNode() {
+			x = Math.random() * 6 - 3;
+			y = Math.random() * 6 - 3;
+			z = Math.random() * 6 - 3;
+			s0 = Math.random() + 0.5;
+			s1 = Math.random() + 0.5;
+			s2 = Math.random() + 0.5;
+			var t = document.createElement('Transform');
+			t.setAttribute("translation", x + " " + y + " " + z);
+			t.setAttribute("scale", s0 + " " + s1 + " " + s2);
+			var s = document.createElement('Shape');
+			// Appearance Node
+			var app = document.createElement('Appearance');
+			// Material Node
+			var mat = document.createElement('Material');
+			app.appendChild(mat);
+			s.appendChild(app);
+			t.appendChild(s);
+			var b = document.createElement('Box');
+			s.appendChild(b);
+			var ot = document.getElementById('root');
+			ot.appendChild(t);
+			return false;
+		};
+		function removeNode() {
+			var ot = document.getElementById('root');
+			for (var i = 0; i < ot.childNodes.length; i++) {
+				// check if we have a real X3DOM Node; not just e.g. a Text-tag
+				if (ot.childNodes[i].nodeType === Node.ELEMENT_NODE) {
+					ot.removeChild(ot.childNodes[i]);
+					break;
+				}
+			}
+			return false;
+		};
+	</script>
+	<script type="text/javascript" src="./x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/barchart.html b/public/X3DOMTutorial/barchart.html
new file mode 100644
index 0000000000000000000000000000000000000000..56986943b9f5d685e858f59159d7afcc3d644b5d
--- /dev/null
+++ b/public/X3DOMTutorial/barchart.html
@@ -0,0 +1,162 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> Bar Chart </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> Coordinate system </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<background transparency='0' skyColor='1 1 1'> </background>
+						<!-- Invoke CoordinateAxes in other scenes as an Inline child inside a scaling Transform node, at the topmost level of the scene graph. -->
+						<!-- Each arrow goes from +1m to -1m to allow linear scaling to fit a scene -->
+						<!-- Note each label rotates about the scene's vertical Y axis for consistency, enabling local orientation by user -->
+						<Group>
+							<!-- Vertical Y arrow and label -->
+							<Group DEF='ArrowGreen'>
+								<Transform translation='0 1 0'>
+									<Shape>
+										<Appearance DEF='Green'>
+											<Material diffuseColor='0 1 0'> </Material>
+										</Appearance>
+										<Cylinder DEF='ArrowCylinder' radius='.025' top='false'> </Cylinder>
+									</Shape>
+								</Transform>
+								<Transform translation='0 2 0'>
+									<Shape>
+										<Appearance USE='Green'> </Appearance>
+										<Cone DEF='ArrowCone' bottomRadius='.05' height='.1'> </Cone>
+									</Shape>
+								</Transform>
+							</Group>
+							<Transform translation='0 2.08 0'>
+								<Billboard>
+									<Shape>
+										<Appearance DEF='LABEL_APPEARANCE'>
+											<Material diffuseColor='0 0 0'> </Material>
+										</Appearance>
+										<Text id='chartlabel-y' string='"year"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+							<Transform rotation='0 0 1 -1.57079'>
+								<!-- Horizontal X arrow and label -->
+								<Group DEF='ArrowRed'>
+									<Transform translation='0 1 0'>
+										<Shape>
+											<Appearance DEF='Red'>
+												<Material diffuseColor='.7 .1 .1' emissiveColor='.33 0 0' />
+											</Appearance>
+											<Cylinder USE='ArrowCylinder'> </Cylinder>
+										</Shape>
+									</Transform>
+									<Transform translation='0 2 0'>
+										<Shape>
+											<Appearance USE='Red'> </Appearance>
+											<Cone USE='ArrowCone'> </Cone>
+										</Shape>
+									</Transform>
+								</Group>
+								<Transform rotation='0 0 1 1.57079' translation='0 2 0'>
+									<!-- note label rotated back to original coordinate frame -->
+									<Billboard>
+										<Shape>
+											<Appearance USE='LABEL_APPEARANCE'>
+											</Appearance>
+											<Text id='chartlabel-x' string='"building id"'>
+												<FontStyle USE='LABEL_FONT'>
+											</Text>
+										</Shape>
+									</Billboard>
+								</Transform>
+							</Transform>
+							<!-- bars -->
+							<Transform id="bar1" translation='0.25 0.5 0'>
+								<Shape>
+									<Appearance DEF='BAR_COLOR'>
+										<Material diffuseColor='1 0 1'>
+										</Material>
+									</Appearance>
+									<Box size='0.025 1 0.025'> </Box>
+								</Shape>
+							</Transform>
+							<Transform id="bar2" translation='0.75 0.5 0'>
+								<Shape>
+									<Appearance USE='BAR_COLOR'>
+									</Appearance>
+									<Box size='0.025 1.0 0.025'> </Box>
+								</Shape>
+							</Transform>
+							<Transform id="bar3" translation='1.25 0.5 0'>
+								<Shape>
+									<Appearance USE='BAR_COLOR'>
+									</Appearance>
+									<Box size='0.025 1.0 0.025'> </Box>
+								</Shape>
+							</Transform>
+							<Transform id="bar4" translation='1.75 0.5 0'>
+								<Shape>
+									<Appearance USE='BAR_COLOR'>
+									</Appearance>
+									<Box size='0.025 1.0 0.025'> </Box>
+								</Shape>
+							</Transform>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				Bar chart example <br> <br>
+				label x-axis: <input type="text" id="label-x" value="building id" size="12" /> <br>
+				label y-axis: <input type="text" id="label-y" value="year" size="12" /><br>
+				attribute year of construction: <br>
+				<input type="text" id="yoc-b1" value="1960" size="12" /><br>
+				<input type="text" id="yoc-b2" value="1968" size="12" /><br>
+				<input type="text" id="yoc-b3" value="1980" size="12" /><br>
+				<input type="text" id="yoc-b4" value="1985" size="12" /><br>
+				<input type="button" value="draw" onclick="drawBarChart()" /> <br>
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+			<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
+			<script>
+				function drawBarChart() {
+					var labelx = document.getElementById("label-x").value;
+					var chartlabelx = document.getElementById("chartlabel-x");
+					chartlabelx.setAttribute("string", labelx);
+					var labely = document.getElementById("label-y").value;
+					var chartlabely = document.getElementById("chartlabel-y");
+					chartlabely.setAttribute("string", labely);
+					var yocb1 = document.getElementById("yoc-b1").value;
+					var yocb2 = document.getElementById("yoc-b2").value;
+					var yocb3 = document.getElementById("yoc-b3").value;
+					var yocb4 = document.getElementById("yoc-b4").value;
+					yocb1 = (yocb1 - 1950) / 10;
+					var bar1 = document.getElementById("bar1");
+					bar1.setAttribute("translation", "0.25 " + yocb1 / 2.0 + " 0");
+					bar1.setAttribute("scale", "1 " + yocb1 + " 1");
+					yocb2 = (yocb2 - 1950) / 10;
+					var bar2 = document.getElementById("bar2");
+					bar2.setAttribute("translation", "0.75 " + yocb2 / 2.0 + " 0");
+					bar2.setAttribute("scale", "1 " + yocb2 + " 1");
+					yocb3 = (yocb3 - 1950) / 10;
+					var bar3 = document.getElementById("bar3");
+					bar3.setAttribute("translation", "1.25 " + yocb3 / 2.0 + " 0");
+					bar3.setAttribute("scale", "1 " + yocb3 + " 1");
+					yocb4 = (yocb4 - 1950) / 10;
+					var bar4 = document.getElementById("bar4");
+					bar4.setAttribute("translation", "1.75 " + yocb4 / 2.0 + " 0");
+					bar4.setAttribute("scale", "1 " + yocb4 + " 1");
+				}
+			</script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/colorbrewer.html b/public/X3DOMTutorial/colorbrewer.html
new file mode 100644
index 0000000000000000000000000000000000000000..4597adf03c76b4b40d2d713dd2bca7848d92c80c
--- /dev/null
+++ b/public/X3DOMTutorial/colorbrewer.html
@@ -0,0 +1,137 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Material brewer</title>
+  <link rel="stylesheet" type="text/css" href="x3dom.css"></link>
+</head>
+
+<body class="ui-widget-content" style="border:0;">
+  <table width="100%" height="85%" border="0">
+    <tr>
+      <td width="50%" align="center" valign="top" scope="col">
+        <X3D id="shapedata" width="600px" height="600px" style="float:left">
+          <Scene>
+            <Shape>
+              <Appearance>
+                <Material id="material"> </Material>
+              </Appearance>
+              <Sphere radius="2.0"> </Sphere>
+            </Shape>
+          </Scene>
+        </X3D>
+      </td>
+      <td width="50%" align="left" valign="top" scope="col">
+        The following example will show you haw to interactively modify the 3D scene.
+        See <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/components/shape.html#Material"
+          target="_blank">
+          X3D Material node definition </a> for an explanation of the different color attributes.
+          <br>
+          <br><b>ambientIntensity</b><br>
+        ambientIntensity: 0 <input type="range" id="ambientIntensity" min="0.0" max="1.0" step="0.05" value="0.2"
+          onchange="changeColor()" />1<br>
+        <br>
+        <b>diffue color</b>
+        <br>
+        red: 0 <input type="range" id="diffuse_r" min="0.0" max="1.0" step="0.05" value="0.8"
+          onchange="changeColor()" />1<br>
+        green: 0 <input type="range" id="diffuse_g" min="0.0" max="1.0" step="0.05" value="0.8"
+          onchange="changeColor()" />1<br>
+        blue: 0 <input type="range" id="diffuse_b" min="0.0" max="1.0" step="0.05" value="0.8"
+          onchange="changeColor()" />1<br>
+        <br><b>emissive color</b><br>
+        red: 0 <input type="range" id="emissive_r" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        green: 0 <input type="range" id="emissive_g" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        blue: 0 <input type="range" id="emissive_b" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        <br>
+        <b>specular color</b>
+        <br>
+        red: 0 <input type="range" id="specular_r" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        green: 0 <input type="range" id="specular_g" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        blue: 0 <input type="range" id="specular_b" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        <br>
+        <b>shininess</b>
+        <br>
+        shininess: 0 <input type="range" id="shininess" min="0.0" max="1.0" step="0.05" value="0.2"
+          onchange="changeColor()" />1<br>
+        <br>
+        <b>transparency</b>
+        <br>
+        transparency : 0 <input type="range" id="transparency" min="0.0" max="1.0" step="0.05" value="0.0"
+          onchange="changeColor()" />1<br>
+        <br>
+        <p>
+          <br><br>
+          The diffuse color of a material will be interactively changed.
+          A JavaScript <a href="http://jqueryui.com/slider/#colorpicker target=" _blank"> RGB color picker </a> is used
+          and modified.
+          If the RGB color value is changed, the diffuse material of the sphere shall be changed as well. So we need to
+          get the Material node first.
+          This is done by the getElementById function in X3DOM. Of course, the Material node needs to have an unique id.
+        <pre>
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	  &lt;Scene&gt;
+	    &lt;Shape&gt; 
+   	      &lt;Appearance&gt;
+     	        &lt;Material id="material" diffuseColor="0.980, 0.502, 0.447"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+	      &lt;Sphere radius="2.0"&gt; &lt;/Sphere&gt;
+ 	    &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+	&lt;/X3D&gt;
+    </pre>
+        <br>
+        For example, if the diffuse color should be set to red, the Material node is referenced by its id and the
+        attribute diffuseColor is set to
+        "1.0 0.0 0.0". The attribute value is always a string.
+        <pre>
+    var mat = document.getElementById("material");
+    mat.setAttribute("diffuseColor", "1.0 0.0 0.0");      
+    </pre>
+        In the example, the RGB value is fetched from the slider.
+        <pre>
+      var mat = document.getElementById("material");
+      rgbstring = " "+ red + " " + green + " " + blue;
+      mat.setAttribute("diffuseColor", rgbstring);
+    </pre>
+        </p>
+      </td>
+      <script type="text/javascript" src="x3dom.js"></script>
+      <script>
+        /**
+        * Change the settings of the directional light
+        *
+        * @param field string: Name of the field
+        * @param value number: New value to set
+        */
+        function changeColor() {
+          var material = document.getElementById("material");
+          var emissive_rgb = " " + document.getElementById("emissive_r").value;
+          emissive_rgb += " " + document.getElementById("emissive_g").value;
+          emissive_rgb += " " + document.getElementById("emissive_b").value;
+          material.setAttribute("emissiveColor", emissive_rgb);
+          var diffuse_rgb = " " + document.getElementById("diffuse_r").value;
+          diffuse_rgb += " " + document.getElementById("diffuse_g").value;
+          diffuse_rgb += " " + document.getElementById("diffuse_b").value;
+          material.setAttribute("diffuseColor", diffuse_rgb);
+          var specular_rgb = " " + document.getElementById("specular_r").value;
+          specular_rgb += " " + document.getElementById("specular_g").value;
+          specular_rgb += " " + document.getElementById("specular_b").value;
+          material.setAttribute("specularColor", specular_rgb);
+          var ambientIntensity = " " + document.getElementById("ambientIntensity").value;
+          material.setAttribute("ambientIntensity", ambientIntensity);
+          var shininess = " " + document.getElementById("shininess").value;
+          material.setAttribute("shininess", shininess);
+          var transparency = " " + document.getElementById("transparency").value;
+          material.setAttribute("transparency", transparency);
+        }
+      </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/colorbrewer2.html b/public/X3DOMTutorial/colorbrewer2.html
new file mode 100644
index 0000000000000000000000000000000000000000..41fc20fb15eb3c47033acb465e7e1104c3e485d4
--- /dev/null
+++ b/public/X3DOMTutorial/colorbrewer2.html
@@ -0,0 +1,133 @@
+<html>
+
+<head>
+  <meta charset="utf-8">
+  <title>Material brewer</title>
+  <!-- source Colorpicker slider: http://jqueryui.com/slider/#colorpicker -->
+  <link rel="stylesheet" type="text/css" href="x3dom.css">
+  <link rel="stylesheet" href="http://code.jquery.com/ui/1.10.4/themes/smoothness/jquery-ui.css">
+  </link>
+  <script src="http://code.jquery.com/jquery-1.10.2.js"></script>
+  <script src="http://code.jquery.com/ui/1.10.4/jquery-ui.js"></script>
+  </link>
+  <style>
+    #red,
+    #green,
+    #blue {
+      float: left;
+      clear: left;
+      width: 300px;
+      margin: 15px;
+    }
+
+    #red .ui-slider-range {
+      background: #ef2929;
+    }
+
+    #red .ui-slider-handle {
+      border-color: #ef2929;
+    }
+
+    #green .ui-slider-range {
+      background: #8ae234;
+    }
+
+    #green .ui-slider-handle {
+      border-color: #8ae234;
+    }
+
+    #blue .ui-slider-range {
+      background: #729fcf;
+    }
+
+    #blue .ui-slider-handle {
+      border-color: #729fcf;
+    }
+  </style>
+</head>
+
+<body class="ui-widget-content" style="border:0;">
+  <table width="100%" height="85%" border="0">
+    <tr>
+      <td width="50%" align="center" valign="top" scope="col">
+        <X3D id="shapedata" width="600px" height="600px" style="float:left">
+          <Scene>
+            <Shape>
+              <Appearance>
+                <Material id="material" diffuseColor="0.980, 0.502, 0.447"> </Material>
+              </Appearance>
+              <Sphere radius="2.0"> </Sphere>
+            </Shape>
+          </Scene>
+        </X3D>
+      </td>
+      <td width="50%" align="left" valign="top" scope="col">
+        <p>The following example will show you haw to interactively modify the 3D scene.</p>
+        <div id="red"></div>
+        <div id="green"></div>
+        <div id="blue"></div>
+        <p>
+          <br><br><br><br><br><br><br><br><br><br>
+          The diffuse color of a material will be interactively changed.
+          A JavaScript <a href="http://jqueryui.com/slider/#colorpicker target=" _blank"> RGB color picker </a> is used
+          and modified.
+          If the RGB color value is changed, the diffuse material of the sphere shall be changed as well. So we need to
+          get the Material node first.
+          This is done by the getElementById function in X3DOM. Of course, the Material node needs to have an unique id.
+        <pre>
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	  &lt;Scene&gt;
+	    &lt;Shape&gt; 
+   	      &lt;Appearance&gt;
+     	        &lt;Material id="material" diffuseColor="0.980, 0.502, 0.447"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+	      &lt;Sphere radius="2.0"&gt; &lt;/Sphere&gt;
+ 	    &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+	&lt;/X3D&gt;
+    </pre>
+        <br>
+        For example, if the diffuse color should be set to red, the Material node is referenced by its id and the
+        attribute diffuseColor is set to
+        "1.0 0.0 0.0". The attribute value is always a string.
+        <pre>
+    var mat = document.getElementById("material");
+    mat.setAttribute("diffuseColor", "1.0 0.0 0.0");      
+    </pre>
+        In the example, the RGB value is fetched from the slider. As the slider gives the RGB values between 0 and 255,
+        they have to be transformed to
+        arithmetic values between 0.0 and 1.0. After that, the RBG value has to be formatted as string.
+        <pre>
+      var mat = document.getElementById("material");
+      rgbstring = " "+ red/255 + " " + green/255 + " " + blue/255;
+      mat.setAttribute("diffuseColor", rgbstring);
+    </pre>
+        </p>
+      </td>
+      <script type="text/javascript" src="x3dom.js"></script>
+      <script>
+        function refreshDiffuseMaterial() {
+          var red = $("#red").slider("value"),
+            green = $("#green").slider("value"),
+            blue = $("#blue").slider("value");
+          var mat = document.getElementById("material");
+          rgbstring = " " + red / 255 + " " + green / 255 + " " + blue / 255;
+          mat.setAttribute("diffuseColor", rgbstring);
+        }
+        $(function () {
+          $("#red, #green, #blue").slider({
+            orientation: "horizontal",
+            range: "min",
+            max: 255,
+            value: 127,
+            slide: refreshDiffuseMaterial,
+            change: refreshDiffuseMaterial
+          });
+          $("#red").slider("value", 255);
+          $("#green").slider("value", 140);
+          $("#blue").slider("value", 60);
+        });
+      </script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/coordinatesystem.html b/public/X3DOMTutorial/coordinatesystem.html
new file mode 100644
index 0000000000000000000000000000000000000000..a1524c3a2c614644cb97847e4b3cf6967333cc76
--- /dev/null
+++ b/public/X3DOMTutorial/coordinatesystem.html
@@ -0,0 +1,119 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> Coordinate system </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> Coordinate system </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<background transparency='0' skyColor='1 1 1'> </background>
+						<!-- Invoke CoordinateAxes in other scenes as an Inline child inside a scaling Transform node, at the topmost level of the scene graph. -->
+						<!-- Each arrow goes from +1m to -1m to allow linear scaling to fit a scene -->
+						<!-- Note each label rotates about the scene's vertical Y axis for consistency, enabling local orientation by user -->
+						<Group>
+							<!-- Vertical Y arrow and label -->
+							<Group DEF='ArrowGreen'>
+								<Shape>
+									<Appearance DEF='Green'>
+										<Material diffuseColor='0 1 0'> </Material>
+									</Appearance>
+									<Cylinder DEF='ArrowCylinder' radius='.025' top='false'> </Cylinder>
+								</Shape>
+								<Transform translation='0 1 0'>
+									<Shape>
+										<Appearance USE='Green'> </Appearance>
+										<Cone DEF='ArrowCone' bottomRadius='.05' height='.1'> </Cone>
+									</Shape>
+								</Transform>
+							</Group>
+							<Transform translation='0 1.08 0'>
+								<Billboard>
+									<Shape>
+										<Appearance DEF='LABEL_APPEARANCE'>
+											<Material diffuseColor='0 0 0'> </Material>
+										</Appearance>
+										<Text string='"Y"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+							<Transform rotation='0 0 1 -1.57079'>
+								<!-- Horizontal X arrow and label -->
+								<Group DEF='ArrowRed'>
+									<Shape>
+										<Appearance DEF='Red'>
+											<Material diffuseColor='.7 .1 .1' emissiveColor='.33 0 0' />
+										</Appearance>
+										<Cylinder USE='ArrowCylinder'> </Cylinder>
+									</Shape>
+									<Transform translation='0 1 0'>
+										<Shape>
+											<Appearance USE='Red'> </Appearance>
+											<Cone USE='ArrowCone'> </Cone>
+										</Shape>
+									</Transform>
+								</Group>
+								<Transform rotation='0 0 1 1.57079' translation='.072 1.1 0'>
+									<!-- note label rotated back to original coordinate frame -->
+									<Billboard>
+										<Shape>
+											<Appearance USE='LABEL_APPEARANCE'>
+											</Appearance>
+											<Text string='"X"'>
+												<FontStyle USE='LABEL_FONT'>
+											</Text>
+										</Shape>
+									</Billboard>
+								</Transform>
+							</Transform>
+							<Transform rotation='1 0 0 1.57079'>
+								<!-- Z arrow and label -->
+								<Group DEF='ArrowBlue'>
+									<Shape>
+										<Appearance DEF='Blue'>
+											<Material diffuseColor='0  0 1'> </Material>
+										</Appearance>
+										<Cylinder USE='ArrowCylinder'> </Cylinder>
+									</Shape>
+									<Transform translation='0 1 0'>
+										<Shape>
+											<Appearance USE='Blue'> </Appearance>
+											<Cone USE='ArrowCone'> </Cone>
+										</Shape>
+									</Transform>
+								</Group>
+								<Transform rotation='1 0 0 -1.57079' translation='0 1.1 .072'>
+									<!-- note label rotated back to original coordinate frame -->
+									<Billboard>
+										<Shape>
+											<Appearance USE='LABEL_APPEARANCE'>
+											</Appearance>
+											<Text string='"Z"'>
+												<FontStyle USE='LABEL_FONT'>
+											</Text>
+										</Shape>
+									</Billboard>
+								</Transform>
+							</Transform>
+						</Group>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				In X3DOM, a right hand coordinate system is used. The Y-axis is pointing up. <br> <br>
+				<img src="http://flylib.com/books/2/416/1/html/2/images/fig3-3.jpg" width="350" height="310" />
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/hellox3dom.html b/public/X3DOMTutorial/hellox3dom.html
new file mode 100644
index 0000000000000000000000000000000000000000..e8b077b17d094c389c96617f105f379b953f87f9
--- /dev/null
+++ b/public/X3DOMTutorial/hellox3dom.html
@@ -0,0 +1,82 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title> Hello X3DOM </title>
+  <link rel="stylesheet" type="text/css" href="x3dom.css">
+  </link>
+</head>
+
+<body>
+  <h1> Hello X3DOM </h1>
+  <table width="100%" height="85%" border="0">
+    <tr>
+      <td width="50%" align="center" valign="top" scope="col">
+        <X3D id="shapedata" width="600px" height="600px" style="float:left">
+          <Scene>
+            <background transparency='0' skyColor='0 1 0'> </background>
+            <Shape>
+              <Box> </Box>
+            </Shape>
+          </Scene>
+        </X3D>
+        </p>
+      </td>
+      <td width="50%" align="left" valign="top" scope="col">
+        In this example, a simple 3D scene is integrated into a web page. This is done by the &lt;X3D&gt; tag in the
+        HTML document.
+        The &lt;X3D&gt; tag is interpreted by the x3dom.js Java Script library. You can either make a local copy of the
+        library or use it
+        from the server. It is recommended to use the library from the server to ensure that you always have the latest
+        version.
+        A local copy of the library is useful for development, if you are not always connected.
+        <br>
+        <pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	&lt;Scene&gt; 
+          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
+            &lt;Shape id=box&gt; 
+              &lt;Box&gt; &lt;/Box&gt;
+            &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+        &lt;/X3D&gt;  
+        </pre>
+        The &lt;X3D&gt; tag defines the size of the 3D canvas on the web page as well as the scene graph.
+        An <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/concepts.html#scenegraph"
+          target="_blank"> X3D scene graph </a>
+        is defined as a directed acyclic graph.
+        The nodes of the scene graph will be rendered on the screen from a given camera position.
+        The default camera position is (0,0,10) pointing to the negative z-Axis.
+        So objects at the center of the coordinate system will be displayed on the screen.
+        A shape node contains a geometry. In this example, it is a simple box. The center of the box is at (0,0,0) with
+        default size 2 in all dimensions
+        <br>
+        The color of the background can be changed in the attribute skyColor. Currently it is red.
+        The color is defined using <a href="http://en.wikipedia.org/wiki/RGB_color_model" target="_blank"> RGB color
+          model </a>
+        with arithmetic notation (0.0 t0 1.0 per value). <br>
+        The color of the Box can be changed by applying an appearance to the shape node.
+        In X3D, the <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/index.html" target="_blank"> Shape
+          node </a> associates a geometry node with
+        nodes that define that geometry's appearance. The following example draws a blue box.
+        <pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	&lt;Scene&gt; 
+          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
+            &lt;Shape id=box&gt; 
+              &lt;appearance &gt; 
+                &lt;material diffuseColor='0 0 1'&gt;&lt;/material&gt; 
+              &lt;/appearance&gt; 
+              &lt;Box&gt; &lt;/Box&gt;
+            &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+        &lt;/X3D&gt;  
+        </pre>
+        <shape>
+          <box></box>
+        </shape>
+      </td>
+      <script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/ifsandmaterial.html b/public/X3DOMTutorial/ifsandmaterial.html
new file mode 100644
index 0000000000000000000000000000000000000000..e4b4a966181ea7ff450139b9e01f2b9211a2dfe4
--- /dev/null
+++ b/public/X3DOMTutorial/ifsandmaterial.html
@@ -0,0 +1,103 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> indexed face set and material </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1>indexed face set and material</h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<Shape>
+							<!-- roof -->
+							<Appearance>
+								<Material diffuseColor="0.980, 0.502, 0.447"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex="  7 4 8 -1 4 5 8 -1 5 6 8 -1 6 7 8 -1">
+								<Coordinate DEF="pointset" point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 ">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+						<Shape>
+							<!-- wall -->
+							<Appearance>
+								<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1 3 0 4 7 -1">
+								<Coordinate USE="pointset">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+						<Shape>
+							<!-- ground -->
+							<Appearance>
+								<Material diffuseColor="0.180, 0.280, 0.230"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 3 2 1 -1 ">
+								<Coordinate USE="pointset">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				One shape has only ony appearance. If different colors for the building elements roof, wall and ground surfaces
+				shall be used,
+				we need to have different shape for these elements. However, they can share the same point set. The following
+				example uses different
+				Material for roo, wall, and ground surfaces.
+				<br>
+				<pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	  &lt;Scene&gt;
+	    &lt;Shape&gt;
+	      &lt;!-- roof --&gt;
+   	      &lt;Appearance&gt;
+     	        &lt;Material diffuseColor="0.980, 0.502, 0.447"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+  	      &lt;IndexedFaceSet solid="true" ccw ="true" 
+   	        coordIndex="  7 4 8 -1 4 5 8 -1 5 6 8 -1 6 7 8 -1"&gt;
+   	        &lt;Coordinate DEF="pointset" point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 " &gt; 
+   	        &lt;/Coordinate&gt;
+	      &lt;/IndexedFaceSet&gt;
+	    &lt;/Shape&gt;
+	    &lt;Shape&gt;
+	      &lt;!-- wall --&gt;
+   	      &lt;Appearance&gt;
+     	        &lt;Material diffuseColor="0.753, 0.753, 0.753"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+  	      &lt;IndexedFaceSet solid="true" ccw ="true" 
+   	        coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1 3 0 4 7 -1"&gt;
+   	        &lt;Coordinate USE="pointset" &gt; 
+   	        &lt;/Coordinate&gt;
+	      &lt;/IndexedFaceSet&gt;
+	    &lt;/Shape&gt;
+	    &lt;Shape&gt;
+	      &lt;!-- ground --&gt;
+   	      &lt;Appearance&gt;
+     	        &lt;Material diffuseColor="0.180, 0.280, 0.230"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+  	      &lt;IndexedFaceSet solid="true" ccw ="true" 
+   	        coordIndex=" 0 3 2 1 -1 "&gt;
+   	        &lt;Coordinate USE="pointset" &gt; 
+   	        &lt;/Coordinate&gt;
+	      &lt;/IndexedFaceSet&gt;
+	    &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+	&lt;/X3D&gt;
+        </pre>
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/ifsandtexturecoord.html b/public/X3DOMTutorial/ifsandtexturecoord.html
new file mode 100644
index 0000000000000000000000000000000000000000..9b78f88d6ecd46df2585cc550a26cd66de0c1e9e
--- /dev/null
+++ b/public/X3DOMTutorial/ifsandtexturecoord.html
@@ -0,0 +1,94 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> indexed face set and material </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+</head>
+
+<body>
+	<h1> indexed face set and material </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<Shape>
+							<!-- roof -->
+							<Appearance>
+								<Material diffuseColor="0.980, 0.502, 0.447"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex="  7 4 8 -1 4 5 8 -1 5 6 8 -1 6 7 8 -1">
+								<Coordinate DEF="pointset" point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 ">
+								</Coordinate>
+								<TextureCoordinate DEF="texcoord" point="0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0">
+									</TextureCoorinate>
+							</IndexedFaceSet>
+						</Shape>
+						<Shape>
+							<!-- wall 1  -->
+							<Appearance>
+								<ImageTexture
+									url="http://upload.wikimedia.org/wikipedia/commons/thumb/d/d1/Brick_wall_close-up_view.jpg/800px-Brick_wall_close-up_view.jpg">
+								</ImageTexture>
+								<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex="0 1 5 4 -1 ">
+								<Coordinate USE="pointset">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+						<Shape>
+							<!-- wall -->
+							<Appearance>
+								<ImageTexture
+									url="http://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Peach_Rinkysplash.jpg/800px-Peach_Rinkysplash.jpg">
+								</ImageTexture>
+								<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex=" 1 2 6 5 -1 2 3 7 6 -1 3 0 4 7 -1"
+								texCoordIndex="0 1 2 3 -1 0 1 2 3 -1 0 1 2 3">
+								<Coordinate USE="pointset">
+								</Coordinate>
+								<TextureCoordinate USE="texcoord">
+									</TextureCoorinate>
+							</IndexedFaceSet>
+						</Shape>
+						<Shape>
+							<!-- ground -->
+							<Appearance>
+								<Material diffuseColor="0.180, 0.280, 0.230"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 3 2 1 -1 ">
+								<Coordinate USE="pointset">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				Example: <a href="http://doc.x3dom.org/tutorials/basics/imagesMovies/index.html" target="_blank"> Using Images
+					and Movies as Textures </a>
+				<br>
+				<a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/components/texturing.html"
+					target="_blank"> Textures </a>
+				<br>
+				<a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/components/geometry3D.html#IndexedFaceSet"
+					target="_blank">
+					How Textures are mapped on IndexedFaceSet:
+				</a><br>
+				<br>
+				<pre class="prettyprint">
+	      &lt;Appearance&gt;
+                &lt;ImageTexture  url="http://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Peach_Rinkysplash.jpg/800px-Peach_Rinkysplash.jpg"&gt;&lt;/ImageTexture&gt;              
+     	        &lt;Material diffuseColor="0.753, 0.753, 0.753"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+        </pre>
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/ifsandtextures.html b/public/X3DOMTutorial/ifsandtextures.html
new file mode 100644
index 0000000000000000000000000000000000000000..54b9bb213efe41004b0f95cda09901e52da6c13f
--- /dev/null
+++ b/public/X3DOMTutorial/ifsandtextures.html
@@ -0,0 +1,87 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> indexed face set and material </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+</head>
+
+<body>
+	<h1> indexed face set and material <h1>
+			<table width="100%" height="85%" border="0">
+				<tr>
+					<td width="50%" align="center" valign="top" scope="col">
+						<X3D id="shapedata" width="600px" height="600px" style="float:left">
+							<Scene>
+								<Shape>
+									<!-- roof -->
+									<Appearance>
+										<Material diffuseColor="0.980, 0.502, 0.447"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex="  7 4 8 -1 4 5 8 -1 5 6 8 -1 6 7 8 -1">
+										<Coordinate DEF="pointset" point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 ">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+								<Shape>
+									<!-- wall 1  -->
+									<Appearance>
+										<ImageTexture url="img/brick_stone_wall_0119_01_preview.jpg"></ImageTexture>
+										<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex="0 1 5 4 -1 ">
+										<Coordinate USE="pointset">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+								<Shape>
+									<!-- wall -->
+									<Appearance>
+										<ImageTexture
+											url="http://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Peach_Rinkysplash.jpg/800px-Peach_Rinkysplash.jpg">
+										</ImageTexture>
+										<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex=" 1 2 6 5 -1 2 3 7 6 -1 3 0 4 7 -1">
+										<Coordinate USE="pointset">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+								<Shape>
+									<!-- ground -->
+									<Appearance>
+										<Material diffuseColor="0.180, 0.280, 0.230"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 3 2 1 -1 ">
+										<Coordinate USE="pointset">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+							</Scene>
+						</X3D>
+						</p>
+					</td>
+					<td width="50%" align="left" valign="top" scope="col">
+						Example: <a href="http://doc.x3dom.org/tutorials/basics/imagesMovies/index.html" target="_blank"> Using
+							Images and Movies as Textures </a>
+						<br>
+						<a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/components/texturing.html"
+							target="_blank"> Textures </a>
+						<br>
+						<a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/components/geometry3D.html#IndexedFaceSet"
+							target="_blank">
+							How Textures are mapped on IndexedFaceSet:
+						</a><br>
+						<br>
+						<pre class="prettyprint">
+	      &lt;Appearance&gt;
+                &lt;ImageTexture  url="http://upload.wikimedia.org/wikipedia/commons/thumb/0/09/Peach_Rinkysplash.jpg/800px-Peach_Rinkysplash.jpg"&gt;&lt;/ImageTexture&gt;              
+     	        &lt;Material diffuseColor="0.753, 0.753, 0.753"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+        </pre>
+					</td>
+					<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/img/HFT_DL3_CMYK_maxH27mm.jpg b/public/X3DOMTutorial/img/HFT_DL3_CMYK_maxH27mm.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..4088489bbe11178930839bb58107ac76fe3169d7
Binary files /dev/null and b/public/X3DOMTutorial/img/HFT_DL3_CMYK_maxH27mm.jpg differ
diff --git a/public/X3DOMTutorial/img/Logo_bisH27mm.jpg b/public/X3DOMTutorial/img/Logo_bisH27mm.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..086f02e48343496c54366fa43b0eaf6f9a44ff54
Binary files /dev/null and b/public/X3DOMTutorial/img/Logo_bisH27mm.jpg differ
diff --git a/public/X3DOMTutorial/img/brick_stone_wall_0119_01_preview.jpg b/public/X3DOMTutorial/img/brick_stone_wall_0119_01_preview.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..1e4f259a232c68b8a2a5ff904a86468a50bafa4e
Binary files /dev/null and b/public/X3DOMTutorial/img/brick_stone_wall_0119_01_preview.jpg differ
diff --git a/public/X3DOMTutorial/index.html b/public/X3DOMTutorial/index.html
index b846fd8f0c7b932a95b08190af5d623fda0f88fe..5b33f281092451f43745b87fd3f59f9c336280fd 100644
--- a/public/X3DOMTutorial/index.html
+++ b/public/X3DOMTutorial/index.html
@@ -1,92 +1,61 @@
-<html xmlns="http://www.w3.org/1999/xhtml">
-<head>
-<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
-<title> Hello X3DOM </title>
-  <link rel="stylesheet" type="text/css" href="https://x3dom.org/download/1.8.1/x3dom.css"></link>
-  <script type="text/javascript" src = "https://x3dom.org/download/1.8.1/x3dom.js"></script>
-  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
+<html lang="en">
 
+<head>
+  <meta charset="UTF-8">
+  <meta name="viewport" content="width=device-width, initial-scale=1.0">
+  <title>X3DOM Tutorials</title>
+  <style>
+    ul {
+      list-style-type: none;
+      padding: 0;
+      margin: 0;
+    }
+
+    .button {
+      text-decoration: none;
+      display: block;
+      width: 500px;
+      height: 25px;
+      color: black;
+      background: lightgray;
+      padding: 10px;
+      text-align: center;
+      border-radius: 5px;
+      line-height: 25px;
+      margin-bottom: 10px;
+      font-family: sans-serif;
+    }
+
+    .button:hover {
+      background-color: #4CAF50;
+      color: white;
+    }
+
+    .center {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+  </style>
 </head>
 
 <body>
-
-<font size="4"> Hello X3DOM </font>
-
-<table width="100%" height="85%" border="0">
-  <tr>
-    <th width="50%" align="center" valign="top" scope="col">
-
-	<X3D id="shapedata" width="600px" height="600px" style="float:left">
-	  <Scene>
-		
-		<background transparency='0' skyColor='0 1 0'> </background>
-                <Shape> 
-                  <Box> </Box>
-                </Shape>
-           	
-	  </Scene>
-        </X3D>
-		
-        </p>	
-	</th>
-    
-    <th width="50%" align="left" valign="top" scope="col">
-        In this example, a simple 3D scene is integrated into a web page. This is done by the &lt;X3D&gt; tag in the HTML document. 
-        The &lt;X3D&gt; tag is interpreted by the x3dom.js Java Script library. You can either make a local copy of the library or use it 
-        from the server. It is recommended to use the library from the server to ensure that you always have the latest version.
-        A local copy of the library is useful for development, if you are not always connected.
-        <br>
-
-        <pre class="prettyprint">
-
-	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
-	&lt;Scene&gt; 
-          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
-            &lt;Shape id=box&gt; 
-              &lt;Box&gt; &lt;/Box&gt;
-            &lt;/Shape&gt;
-	  &lt;/Scene&gt;
-        &lt;/X3D&gt;  
-        </pre>
-        
-        
-        The &lt;X3D&gt; tag defines the size of the 3D canvas on the web page as well as the scene graph. 
-        An <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/concepts.html#scenegraph" target="_blank"> X3D scene graph </a>
-        is defined as a directed acyclic graph.  
-        
-        The nodes of the scene graph will be rendered on the screen from a given camera position. 
-        The default camera position is (0,0,10) pointing to the negative z-Axis. 
-        So objects at the center of the coordinate system will be displayed on the screen.
-        A shape node contains a geometry. In this example, it is a simple box. The center of the box is at (0,0,0) with default size 2 in all dimensions
-        <br>
-        The color of the background can be changed in the attribute skyColor. Currently it is red. 
-        The color is defined using <a href="http://en.wikipedia.org/wiki/RGB_color_model" target="_blank"> RGB color model </a>
-        with arithmetic notation (0.0 t0 1.0 per value). <br>
-
-        The color of the Box can be changed by applying an appearance to the shape node. 
-        In X3D, the <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/index.html" target="_blank"> Shape node </a> associates a geometry node with 
-        nodes that define that geometry's appearance. The following example draws a blue box.
-
-        <pre class="prettyprint">
-
-	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
-	&lt;Scene&gt; 
-          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
-            &lt;Shape id=box&gt; 
-              &lt;appearance &gt; 
-                &lt;material diffuseColor='0 0 1'&gt;&lt;/material&gt; 
-              &lt;/appearance&gt; 
-              &lt;Box&gt; &lt;/Box&gt;
-            &lt;/Shape&gt;
-	  &lt;/Scene&gt;
-        &lt;/X3D&gt;  
-        </pre>
-
-    <shape> 
-
-        <box></box> 
-    </shape> 
-    </th>
-        
+  <ul class="center">
+    <li><a class="button" href="hellox3dom.html">hello X3DOM</a></li>
+    <li><a class="button" href="coordinatesystem.html">coordinate system</a></li>
+    <li><a class="button" href="transform.html">transform</a></li>
+    <li><a class="button" href="colorbrewer.html">color brewer</a></li>
+    <li><a class="button" href="colorbrewer2.html">color brewer 2</a></li>
+    <li><a class="button" href="indexedfaceset.html">indexedfaceset</a></li>
+    <li><a class="button" href="indexedfaceset2.html">indexedfaceset 2</a></li>
+    <li><a class="button" href="ifsandmaterial.html">indexedfaceset and material</a></li>
+    <li><a class="button" href="ifsandtexturecoord.html">indexedfaceset and texture coord</a></li>
+    <li><a class="button" href="ifsandtextures.html">indexedfaceset and textures</a></li>
+    <li><a class="button" href="terrain.html">terrain</a></li>
+    <li><a class="button" href="barchart.html">barchart</a></li>
+    <li><a class="button" href="toytown.html">toy town</a></li>
+    <li><a class="button" href="addnode.html">add node</a></li>
+  </ul>
 </body>
+
 </html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/indexedfaceset.html b/public/X3DOMTutorial/indexedfaceset.html
new file mode 100644
index 0000000000000000000000000000000000000000..997415b6c8176169fc3c7262481cc65ac2439fb3
--- /dev/null
+++ b/public/X3DOMTutorial/indexedfaceset.html
@@ -0,0 +1,244 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> Indexed Face Set </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> Indexed Face Set </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<Shape>
+							<Appearance>
+								<Material diffuseColor="0.5 0.5 0.5"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1
+                             3 0 4 7 -1 0 3 2 1 -1 7 4 8 -1
+                             4 5 8 -1 5 6 8 -1 6 7 8 -1">
+								<Coordinate point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 ">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+						<!-- add points (as spheres) and labels -->
+						<!-- P0 -->
+						<Transform translation='-1 0 1'>
+							<Shape DEF='Point'>
+								<Appearance DEF='Green'>
+									<Material diffuseColor='0 1 0'> </Material>
+								</Appearance>
+								<Sphere radius="0.1"> </Sphere>
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance DEF='LABEL_APPEARANCE'>
+											<Material diffuseColor='0 0 0'> </Material>
+										</Appearance>
+										<Text string='"P0"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P1 -->
+						<Transform translation='1 0 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P1"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P2 -->
+						<Transform translation='1 0 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P2"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P3 -->
+						<Transform translation='-1 0 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P3"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P4 -->
+						<Transform translation='-1 2 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P4"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P5 -->
+						<Transform translation='1 2 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P5"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P6 -->
+						<Transform translation='1 2 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P6"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P7 -->
+						<Transform translation='-1 2 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P7"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P8 -->
+						<Transform translation='0 3 0'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 0.0 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P8"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				An IndexedFaceSet is used to define a polygonal shape. For example, it can be used to model a building.
+				The building geometry is given by a set of points P={P0, P1, ..., Pn}
+				and a set of polygons F={F0, F1, ..., Fm}. Each point Pi is given by its coordinates Pi=(xi,yi,zi).
+				Each polygon Fi is defined by a list of m coplanar points (m >=3) given in counterclockwise order:
+				Fi=(Pi0, Pi1, ... Pim)
+				<pre>
+	Example:
+	P = {P0, P1, P2, P3, P4, P5, P6, P7, P8}
+	with
+        P0 = (-1.0, 0.0,  1.0)
+	P1 = ( 1.0, 0.0,  1.0)
+	P2 = ( 1.0, 0.0, -1.0)
+	P3 = (-1.0, 0.0, -1.0)
+        P4 = (-1.0, 2.0,  1.0)
+	P5 = ( 1.0, 2.0,  1.0)
+	P6 = ( 1.0, 2.0, -1.0)
+	P7 = (-1.0, 2.0, -1.0)
+	P8 = ( 0.0, 3.0,  0.0)
+	F = {F0, F1, F2, F3, F4, F5, F6, F7, F8}
+        wall: 
+        F0 = (P0, P1, P5, P4)
+        F1 = (P1, P2, P6, P5) 
+	F2 = (P2, P3, P7, P6)
+	F3 = (P3, P0, P4, P7)
+	ground:
+	F4 = (P0, P3, P2, P1)
+	roof:
+	F5 = (P7, P4, P8)
+	F6 = (P4, P5, P8)
+	F7 = (P5, P6, P8)
+	F8 = (P6, P7, P8)
+        </pre>
+				<br>
+				In the IndexedFaceSet the point set P is defined in the Coordinate node.
+				The set of polygons F is defined in the attribute coordIndex. Each polygon is given by a list of point indices
+				followed by -1 to indicate the end of a polygon and the beginning of a new one.
+				<br>
+				<pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	  &lt;Scene&gt;
+	    &lt;Shape&gt;
+   	      &lt;Appearance&gt;
+     	        &lt;Material diffuseColor="0.5 0.5 0.5"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+  	      &lt;IndexedFaceSet solid="true" ccw ="true" 
+   	        coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1
+                             3 0 4 7 -1 0 3 2 1 -1 7 4 8 -1
+                             4 5 8 -1 5 6 8 -1 6 7 8 -1"&gt;
+   	        &lt;Coordinate point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 " &gt; 
+   	        &lt;/Coordinate&gt;
+	      &lt;/IndexedFaceSet&gt;
+	    &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+	&lt;/X3D&gt; 
+        </pre>
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/indexedfaceset2.html b/public/X3DOMTutorial/indexedfaceset2.html
new file mode 100644
index 0000000000000000000000000000000000000000..d4b02df930da0cb0d380ecb0681e609374e9b12a
--- /dev/null
+++ b/public/X3DOMTutorial/indexedfaceset2.html
@@ -0,0 +1,249 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> Indexed Face Set</title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> Indexed Face Set </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<Shape>
+							<Appearance>
+								<Material diffuseColor="0.5 0.5 0.5"> </Material>
+							</Appearance>
+							<IndexedFaceSet solid="false" ccw="true" coordIndex=" 0 4 5 1 -1 1 2 6 5 -1 2 3 7 6 -1
+                             3 0 4 7 -1 0 1 2 3 -1 7 4 8 -1
+                             4 5 8 -1 5 6 8 -1 6 7 8 -1  
+					     9 13 14 10 -1 10 11 15 14 -1 11 12 16 15 -1
+                             12 9 13 16 -1 9 10 11 12 -1 16 13 17 -1
+                             13 14 17 -1 14 15 17 -1 15 16 17 -1">
+								<Coordinate point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0, 
+							2 0 1, 4 0 1, 4 0 -1, 2 0 -1,
+             	            2 2 1, 4 2 1, 4 2 -1, 2 2 -1, 3 3 0 ">
+								</Coordinate>
+							</IndexedFaceSet>
+						</Shape>
+						<!-- add points (as spheres) and labels -->
+						<!-- P0 -->
+						<Transform translation='-1 0 1'>
+							<Shape DEF='Point'>
+								<Appearance DEF='Green'>
+									<Material diffuseColor='0 1 0'> </Material>
+								</Appearance>
+								<Sphere radius="0.1"> </Sphere>
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance DEF='LABEL_APPEARANCE'>
+											<Material diffuseColor='0 0 0'> </Material>
+										</Appearance>
+										<Text string='"P0"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P1 -->
+						<Transform translation='1 0 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P1"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P2 -->
+						<Transform translation='1 0 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P2"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P3 -->
+						<Transform translation='-1 0 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P3"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P4 -->
+						<Transform translation='-1 2 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P4"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P5 -->
+						<Transform translation='1 2 1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P5"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P6 -->
+						<Transform translation='1 2 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P6"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P7 -->
+						<Transform translation='-1 2 -1'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 -0.75 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P7"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+						<!-- P8 -->
+						<Transform translation='0 3 0'>
+							<Shape USE="Point">
+							</Shape>
+							<Transform translation='0 0.0 0'>
+								<Billboard>
+									<Shape>
+										<Appearance USE='LABEL_APPEARANCE'>
+										</Appearance>
+										<Text string='"P8"'>
+											<FontStyle DEF='LABEL_FONT' family='"SANS"' justify='"MIDDLE" "MIDDLE"' size='.2'> </FontStyle>
+										</Text>
+									</Shape>
+								</Billboard>
+							</Transform>
+						</Transform>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				An IndexedFaceSet is used to define a polygonal shape. For example, it can be used to model a building.
+				The building geometry is given by a set of points P={P0, P1, ..., Pn}
+				and a set of polygons F={F0, F1, ..., Fm}. Each point Pi is given by its coordinates Pi=(xi,yi,zi).
+				Each polygon Fi is defined by a list of m coplanar points (m >=3) given in counterclockwise order:
+				Fi=(Pi0, Pi1, ... Pim)
+				<pre>
+	Example:
+	P = {P0, P1, P2, P3, P4, P5, P6, P7, P8}
+	with
+        P0 = (-1.0, 0.0,  1.0)
+	P1 = ( 1.0, 0.0,  1.0)
+	P2 = ( 1.0, 0.0, -1.0)
+	P3 = (-1.0, 0.0, -1.0)
+        P4 = (-1.0, 2.0,  1.0)
+	P5 = ( 1.0, 2.0,  1.0)
+	P6 = ( 1.0, 2.0, -1.0)
+	P7 = (-1.0, 2.0, -1.0)
+	P8 = ( 0.0, 3.0,  0.0)
+	F = {F0, F1, F2, F3, F4, F5, F6, F7, F8}
+        wall: 
+        F0 = (P0, P1, P5, P4)
+        F1 = (P1, P2, P6, P5) 
+	F2 = (P2, P3, P7, P6)
+	F3 = (P3, P0, P4, P7)
+	ground:
+	F4 = (P0, P3, P2, P1)
+	roof:
+	F5 = (P7, P4, P8)
+	F6 = (P4, P5, P8)
+	F7 = (P5, P6, P8)
+	F8 = (P6, P7, P8)
+        </pre>
+				<br>
+				In the IndexedFaceSet the point set P is defined in the Coordinate node.
+				The set of polygons F is defined in the attribute coordIndex. Each polygon is given by a list of point indices
+				followed by -1 to indicate the end of a polygon and the beginning of a new one.
+				<br>
+				<pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	  &lt;Scene&gt;
+	    &lt;Shape&gt;
+   	      &lt;Appearance&gt;
+     	        &lt;Material diffuseColor="0.5 0.5 0.5"&gt; &lt;/Material&gt;
+   	      &lt;/Appearance&gt;
+  	      &lt;IndexedFaceSet solid="true" ccw ="true" 
+   	        coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1
+                             3 0 4 7 -1 0 3 2 1 -1 7 4 8 -1
+                             4 5 8 -1 5 6 8 -1 6 7 8 -1"&gt;
+   	        &lt;Coordinate point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 " &gt; 
+   	        &lt;/Coordinate&gt;
+	      &lt;/IndexedFaceSet&gt;
+	    &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+	&lt;/X3D&gt; 
+        </pre>
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/terrain.html b/public/X3DOMTutorial/terrain.html
new file mode 100644
index 0000000000000000000000000000000000000000..edec4877de85a089e987a5e0447b70d6b8928b57
--- /dev/null
+++ b/public/X3DOMTutorial/terrain.html
@@ -0,0 +1,92 @@
+<html>
+
+<head>
+  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+  <title>Terrain</title>
+  <link rel="stylesheet" type="text/css" href="x3dom.css">
+  </link>
+</head>
+
+<body>
+  <h1>Terrain</h1>
+  <table width="100%" height="85%" border="0">
+    <tr>
+      <td width="50%" align="center" valign="top" scope="col">
+        <X3D id="shapedata" width="600px" height="600px" style="float:left">
+          <Scene>
+            <viewpoint position="0 0 4000"></viewpoint>
+            <background transparency='0' skyColor='1 1 1'> </background>
+            <Transform rotation='1 0 0 -1.57079'>
+              <Shape>
+                <appearance>
+                  <material diffuseColor='0.9, 0.7, 0.4'></material>
+                </appearance>
+                <IndexedTriangleSet
+                  index="0 1 2 0 3 1 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 4 6 19 20 21 22 7 9 23 10 24 11 20 25 21 26 27 28 16 29 17 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 30 32 63 33 35 64 36 38 65 66 67 68 39 41 69 42 44 70 45 71 46 51 72 52 48 73 49 66 74 67 54 75 55 57 76 58 60 77 61 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 78 80 129 81 83 130 84 86 131 87 89 132 90 92 133 134 135 136 93 95 137 96 98 138 99 101 139 102 140 103 108 141 109 105 142 106 114 143 115 111 144 112 134 145 135 117 146 118 120 147 121 123 148 124 126 149 127 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 150 152 219 153 155 220 156 158 221 159 161 222 162 164 223 165 167 224 168 170 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 183 241 184 189 242 190 186 243 187 195 244 196 192 245 193 201 246 202 198 247 199 248 249 250 204 251 205 207 252 208 210 253 211 213 254 214 216 255 217 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 256 258 325 259 261 326 262 264 327 328 329 330 331 332 333 268 270 334 271 273 335 274 276 336 277 279 337 280 282 338 283 339 284 289 340 290 286 341 287 295 342 296 292 343 293 301 344 302 298 345 299 307 346 308 304 347 305 331 348 332 310 349 311 313 350 314 316 351 317 319 352 320 322 353 323 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 354 356 432 357 359 433 360 362 434 363 365 435 436 437 438 366 368 439 369 371 440 372 374 441 375 377 442 378 380 443 381 383 444 385 384 445 390 446 391 387 447 388 396 448 397 393 449 394 402 450 403 399 451 400 408 452 409 405 453 406 414 454 415 411 455 412 436 456 437 417 457 418 420 458 421 423 459 424 426 460 427 429 461 430 462 463 432 434 362 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 464 546 547 434 464 548 465 467 549 468 470 550 551 552 553 471 473 554 474 476 555 477 479 556 480 482 557 483 485 558 486 488 559 489 491 560 561 493 492 498 562 499 497 563 495 504 564 505 501 565 502 510 566 511 507 567 508 516 568 517 513 569 514 522 570 523 519 571 520 528 572 529 525 573 526 551 574 552 531 575 532 534 576 535 537 577 538 540 578 541 543 579 544 548 464 547 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 560 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 548 547 657 658 659 660 583 585 661 586 588 662 663 664 665 589 591 666 592 594 667 595 597 668 598 600 669 601 603 670 604 606 671 607 609 610 610 560 672 673 613 612 618 674 619 615 675 616 624 676 625 621 677 622 630 678 631 627 679 628 636 680 637 633 681 634 642 682 643 639 683 640 648 684 649 645 685 646 654 686 655 651 687 652 663 688 664 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 689 691 749 750 751 752 695 697 753 698 700 754 701 755 702 707 756 708 704 757 705 713 758 714 710 759 711 719 760 720 716 761 717 725 762 726 722 763 723 731 764 732 728 765 729 737 766 738 734 767 735 743 768 744 740 769 741 746 770 747 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 771 773 828 829 830 831 777 779 832 780 833 781 786 834 787 783 835 784 792 836 793 789 837 790 798 838 799 795 839 796 804 798 805 801 840 802 810 841 811 807 842 808 816 843 817 813 844 814 822 845 823 819 846 820 825 847 826 848 849 850 851 852 853 854 855 856 857 858 859 860 856 861 862 863 864 865 861 838 866 867 868 869 838 798 870 871 872 873 798 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 848 850 896 897 898 899 854 900 855 860 854 856 857 901 858 865 860 861 862 902 863 869 865 838 866 903 867 873 869 798 870 904 871 878 873 879 875 905 876 884 906 885 881 907 882 890 908 891 887 909 888 893 910 894 911 912 913 900 914 855 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 911 913 933 900 934 914 915 935 916 918 936 919 921 937 922 924 938 925 927 939 928 930 940 931 934 941 914 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 934 957 941 942 958 943 945 959 946 948 960 949 951 961 952 954 962 955 957 963 941 964 965 966 967 968 969 970 971 972 973 974 975 957 976 963 964 977 965 967 978 968 970 979 971 973 980 974 976 977 963 977 978 981 978 979 982 979 980 973 976 983 977 977 984 978 978 985 979 979 986 980 983 984 977 984 985 978 985 986 979 983 987 984 984 988 985 985 989 986 987 988 984 988 989 985 987 990 988 988 991 989 990 991 988 990 992 991">
+                  <Coordinate DEF="_coords"
+                    point="354.3307 35.6428 0 472.4409 52.93105 -118.1102 472.4409 35.6428 0 354.3307 52.93105 -118.1102 472.4409 35.6428 0 472.4409 52.93105 -118.1102 590.5512 46.75638 -118.1102 354.3307 19.82451 118.1102 354.3307 35.6428 0 472.4409 35.6428 0 236.2205 31.31463 0 354.3307 52.93105 -118.1102 354.3307 35.6428 0 354.3307 52.93105 -118.1102 472.4409 59.55834 -236.2205 472.4409 52.93105 -118.1102 472.4409 52.93105 -118.1102 590.5512 52.93105 -236.2205 590.5512 46.75638 -118.1102 590.5512 30.66875 0 236.2205 35.34792 118.1102 354.3307 35.6428 0 354.3307 19.82451 118.1102 472.4409 14.29063 118.1102 236.2205 46.75638 -118.1102 236.2205 31.31463 0 354.3307 52.93105 -118.1102 354.3307 59.55834 -236.2205 472.4409 59.55834 -236.2205 472.4409 59.55834 -236.2205 590.5512 46.75638 -118.1102 590.5512 52.93105 -236.2205 708.6614 35.6428 -236.2205 590.5512 30.66875 0 590.5512 46.75638 -118.1102 708.6614 30.66875 -118.1102 472.4409 14.29063 118.1102 472.4409 35.6428 0 590.5512 30.66875 0 236.2205 57.10271 236.2205 236.2205 35.34792 118.1102 354.3307 19.82451 118.1102 354.3307 21.3678 236.2205 354.3307 19.82451 118.1102 472.4409 14.29063 118.1102 118.1102 20.32498 0 236.2205 46.75638 -118.1102 236.2205 31.31463 0 236.2205 46.75638 -118.1102 354.3307 59.55834 -236.2205 354.3307 52.93105 -118.1102 118.1102 37.27659 118.1102 236.2205 31.31463 0 236.2205 35.34792 118.1102 354.3307 59.55834 -236.2205 472.4409 53.31618 -354.3307 472.4409 59.55834 -236.2205 472.4409 59.55834 -236.2205 590.5512 46.75638 -354.3307 590.5512 52.93105 -236.2205 590.5512 52.93105 -236.2205 708.6614 30.66875 -354.3307 708.6614 35.6428 -236.2205 708.6614 30.66875 -118.1102 708.6614 17.88719 0 590.5512 11.00248 118.1102 118.1102 71.4288 236.2205 236.2205 35.34792 118.1102 236.2205 57.10271 236.2205 354.3307 21.3678 236.2205 472.4409 -2.33177 236.2205 118.1102 30.66875 -118.1102 118.1102 20.32498 0 236.2205 52.93105 -236.2205 118.1102 37.27659 118.1102 354.3307 53.97681 -354.3307 472.4409 53.31618 -354.3307 590.5512 46.75638 -354.3307 708.6614 35.6428 -236.2205 708.6614 30.66875 -354.3307 826.7717 11.00248 -354.3307 708.6614 30.66875 -118.1102 708.6614 35.6428 -236.2205 826.7717 14.29063 -236.2205 708.6614 17.88719 0 708.6614 30.66875 -118.1102 826.7717 11.00248 -118.1102 590.5512 11.00248 118.1102 590.5512 30.66875 0 708.6614 17.88719 0 472.4409 -2.33177 236.2205 472.4409 14.29063 118.1102 590.5512 11.00248 118.1102 118.1102 90.14421 354.3307 118.1102 71.4288 236.2205 236.2205 57.10271 236.2205 236.2205 69.5469 354.3307 236.2205 57.10271 236.2205 354.3307 21.3678 236.2205 354.3307 24.84853 354.3307 354.3307 21.3678 236.2205 472.4409 -2.33177 236.2205 0 0 0 118.1102 30.66875 -118.1102 118.1102 20.32498 0 118.1102 30.66875 -118.1102 236.2205 52.93105 -236.2205 236.2205 46.75638 -118.1102 0 17.68169 118.1102 118.1102 20.32498 0 118.1102 37.27659 118.1102 236.2205 52.93105 -236.2205 354.3307 53.97681 -354.3307 354.3307 59.55834 -236.2205 0 51.99268 236.2205 118.1102 37.27659 118.1102 118.1102 71.4288 236.2205 354.3307 53.97681 -354.3307 472.4409 38.18617 -472.4409 472.4409 53.31618 -354.3307 472.4409 53.31618 -354.3307 590.5512 31.45388 -472.4409 590.5512 46.75638 -354.3307 590.5512 46.75638 -354.3307 708.6614 17.89071 -472.4409 708.6614 30.66875 -354.3307 708.6614 30.66875 -354.3307 826.7717 2.855471 -472.4409 826.7717 11.00248 -354.3307 826.7717 14.29063 -236.2205 826.7717 11.00248 -118.1102 826.7717 2.855471 0 708.6614 2.855471 118.1102 590.5512 -4.462562 236.2205 0 69.5469 354.3307 118.1102 71.4288 236.2205 118.1102 90.14421 354.3307 236.2205 69.5469 354.3307 354.3307 24.84853 354.3307 472.4409 -7.134798 354.3307 0 10.07483 -118.1102 0 0 0 118.1102 35.6428 -236.2205 0 17.68169 118.1102 236.2205 48.10602 -354.3307 0 51.99268 236.2205 354.3307 39.85344 -472.4409 472.4409 38.18617 -472.4409 590.5512 31.45388 -472.4409 708.6614 17.89071 -472.4409 826.7717 11.00248 -354.3307 826.7717 2.855471 -472.4409 944.8819 -7.690696 -472.4409 826.7717 14.29063 -236.2205 826.7717 11.00248 -354.3307 944.8819 -4.462562 -354.3307 826.7717 11.00248 -118.1102 826.7717 14.29063 -236.2205 944.8819 -2.97764 -236.2205 826.7717 2.855471 0 826.7717 11.00248 -118.1102 944.8819 -4.462562 -118.1102 708.6614 2.855471 118.1102 708.6614 17.88719 0 826.7717 2.855471 0 590.5512 -4.462562 236.2205 590.5512 11.00248 118.1102 708.6614 2.855471 118.1102 472.4409 -7.134798 354.3307 472.4409 -2.33177 236.2205 590.5512 -4.462562 236.2205 0 69.5469 472.4409 0 69.5469 354.3307 118.1102 90.14421 354.3307 118.1102 90.14421 472.4409 118.1102 90.14421 354.3307 236.2205 69.5469 354.3307 236.2205 69.5469 472.4409 236.2205 69.5469 354.3307 354.3307 24.84853 354.3307 354.3307 24.84853 472.4409 354.3307 24.84853 354.3307 472.4409 -7.134798 354.3307 -118.1102 -57.12892 0 0 10.07483 -118.1102 0 0 0 0 10.07483 -118.1102 118.1102 35.6428 -236.2205 118.1102 30.66875 -118.1102 -118.1102 -39.00548 118.1102 0 0 0 0 17.68169 118.1102 118.1102 35.6428 -236.2205 236.2205 48.10602 -354.3307 236.2205 52.93105 -236.2205 -118.1102 6.824681 236.2205 0 17.68169 118.1102 0 51.99268 236.2205 236.2205 48.10602 -354.3307 354.3307 39.85344 -472.4409 354.3307 53.97681 -354.3307 -118.1102 24.84853 354.3307 0 51.99268 236.2205 0 69.5469 354.3307 354.3307 39.85344 -472.4409 472.4409 19.91021 -590.5512 472.4409 38.18617 -472.4409 472.4409 38.18617 -472.4409 590.5512 13.78903 -590.5512 590.5512 31.45388 -472.4409 590.5512 31.45388 -472.4409 708.6614 3.640598 -590.5512 708.6614 17.89071 -472.4409 708.6614 17.89071 -472.4409 826.7717 -5.736107 -590.5512 826.7717 2.855471 -472.4409 826.7717 2.855471 -472.4409 944.8819 -9.572591 -590.5512 944.8819 -7.690696 -472.4409 944.8819 -4.462562 -354.3307 944.8819 -2.97764 -236.2205 944.8819 -4.462562 -118.1102 944.8819 -7.690696 0 826.7717 -5.736107 118.1102 708.6614 -7.690696 236.2205 590.5512 -9.572591 354.3307 -118.1102 24.84853 472.4409 0 69.5469 354.3307 0 69.5469 472.4409 0 69.5469 472.4409 118.1102 90.14421 354.3307 118.1102 90.14421 472.4409 118.1102 90.14421 472.4409 236.2205 69.5469 354.3307 236.2205 69.5469 472.4409 236.2205 69.5469 472.4409 354.3307 24.84853 354.3307 354.3307 24.84853 472.4409 354.3307 24.84853 472.4409 472.4409 -7.134798 354.3307 472.4409 -7.134798 472.4409 -118.1102 -46.41908 -118.1102 -118.1102 -57.12892 0 0 13.47484 -236.2205 -118.1102 -39.00548 118.1102 118.1102 31.71451 -354.3307 -118.1102 6.824681 236.2205 236.2205 35.55231 -472.4409 -118.1102 24.84853 472.4409 -118.1102 24.84853 354.3307 0 69.5469 354.3307 354.3307 22.52593 -590.5512 472.4409 19.91021 -590.5512 590.5512 13.78903 -590.5512 708.6614 3.640598 -590.5512 826.7717 -5.736107 -590.5512 826.7717 -5.736107 118.1102 826.7717 2.855471 0 944.8819 -7.690696 0 708.6614 -7.690696 236.2205 708.6614 2.855471 118.1102 826.7717 -5.736107 118.1102 590.5512 -9.572591 354.3307 590.5512 -4.462562 236.2205 708.6614 -7.690696 236.2205 472.4409 -7.134798 472.4409 472.4409 -7.134798 354.3307 590.5512 -9.572591 354.3307 -118.1102 15.65856 590.5512 -118.1102 24.84853 472.4409 0 69.5469 472.4409 0 51.99268 590.5512 0 69.5469 472.4409 118.1102 90.14421 472.4409 118.1102 69.5469 590.5512 118.1102 90.14421 472.4409 236.2205 69.5469 472.4409 236.2205 51.99268 590.5512 236.2205 69.5469 472.4409 354.3307 24.84853 472.4409 354.3307 14.77285 590.5512 354.3307 24.84853 472.4409 472.4409 -7.134798 472.4409 -236.2205 -124.0258 0 -118.1102 -46.41908 -118.1102 -118.1102 -57.12892 0 -118.1102 -46.41908 -118.1102 0 13.47484 -236.2205 0 10.07483 -118.1102 -236.2205 -97.99729 118.1102 -118.1102 -57.12892 0 -118.1102 -39.00548 118.1102 0 13.47484 -236.2205 118.1102 31.71451 -354.3307 118.1102 35.6428 -236.2205 -236.2205 -43.89348 236.2205 -118.1102 -39.00548 118.1102 -118.1102 6.824681 236.2205 118.1102 31.71451 -354.3307 236.2205 35.55231 -472.4409 236.2205 48.10602 -354.3307 -236.2205 -8.062447 354.3307 -118.1102 6.824681 236.2205 -118.1102 24.84853 354.3307 236.2205 35.55231 -472.4409 354.3307 22.52593 -590.5512 354.3307 39.85344 -472.4409 -236.2205 0.4540042 472.4409 -118.1102 24.84853 354.3307 -118.1102 24.84853 472.4409 354.3307 22.52593 -590.5512 472.4409 5.757028 -708.6614 472.4409 19.91021 -590.5512 472.4409 19.91021 -590.5512 590.5512 1.157014 -708.6614 590.5512 13.78903 -590.5512 590.5512 13.78903 -590.5512 708.6614 -5.147323 -708.6614 708.6614 3.640598 -590.5512 708.6614 3.640598 -590.5512 826.7717 -9.187465 -708.6614 826.7717 -5.736107 -590.5512 826.7717 -5.736107 -590.5512 944.8819 -9.572591 -708.6614 944.8819 -9.572591 -590.5512 944.8819 -9.572591 118.1102 826.7717 -9.572591 236.2205 708.6614 -9.572591 354.3307 472.4409 -7.134798 472.4409 590.5512 -9.572591 354.3307 590.5512 -9.572591 472.4409 -236.2205 24.45906 590.5512 -118.1102 24.84853 472.4409 -118.1102 15.65856 590.5512 0 51.99268 590.5512 118.1102 69.5469 590.5512 236.2205 51.99268 590.5512 354.3307 14.77285 590.5512 472.4409 -8.92672 590.5512 -236.2205 -128.7477 -118.1102 -236.2205 -124.0258 0 -118.1102 -41.67618 -236.2205 -236.2205 -97.99729 118.1102 0 8.308461 -354.3307 -236.2205 -43.89348 236.2205 118.1102 22.09782 -472.4409 -236.2205 -8.062447 354.3307 236.2205 20.25569 -590.5512 -236.2205 0.4540042 472.4409 354.3307 8.549946 -708.6614 472.4409 5.757028 -708.6614 590.5512 1.157014 -708.6614 708.6614 -5.147323 -708.6614 826.7717 -9.187465 -708.6614 826.7717 -9.572591 236.2205 826.7717 -5.736107 118.1102 944.8819 -9.572591 118.1102 708.6614 -9.572591 354.3307 708.6614 -7.690696 236.2205 826.7717 -9.572591 236.2205 590.5512 -9.572591 472.4409 590.5512 -9.572591 354.3307 708.6614 -9.572591 354.3307 472.4409 -8.92672 590.5512 472.4409 -7.134798 472.4409 590.5512 -9.572591 472.4409 -236.2205 37.63034 708.6614 -236.2205 24.45906 590.5512 -118.1102 15.65856 590.5512 -118.1102 -0.6956833 708.6614 -118.1102 15.65856 590.5512 0 51.99268 590.5512 0 14.77285 708.6614 0 51.99268 590.5512 118.1102 69.5469 590.5512 118.1102 24.84853 708.6614 118.1102 69.5469 590.5512 236.2205 51.99268 590.5512 236.2205 14.77285 708.6614 236.2205 51.99268 590.5512 354.3307 14.77285 590.5512 354.3307 -4.038716 708.6614 354.3307 14.77285 590.5512 472.4409 -8.92672 590.5512 -354.3307 -240.1343 0 -236.2205 -128.7477 -118.1102 -236.2205 -124.0258 0 -236.2205 -128.7477 -118.1102 -118.1102 -41.67618 -236.2205 -118.1102 -46.41908 -118.1102 -354.3307 -123.21 118.1102 -236.2205 -124.0258 0 -236.2205 -97.99729 118.1102 -118.1102 -41.67618 -236.2205 0 8.308461 -354.3307 0 13.47484 -236.2205 -354.3307 -59.01081 236.2205 -236.2205 -97.99729 118.1102 -236.2205 -43.89348 236.2205 0 8.308461 -354.3307 118.1102 22.09782 -472.4409 118.1102 31.71451 -354.3307 -354.3307 -12.18823 354.3307 -236.2205 -43.89348 236.2205 -236.2205 -8.062447 354.3307 118.1102 22.09782 -472.4409 236.2205 20.25569 -590.5512 236.2205 35.55231 -472.4409 -354.3307 23.81319 472.4409 -236.2205 -8.062447 354.3307 -236.2205 0.4540042 472.4409 236.2205 20.25569 -590.5512 354.3307 8.549946 -708.6614 354.3307 22.52593 -590.5512 -354.3307 74.8541 590.5512 -236.2205 0.4540042 472.4409 -236.2205 24.45906 590.5512 354.3307 8.549946 -708.6614 472.4409 1.954996 -826.7717 472.4409 5.757028 -708.6614 472.4409 5.757028 -708.6614 590.5512 -1.337298 -826.7717 590.5512 1.157014 -708.6614 590.5512 1.157014 -708.6614 708.6614 -5.361954 -826.7717 708.6614 -5.147323 -708.6614 708.6614 -5.147323 -708.6614 826.7717 -8.526836 -826.7717 826.7717 -9.187465 -708.6614 826.7717 -9.187465 -708.6614 944.8819 -9.572591 -826.7717 944.8819 -9.572591 -708.6614 944.8819 -9.572591 236.2205 826.7717 -9.572591 354.3307 708.6614 -9.572591 472.4409 590.5512 -19.11479 590.5512 -354.3307 98.92684 708.6614 -236.2205 24.45906 590.5512 -236.2205 37.63034 708.6614 -118.1102 -0.6956833 708.6614 0 14.77285 708.6614 118.1102 24.84853 708.6614 236.2205 14.77285 708.6614 354.3307 -4.038716 708.6614 472.4409 -9.572591 708.6614 -354.3307 -299.406 -118.1102 -354.3307 -240.1343 0 -236.2205 -122.3015 -236.2205 -354.3307 -123.21 118.1102 -118.1102 -47.93937 -354.3307 -354.3307 -59.01081 236.2205 0 4.583054 -472.4409 -354.3307 -12.18823 354.3307 118.1102 11.09076 -590.5512 -354.3307 23.81319 472.4409 236.2205 8.328656 -708.6614 -354.3307 74.8541 590.5512 354.3307 3.883989 -826.7717 472.4409 1.954996 -826.7717 590.5512 -1.337298 -826.7717 708.6614 -5.361954 -826.7717 826.7717 -8.526836 -826.7717 826.7717 -9.572591 354.3307 826.7717 -9.572591 236.2205 826.7717 -9.572591 354.3307 590.5512 -19.11479 590.5512 590.5512 -9.572591 472.4409 708.6614 -9.572591 472.4409 472.4409 -9.572591 708.6614 472.4409 -8.92672 590.5512 590.5512 -19.11479 590.5512 -354.3307 74.8541 826.7717 -354.3307 98.92684 708.6614 -236.2205 37.63034 708.6614 -236.2205 23.81319 826.7717 -236.2205 37.63034 708.6614 -118.1102 -0.6956833 708.6614 -118.1102 -8.686885 826.7717 -118.1102 -0.6956833 708.6614 0 14.77285 708.6614 0 -8.92672 826.7717 0 14.77285 708.6614 118.1102 24.84853 708.6614 118.1102 -7.134798 826.7717 118.1102 24.84853 708.6614 236.2205 14.77285 708.6614 236.2205 -8.92672 826.7717 236.2205 14.77285 708.6614 354.3307 -4.038716 708.6614 354.3307 -9.572591 826.7717 354.3307 -4.038716 708.6614 472.4409 -9.572591 708.6614 -472.4409 -208.2875 0 -354.3307 -299.406 -118.1102 -354.3307 -240.1343 0 -236.2205 -122.3015 -236.2205 -236.2205 -128.7477 -118.1102 -354.3307 -299.406 -118.1102 -472.4409 -97.99729 118.1102 -354.3307 -240.1343 0 -354.3307 -123.21 118.1102 -236.2205 -122.3015 -236.2205 -118.1102 -47.93937 -354.3307 -118.1102 -41.67618 -236.2205 -472.4409 -44.53935 236.2205 -354.3307 -123.21 118.1102 -354.3307 -59.01081 236.2205 -118.1102 -47.93937 -354.3307 0 4.583054 -472.4409 0 8.308461 -354.3307 -472.4409 -7.157206 354.3307 -354.3307 -59.01081 236.2205 -354.3307 -12.18823 354.3307 0 4.583054 -472.4409 118.1102 11.09076 -590.5512 118.1102 22.09782 -472.4409 -472.4409 37.63034 472.4409 -354.3307 -12.18823 354.3307 -354.3307 23.81319 472.4409 118.1102 11.09076 -590.5512 236.2205 8.328656 -708.6614 236.2205 20.25569 -590.5512 -472.4409 98.92684 590.5512 -354.3307 23.81319 472.4409 -354.3307 74.8541 590.5512 236.2205 8.328656 -708.6614 354.3307 3.883989 -826.7717 354.3307 8.549946 -708.6614 -472.4409 127.1727 708.6614 -354.3307 74.8541 590.5512 -354.3307 98.92684 708.6614 354.3307 3.883989 -826.7717 472.4409 3.218627 -944.8819 472.4409 1.954996 -826.7717 472.4409 1.954996 -826.7717 590.5512 -0.3193718 -944.8819 590.5512 -1.337298 -826.7717 590.5512 -1.337298 -826.7717 708.6614 -4.68904 -944.8819 708.6614 -5.361954 -826.7717 708.6614 -5.361954 -826.7717 826.7717 -8.22295 -944.8819 826.7717 -8.526836 -826.7717 826.7717 -8.526836 -826.7717 944.8819 -9.572591 -944.8819 944.8819 -9.572591 -826.7717 944.8819 -9.572591 236.2205 944.8819 -9.572591 354.3307 826.7717 -9.572591 472.4409 708.6614 -68.92579 590.5512 590.5512 -68.92579 708.6614 -472.4409 98.92684 826.7717 -354.3307 98.92684 708.6614 -354.3307 74.8541 826.7717 -236.2205 23.81319 826.7717 -118.1102 -8.686885 826.7717 0 -8.92672 826.7717 118.1102 -7.134798 826.7717 236.2205 -8.92672 826.7717 354.3307 -9.572591 826.7717 472.4409 -9.572591 826.7717 -472.4409 -177.2051 -118.1102 -472.4409 -208.2875 0 -354.3307 -207.4029 -236.2205 -472.4409 -97.99729 118.1102 -236.2205 -110.4349 -354.3307 -472.4409 -44.53935 236.2205 -118.1102 -37.65593 -472.4409 -472.4409 -7.157206 354.3307 0 -0.1165306 -590.5512 -472.4409 37.63034 472.4409 118.1102 3.83689 -708.6614 -472.4409 98.92684 590.5512 236.2205 4.574885 -826.7717 -472.4409 127.1727 708.6614 354.3307 4.574885 -944.8819 472.4409 3.218627 -944.8819 590.5512 -0.3193718 -944.8819 708.6614 -4.68904 -944.8819 826.7717 -8.22295 -944.8819 708.6614 -68.92579 590.5512 708.6614 -9.572591 472.4409 826.7717 -9.572591 472.4409 590.5512 -68.92579 708.6614 590.5512 -19.11479 590.5512 708.6614 -68.92579 590.5512 472.4409 -9.572591 826.7717 472.4409 -9.572591 708.6614 590.5512 -68.92579 708.6614 -472.4409 37.63034 944.8819 -472.4409 98.92684 826.7717 -354.3307 74.8541 826.7717 -354.3307 23.81319 944.8819 -354.3307 74.8541 826.7717 -236.2205 23.81319 826.7717 -236.2205 -1.983788 944.8819 -236.2205 23.81319 826.7717 -118.1102 -8.686885 826.7717 -118.1102 -9.572591 944.8819 -118.1102 -8.686885 826.7717 0 -8.92672 826.7717 0 -9.572591 944.8819 0 -8.92672 826.7717 118.1102 -7.134798 826.7717 118.1102 -9.572591 944.8819 118.1102 -7.134798 826.7717 236.2205 -8.92672 826.7717 236.2205 -9.572591 944.8819 236.2205 -8.92672 826.7717 354.3307 -9.572591 826.7717 354.3307 -9.572591 944.8819 354.3307 -9.572591 826.7717 -590.5512 -59.01081 0 -472.4409 -177.2051 -118.1102 -472.4409 -208.2875 0 -472.4409 -177.2051 -118.1102 -354.3307 -207.4029 -236.2205 -354.3307 -299.406 -118.1102 -590.5512 -44.53935 118.1102 -472.4409 -208.2875 0 -472.4409 -97.99729 118.1102 -354.3307 -207.4029 -236.2205 -236.2205 -110.4349 -354.3307 -236.2205 -122.3015 -236.2205 -590.5512 -17.52076 236.2205 -472.4409 -97.99729 118.1102 -472.4409 -44.53935 236.2205 -236.2205 -110.4349 -354.3307 -118.1102 -37.65593 -472.4409 -118.1102 -47.93937 -354.3307 -590.5512 -8.686885 354.3307 -472.4409 -44.53935 236.2205 -472.4409 -7.157206 354.3307 -118.1102 -37.65593 -472.4409 0 -0.1165306 -590.5512 0 4.583054 -472.4409 -590.5512 23.81319 472.4409 -472.4409 -7.157206 354.3307 -472.4409 37.63034 472.4409 0 -0.1165306 -590.5512 118.1102 3.83689 -708.6614 118.1102 11.09076 -590.5512 -590.5512 74.8541 590.5512 -472.4409 37.63034 472.4409 -472.4409 98.92684 590.5512 118.1102 3.83689 -708.6614 236.2205 4.574885 -826.7717 236.2205 8.328656 -708.6614 -590.5512 98.92684 708.6614 -472.4409 98.92684 590.5512 -472.4409 127.1727 708.6614 236.2205 4.574885 -826.7717 354.3307 4.574885 -944.8819 354.3307 3.883989 -826.7717 -590.5512 74.8541 826.7717 -472.4409 127.1727 708.6614 -472.4409 98.92684 826.7717 944.8819 -9.572591 472.4409 708.6614 -68.92579 590.5512 826.7717 -9.572591 472.4409 826.7717 -68.92579 590.5512 708.6614 -181.5167 708.6614 590.5512 -19.11479 826.7717 -590.5512 23.81319 944.8819 -472.4409 98.92684 826.7717 -472.4409 37.63034 944.8819 -354.3307 23.81319 944.8819 -236.2205 -1.983788 944.8819 -118.1102 -9.572591 944.8819 0 -9.572591 944.8819 118.1102 -9.572591 944.8819 236.2205 -9.572591 944.8819 472.4409 -9.572591 944.8819 -590.5512 -51.52911 -118.1102 -590.5512 -59.01081 0 -472.4409 -122.3015 -236.2205 -590.5512 -44.53935 118.1102 -354.3307 -139.0247 -354.3307 -590.5512 -17.52076 236.2205 -236.2205 -87.33477 -472.4409 -590.5512 -8.686885 354.3307 -118.1102 -14.01897 -590.5512 -590.5512 23.81319 472.4409 0 -1.337298 -708.6614 -590.5512 74.8541 590.5512 118.1102 3.218627 -826.7717 -590.5512 98.92684 708.6614 236.2205 3.883989 -944.8819 -590.5512 74.8541 826.7717 826.7717 -68.92579 590.5512 826.7717 -9.572591 472.4409 944.8819 -9.572591 472.4409 708.6614 -181.5167 708.6614 708.6614 -68.92579 590.5512 826.7717 -68.92579 590.5512 590.5512 -19.11479 826.7717 590.5512 -68.92579 708.6614 708.6614 -181.5167 708.6614 472.4409 -9.572591 944.8819 472.4409 -9.572591 826.7717 590.5512 -19.11479 826.7717 -708.6614 -13.07393 0 -590.5512 -51.52911 -118.1102 -590.5512 -59.01081 0 -590.5512 -51.52911 -118.1102 -472.4409 -122.3015 -236.2205 -472.4409 -177.2051 -118.1102 -708.6614 -10.50024 118.1102 -590.5512 -59.01081 0 -590.5512 -44.53935 118.1102 -472.4409 -122.3015 -236.2205 -354.3307 -139.0247 -354.3307 -354.3307 -207.4029 -236.2205 -708.6614 -9.572591 236.2205 -590.5512 -44.53935 118.1102 -590.5512 -17.52076 236.2205 -354.3307 -139.0247 -354.3307 -236.2205 -87.33477 -472.4409 -236.2205 -110.4349 -354.3307 -708.6614 -9.572591 354.3307 -590.5512 -17.52076 236.2205 -590.5512 -8.686885 354.3307 -236.2205 -87.33477 -472.4409 -118.1102 -14.01897 -590.5512 -118.1102 -37.65593 -472.4409 -708.6614 -1.983788 472.4409 -590.5512 -8.686885 354.3307 -590.5512 23.81319 472.4409 -118.1102 -14.01897 -590.5512 0 -1.337298 -708.6614 0 -0.1165306 -590.5512 -708.6614 23.81319 590.5512 -590.5512 23.81319 472.4409 -590.5512 74.8541 590.5512 0 -1.337298 -708.6614 118.1102 3.218627 -826.7717 118.1102 3.83689 -708.6614 -708.6614 37.63034 708.6614 -590.5512 74.8541 590.5512 -590.5512 98.92684 708.6614 118.1102 3.218627 -826.7717 236.2205 3.883989 -944.8819 236.2205 4.574885 -826.7717 -708.6614 23.81319 826.7717 -590.5512 98.92684 708.6614 -590.5512 74.8541 826.7717 -708.6614 -1.983788 944.8819 -590.5512 74.8541 826.7717 -590.5512 23.81319 944.8819 944.8819 -19.11479 590.5512 708.6614 -181.5167 708.6614 826.7717 -68.92579 590.5512 826.7717 -181.5167 708.6614 708.6614 -68.92579 826.7717 590.5512 -9.572591 944.8819 -708.6614 -10.50024 -118.1102 -708.6614 -13.07393 0 -590.5512 -48.27113 -236.2205 -708.6614 -10.50024 118.1102 -472.4409 -110.4349 -354.3307 -708.6614 -9.572591 236.2205 -354.3307 -109.5073 -472.4409 -708.6614 -9.572591 354.3307 -236.2205 -39.93783 -590.5512 -708.6614 -1.983788 472.4409 -118.1102 -5.361954 -708.6614 -708.6614 23.81319 590.5512 0 -0.3193718 -826.7717 -708.6614 37.63034 708.6614 118.1102 1.954996 -944.8819 -708.6614 23.81319 826.7717 826.7717 -181.5167 708.6614 826.7717 -68.92579 590.5512 944.8819 -19.11479 590.5512 708.6614 -68.92579 826.7717 708.6614 -181.5167 708.6614 826.7717 -181.5167 708.6614 590.5512 -9.572591 944.8819 590.5512 -19.11479 826.7717 708.6614 -68.92579 826.7717 -826.7717 -9.572591 0 -708.6614 -10.50024 -118.1102 -708.6614 -13.07393 0 -708.6614 -10.50024 -118.1102 -590.5512 -48.27113 -236.2205 -590.5512 -51.52911 -118.1102 -826.7717 -9.572591 118.1102 -708.6614 -13.07393 0 -708.6614 -10.50024 118.1102 -590.5512 -48.27113 -236.2205 -472.4409 -110.4349 -354.3307 -472.4409 -122.3015 -236.2205 -826.7717 -9.572591 236.2205 -708.6614 -10.50024 118.1102 -708.6614 -9.572591 236.2205 -472.4409 -110.4349 -354.3307 -354.3307 -109.5073 -472.4409 -354.3307 -139.0247 -354.3307 -826.7717 -9.572591 354.3307 -708.6614 -9.572591 236.2205 -708.6614 -9.572591 354.3307 -354.3307 -109.5073 -472.4409 -236.2205 -39.93783 -590.5512 -236.2205 -87.33477 -472.4409 -826.7717 -9.572591 472.4409 -708.6614 -9.572591 354.3307 -708.6614 -1.983788 472.4409 -236.2205 -39.93783 -590.5512 -118.1102 -5.361954 -708.6614 -118.1102 -14.01897 -590.5512 -826.7717 -8.686885 590.5512 -708.6614 -1.983788 472.4409 -708.6614 23.81319 590.5512 -118.1102 -5.361954 -708.6614 0 -0.3193718 -826.7717 0 -1.337298 -708.6614 -826.7717 -6.229558 708.6614 -708.6614 23.81319 590.5512 -708.6614 37.63034 708.6614 0 -0.3193718 -826.7717 118.1102 1.954996 -944.8819 118.1102 3.218627 -826.7717 -826.7717 -8.686885 826.7717 -708.6614 37.63034 708.6614 -708.6614 23.81319 826.7717 -826.7717 -9.572591 944.8819 -708.6614 23.81319 826.7717 -708.6614 -1.983788 944.8819 944.8819 -68.92579 708.6614 708.6614 -68.92579 826.7717 826.7717 -181.5167 708.6614 826.7717 -68.92579 826.7717 708.6614 -9.572591 944.8819 -826.7717 -9.572591 -118.1102 -826.7717 -9.572591 0 -708.6614 -10.38838 -236.2205 -826.7717 -9.572591 118.1102 -590.5512 -53.0494 -354.3307 -826.7717 -9.572591 236.2205 -472.4409 -87.33477 -472.4409 -354.3307 -53.0494 -590.5512 -826.7717 -9.572591 472.4409 -236.2205 -9.342625 -708.6614 -826.7717 -8.686885 590.5512 -118.1102 -4.68904 -826.7717 -826.7717 -6.229558 708.6614 0 -1.337298 -944.8819 -826.7717 -8.686885 826.7717 826.7717 -68.92579 826.7717 826.7717 -181.5167 708.6614 944.8819 -68.92579 708.6614 708.6614 -9.572591 944.8819 708.6614 -68.92579 826.7717 826.7717 -68.92579 826.7717 -944.8819 -9.572591 0 -826.7717 -9.572591 -118.1102 -826.7717 -9.572591 0 -826.7717 -9.572591 -118.1102 -708.6614 -10.38838 -236.2205 -708.6614 -10.50024 -118.1102 -944.8819 -9.572591 118.1102 -826.7717 -9.572591 118.1102 -708.6614 -10.38838 -236.2205 -590.5512 -53.0494 -354.3307 -590.5512 -48.27113 -236.2205 -944.8819 -9.572591 236.2205 -590.5512 -53.0494 -354.3307 -472.4409 -87.33477 -472.4409 -472.4409 -110.4349 -354.3307 -944.8819 -9.572591 354.3307 -472.4409 -87.33477 -472.4409 -354.3307 -53.0494 -590.5512 -354.3307 -109.5073 -472.4409 -944.8819 -9.572591 472.4409 -826.7717 -9.572591 472.4409 -354.3307 -53.0494 -590.5512 -236.2205 -9.342625 -708.6614 -236.2205 -39.93783 -590.5512 -944.8819 -9.572591 590.5512 -826.7717 -9.572591 472.4409 -826.7717 -8.686885 590.5512 -236.2205 -9.342625 -708.6614 -118.1102 -4.68904 -826.7717 -118.1102 -5.361954 -708.6614 -944.8819 -9.572591 708.6614 -826.7717 -8.686885 590.5512 -826.7717 -6.229558 708.6614 -118.1102 -4.68904 -826.7717 0 -1.337298 -944.8819 0 -0.3193718 -826.7717 -944.8819 -9.572591 826.7717 -826.7717 -6.229558 708.6614 -826.7717 -8.686885 826.7717 -944.8819 -9.572591 944.8819 -826.7717 -8.686885 826.7717 -826.7717 -9.572591 944.8819 944.8819 -19.11479 826.7717 708.6614 -9.572591 944.8819 826.7717 -68.92579 826.7717 826.7717 -9.572591 944.8819 -944.8819 -9.572591 -118.1102 -826.7717 -9.572591 -236.2205 -708.6614 -12.65173 -354.3307 -590.5512 -40.32296 -472.4409 -472.4409 -40.32296 -590.5512 -354.3307 -12.65173 -708.6614 -944.8819 -9.572591 590.5512 -236.2205 -8.22295 -826.7717 -944.8819 -9.572591 708.6614 -118.1102 -5.361954 -944.8819 -944.8819 -9.572591 826.7717 826.7717 -9.572591 944.8819 826.7717 -68.92579 826.7717 944.8819 -19.11479 826.7717 -826.7717 -9.572591 -236.2205 -826.7717 -9.572591 -236.2205 -708.6614 -12.65173 -354.3307 -708.6614 -10.38838 -236.2205 -708.6614 -12.65173 -354.3307 -590.5512 -40.32296 -472.4409 -590.5512 -53.0494 -354.3307 -590.5512 -40.32296 -472.4409 -472.4409 -40.32296 -590.5512 -472.4409 -87.33477 -472.4409 -472.4409 -40.32296 -590.5512 -354.3307 -12.65173 -708.6614 -354.3307 -53.0494 -590.5512 -354.3307 -12.65173 -708.6614 -236.2205 -8.22295 -826.7717 -236.2205 -9.342625 -708.6614 -236.2205 -8.22295 -826.7717 -118.1102 -5.361954 -944.8819 -118.1102 -4.68904 -826.7717 944.8819 -9.572591 944.8819 -944.8819 -9.572591 -236.2205 -826.7717 -9.572591 -354.3307 -708.6614 -10.38838 -472.4409 -590.5512 -16.56235 -590.5512 -472.4409 -10.38838 -708.6614 -354.3307 -9.572591 -826.7717 -236.2205 -8.526836 -944.8819 -826.7717 -9.572591 -354.3307 -826.7717 -9.572591 -354.3307 -708.6614 -10.38838 -472.4409 -708.6614 -12.65173 -354.3307 -708.6614 -10.38838 -472.4409 -590.5512 -16.56235 -590.5512 -590.5512 -40.32296 -472.4409 -590.5512 -16.56235 -590.5512 -472.4409 -10.38838 -708.6614 -472.4409 -40.32296 -590.5512 -472.4409 -10.38838 -708.6614 -354.3307 -9.572591 -826.7717 -354.3307 -12.65173 -708.6614 -354.3307 -9.572591 -826.7717 -236.2205 -8.526836 -944.8819 -236.2205 -8.22295 -826.7717 -944.8819 -9.572591 -354.3307 -826.7717 -9.572591 -472.4409 -708.6614 -9.572591 -590.5512 -590.5512 -9.572591 -708.6614 -472.4409 -9.572591 -826.7717 -354.3307 -9.572591 -944.8819 -826.7717 -9.572591 -472.4409 -826.7717 -9.572591 -472.4409 -708.6614 -9.572591 -590.5512 -708.6614 -10.38838 -472.4409 -708.6614 -9.572591 -590.5512 -590.5512 -9.572591 -708.6614 -590.5512 -16.56235 -590.5512 -590.5512 -9.572591 -708.6614 -472.4409 -9.572591 -826.7717 -472.4409 -10.38838 -708.6614 -472.4409 -9.572591 -826.7717 -354.3307 -9.572591 -944.8819 -354.3307 -9.572591 -826.7717 -944.8819 -9.572591 -472.4409 -826.7717 -9.572591 -590.5512 -708.6614 -9.572591 -708.6614 -590.5512 -9.572591 -826.7717 -472.4409 -9.572591 -944.8819 -708.6614 -9.572591 -590.5512 -590.5512 -9.572591 -708.6614 -944.8819 -9.572591 -590.5512 -826.7717 -9.572591 -708.6614 -708.6614 -9.572591 -826.7717 -590.5512 -9.572591 -944.8819 -944.8819 -9.572591 -708.6614 -826.7717 -9.572591 -826.7717 -708.6614 -9.572591 -944.8819 -944.8819 -9.572591 -826.7717 -826.7717 -9.572591 -944.8819 -944.8819 -9.572591 -944.8819" />
+                </IndexedTriangleSet>
+            </Transform>
+            </Shape>
+          </Scene>
+        </X3D>
+        </p>
+      </td>
+      <td width="50%" align="left" valign="top" scope="col">
+        In this example, a simple 3D scene is integrated into a web page. This is done by the &lt;X3D&gt; tag in the
+        HTML document.
+        The &lt;X3D&gt; tag is interpreted by the x3dom.js Java Script library. You can either make a local copy of the
+        library or use it
+        from the server. It is recommended to use the library from the server to ensure that you always have the latest
+        version.
+        A local copy of the library is useful for development, if you are not always connected.
+        <br>
+        <pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	&lt;Scene&gt; 
+          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
+            &lt;Shape id=box&gt; 
+              &lt;Box&gt; &lt;/Box&gt;
+            &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+        &lt;/X3D&gt;  
+        </pre>
+        The &lt;X3D&gt; tag defines the size of the 3D canvas on the web page as well as the scene graph.
+        An <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/Part01/concepts.html#scenegraph"
+          target="_blank"> X3D scene graph </a>
+        is defined as a directed acyclic graph.
+        The nodes of the scene graph will be rendered on the screen from a given camera position.
+        The default camera position is (0,0,10) pointing to the negative z-Axis.
+        So objects at the center of the coordinate system will be displayed on the screen.
+        A shape node contains a geometry. In this example, it is a simple box. The center of the box is at (0,0,0) with
+        default size 2 in all dimensions
+        <br>
+        The color of the background can be changed in the attribute skyColor. Currently it is red.
+        The color is defined using <a href="http://en.wikipedia.org/wiki/RGB_color_model" target="_blank"> RGB color
+          model </a>
+        with arithmetic notation (0.0 t0 1.0 per value). <br>
+        The color of the Box can be changed by applying an appearance to the shape node.
+        In X3D, the <a href="http://www.web3d.org/files/specifications/19775-1/V3.3/index.html" target="_blank"> Shape
+          node </a> associates a geometry node with
+        nodes that define that geometry's appearance. The following example draws a blue box.
+        <pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	&lt;Scene&gt; 
+          &lt;background transparency='0' skyColor='1 0 0'&gt; &lt;/background&gt;
+            &lt;Shape id=box&gt; 
+              &lt;appearance &gt; 
+                &lt;material diffuseColor='0 0 1'&gt;&lt;/material&gt; 
+              &lt;/appearance&gt; 
+              &lt;Box&gt; &lt;/Box&gt;
+            &lt;/Shape&gt;
+	  &lt;/Scene&gt;
+        &lt;/X3D&gt;  
+        </pre>
+        <shape>
+          <box></box>
+        </shape>
+      </td>
+      <script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/toytown.html b/public/X3DOMTutorial/toytown.html
new file mode 100644
index 0000000000000000000000000000000000000000..b50200a3835684419369f6b47469afa209b4c830
--- /dev/null
+++ b/public/X3DOMTutorial/toytown.html
@@ -0,0 +1,104 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> toy town </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> toy town </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<transform id="terrain">
+							<Shape>
+								<Appearance>
+									<ImageTexture url="./img/Logo_bisH27mm.jpg"></ImageTexture>
+									<Material diffuseColor="0, 1, 0"> </Material>
+								</Appearance>
+								<IndexedFaceSet solid="true" ccw="true" coordIndex="  0 3 2 1 -1">
+									<Coordinate point="-5 0 -5, 5 0 -5, 5 0 5, -5 0 5">
+									</Coordinate>
+								</IndexedFaceSet>
+							</Shape>
+						</transform>
+						<transform id="building_1">
+							<Group DEF="building">
+								<Shape DEF="roof">
+									<!-- roof -->
+									<Appearance>
+										<Material diffuseColor="0.980, 0.502, 0.447"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex="  7 4 8 -1 4 5 8 -1 5 6 8 -1 6 7 8 -1">
+										<Coordinate DEF="pointset" point="-1 0 1, 1 0 1, 1 0 -1, -1 0 -1,
+             	            -1 2 1, 1 2 1, 1 2 -1, -1 2 -1, 0 3 0 ">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+								<Shape DEF="wall">
+									<!-- wall -->
+									<Appearance>
+										<Material diffuseColor="0.753, 0.753, 0.753"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 1 5 4 -1 1 2 6 5 -1 2 3 7 6 -1 3 0 4 7 -1">
+										<Coordinate USE="pointset">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+								<Shape DEF="ground">
+									<!-- ground -->
+									<Appearance>
+										<Material diffuseColor="0.180, 0.280, 0.230"> </Material>
+									</Appearance>
+									<IndexedFaceSet solid="true" ccw="true" coordIndex=" 0 3 2 1 -1 ">
+										<Coordinate USE="pointset">
+										</Coordinate>
+									</IndexedFaceSet>
+								</Shape>
+							</Group>
+						</Transform>
+						<Transform id="building_2" translation="3 0 0">
+							<Group>
+								<Shape USE="roof">
+								</Shape>
+								<Shape USE="wall">
+								</Shape>
+								<Shape USE="ground">
+								</Shape>
+							</Group>
+						</Transform>
+						<Transform id="building_3" translation="0 0 4">
+							<Group>
+								<Shape USE="roof">
+								</Shape>
+								<Shape USE="wall">
+								</Shape>
+								<Shape USE="ground">
+								</Shape>
+							</Group>
+						</Transform>
+						<Transform id="building_4" translation="-3 0 0">
+							<Group>
+								<Shape USE="roof">
+								</Shape>
+								<Shape USE="wall">
+								</Shape>
+								<Shape USE="ground">
+								</Shape>
+							</Group>
+						</Transform>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				DEF / USE
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/transform.html b/public/X3DOMTutorial/transform.html
new file mode 100644
index 0000000000000000000000000000000000000000..49804bb1e60148d63487ca79de028a005cb65155
--- /dev/null
+++ b/public/X3DOMTutorial/transform.html
@@ -0,0 +1,86 @@
+<html>
+
+<head>
+	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+	<title> Transformation </title>
+	<link rel="stylesheet" type="text/css" href="x3dom.css">
+	</link>
+</head>
+
+<body>
+	<h1> Transformation </h1>
+	<table width="100%" height="85%" border="0">
+		<tr>
+			<td width="50%" align="center" valign="top" scope="col">
+				<X3D id="shapedata" width="600px" height="600px" style="float:left">
+					<Scene>
+						<background transparency='0' skyColor='1 1 1'> </background>
+						<Shape>
+							<Appearance>
+								<Material diffuseColor='1 0 0'></Material>
+							</Appearance>
+							<Box></Box>
+						</Shape>
+						<Transform translation='-3 0 0'>
+							<Shape>
+								<Appearance>
+									<Material diffuseColor='0 1 0'></Material>
+								</Appearance>
+								<Cone></Cone>
+							</Shape>
+						</Transform>
+						<Transform translation='3 0 0'>
+							<Shape>
+								<Appearance>
+									<Material diffuseColor='0 0 1'></Material>
+								</Appearance>
+								<Sphere></Sphere>
+							</Shape>
+						</Transform>
+					</Scene>
+				</X3D>
+				</p>
+			</td>
+			<td width="50%" align="left" valign="top" scope="col">
+				In X3DOM, a shape such as Box, Cone, and Sphere is always created at the center of the coordinate system. The
+				size of the shape can be modified,
+				but the location is always centered at (0,0,0). To move a shape to another location, a transformation needs to
+				be applied. See slides for
+				the different kinds of affine transformations: translation, rotation, and scaling.
+				<br>
+				<pre class="prettyprint">
+	&lt;X3D id="shapedata" width="600px" height="600px" style="float:left"&gt;
+	&lt;Scene&gt; 
+          &lt;background transparency='0' skyColor='1 1 1'&gt; &lt;/background&gt;
+      		&lt;Shape&gt; 
+        	  &lt;Appearance&gt; 
+        	    &lt;Material diffuseColor='1 0 0'&gt;&lt;/Material&gt; 
+        	  &lt;/Appearance&gt; 
+        	  &lt;Box&gt;&lt;/Box&gt; 
+    		&lt;/Shape&gt; 
+    		&lt;Transform translation='-3 0 0'&gt; 
+    		  &lt;Shape&gt; 
+        	    &lt;Appearance&gt; 
+        	      &lt;Material diffuseColor='0 1 0'&gt;&lt;/Material&gt; 
+        	    &lt;/Appearance&gt; 
+        	    &lt;Cone&gt;&lt;/Cone&gt; 
+    		  &lt;/Shape&gt; 
+    		&lt;/Transform&gt; 
+   		&lt;Transform translation='3 0 0'&gt; 
+    		  &lt;Shape&gt; 
+        	    &lt;Appearance&gt; 
+        	      &lt;Material diffuseColor='0 0 1'&gt;&lt;/Material&gt; 
+        	    &lt;/Appearance&gt; 
+        	    &lt;Sphere&gt;&lt;/Sphere&gt;
+    		  &lt;/Shape&gt; 
+    		&lt;/Transform&gt; 
+	  &lt;/Scene&gt;
+        &lt;/X3D&gt;  
+        </pre>
+				<br>
+				This example illustrates how to move shapes to another location.
+			</td>
+			<script type="text/javascript" src="x3dom.js"></script>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/public/X3DOMTutorial/x3dom.css b/public/X3DOMTutorial/x3dom.css
new file mode 100644
index 0000000000000000000000000000000000000000..59811b5d9fe07e739ff4368a25e2f14c4afe759b
--- /dev/null
+++ b/public/X3DOMTutorial/x3dom.css
@@ -0,0 +1,222 @@
+/*
+ * X3DOM JavaScript Library
+ * http://www.x3dom.org
+ *
+ * (C)2009 Fraunhofer IGD, Darmstadt, Germany
+ * Dual licensed under the MIT and GPL
+ *
+ * Based on code originally provided by
+ * Philip Taylor: http://philip.html5.org
+ */
+
+body {
+  background-color: white;
+  font-family: Helvetica, sans-serif;
+  font-size: 12px;
+}
+
+X3D, x3d {
+  position:relative;    /* in order to be able to position stat-div within X3D */
+  float:left;           /* float the element so it has the same size like the canvas */
+  cursor:pointer;
+  margin: 0;
+  padding: 0;
+  border: 1px solid #000;
+}
+
+object {
+	margin: 0;
+	padding: 0;
+	border: none;
+	z-index: 0;
+  width:100%;
+  height:100%;
+  float:left;
+}
+
+X3D:hover, 
+x3d:hover, 
+.x3dom-canvas:hover {
+  -webkit-user-select: none;
+  -webkit-touch-callout: none;
+}
+
+.x3dom-canvas {
+  border:none;
+  cursor:pointer;
+  cursor:-webkit-grab;
+  cursor:grab;
+  width:100%;
+  height:100%;
+  float:left;
+}
+
+.x3dom-canvas-mousedown {
+  cursor:-webkit-grabbing;
+  cursor:grabbing;
+}
+
+.x3dom-canvas:focus {
+    outline:none; 
+}
+.x3dom-progress {
+    margin: 0;
+    padding: 6px 8px 0px 26px;
+    left: 0px;
+    top: 0px;
+    position: absolute;
+    color: #0f0;
+    font-family: Helvetica, sans-serif;
+    line-height:10px;
+    font-size: 10px;
+    min-width: 45px;
+    min-height: 20px;
+    border: 0px;
+    background-position: 4px 4px;
+    background-repeat: no-repeat;
+    background-color: #333;
+    background-color: rgba(51, 51, 51, 0.9);
+    z-index: 100;
+    background-image: url('data:image/gif;base64,R0lGODlhEAAQAPQAADMzM////z4+Po+Pj0pKSsbGxpycnP///7e3t+Hh4XR0dGZmZu7u7oGBgfr6+tLS0qqqqgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh/hpDcmVhdGVkIHdpdGggYWpheGxvYWQuaW5mbwAh+QQJCgAAACwAAAAAEAAQAAAFdyAgAgIJIeWoAkRCCMdBkKtIHIngyMKsErPBYbADpkSCwhDmQCBethRB6Vj4kFCkQPG4IlWDgrNRIwnO4UKBXDufzQvDMaoSDBgFb886MiQadgNABAokfCwzBA8LCg0Egl8jAggGAA1kBIA1BAYzlyILczULC2UhACH5BAkKAAAALAAAAAAQABAAAAV2ICACAmlAZTmOREEIyUEQjLKKxPHADhEvqxlgcGgkGI1DYSVAIAWMx+lwSKkICJ0QsHi9RgKBwnVTiRQQgwF4I4UFDQQEwi6/3YSGWRRmjhEETAJfIgMFCnAKM0KDV4EEEAQLiF18TAYNXDaSe3x6mjidN1s3IQAh+QQJCgAAACwAAAAAEAAQAAAFeCAgAgLZDGU5jgRECEUiCI+yioSDwDJyLKsXoHFQxBSHAoAAFBhqtMJg8DgQBgfrEsJAEAg4YhZIEiwgKtHiMBgtpg3wbUZXGO7kOb1MUKRFMysCChAoggJCIg0GC2aNe4gqQldfL4l/Ag1AXySJgn5LcoE3QXI3IQAh+QQJCgAAACwAAAAAEAAQAAAFdiAgAgLZNGU5joQhCEjxIssqEo8bC9BRjy9Ag7GILQ4QEoE0gBAEBcOpcBA0DoxSK/e8LRIHn+i1cK0IyKdg0VAoljYIg+GgnRrwVS/8IAkICyosBIQpBAMoKy9dImxPhS+GKkFrkX+TigtLlIyKXUF+NjagNiEAIfkECQoAAAAsAAAAABAAEAAABWwgIAICaRhlOY4EIgjH8R7LKhKHGwsMvb4AAy3WODBIBBKCsYA9TjuhDNDKEVSERezQEL0WrhXucRUQGuik7bFlngzqVW9LMl9XWvLdjFaJtDFqZ1cEZUB0dUgvL3dgP4WJZn4jkomWNpSTIyEAIfkECQoAAAAsAAAAABAAEAAABX4gIAICuSxlOY6CIgiD8RrEKgqGOwxwUrMlAoSwIzAGpJpgoSDAGifDY5kopBYDlEpAQBwevxfBtRIUGi8xwWkDNBCIwmC9Vq0aiQQDQuK+VgQPDXV9hCJjBwcFYU5pLwwHXQcMKSmNLQcIAExlbH8JBwttaX0ABAcNbWVbKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICSRBlOY7CIghN8zbEKsKoIjdFzZaEgUBHKChMJtRwcWpAWoWnifm6ESAMhO8lQK0EEAV3rFopIBCEcGwDKAqPh4HUrY4ICHH1dSoTFgcHUiZjBhAJB2AHDykpKAwHAwdzf19KkASIPl9cDgcnDkdtNwiMJCshACH5BAkKAAAALAAAAAAQABAAAAV3ICACAkkQZTmOAiosiyAoxCq+KPxCNVsSMRgBsiClWrLTSWFoIQZHl6pleBh6suxKMIhlvzbAwkBWfFWrBQTxNLq2RG2yhSUkDs2b63AYDAoJXAcFRwADeAkJDX0AQCsEfAQMDAIPBz0rCgcxky0JRWE1AmwpKyEAIfkECQoAAAAsAAAAABAAEAAABXkgIAICKZzkqJ4nQZxLqZKv4NqNLKK2/Q4Ek4lFXChsg5ypJjs1II3gEDUSRInEGYAw6B6zM4JhrDAtEosVkLUtHA7RHaHAGJQEjsODcEg0FBAFVgkQJQ1pAwcDDw8KcFtSInwJAowCCA6RIwqZAgkPNgVpWndjdyohACH5BAkKAAAALAAAAAAQABAAAAV5ICACAimc5KieLEuUKvm2xAKLqDCfC2GaO9eL0LABWTiBYmA06W6kHgvCqEJiAIJiu3gcvgUsscHUERm+kaCxyxa+zRPk0SgJEgfIvbAdIAQLCAYlCj4DBw0IBQsMCjIqBAcPAooCBg9pKgsJLwUFOhCZKyQDA3YqIQAh+QQJCgAAACwAAAAAEAAQAAAFdSAgAgIpnOSonmxbqiThCrJKEHFbo8JxDDOZYFFb+A41E4H4OhkOipXwBElYITDAckFEOBgMQ3arkMkUBdxIUGZpEb7kaQBRlASPg0FQQHAbEEMGDSVEAA1QBhAED1E0NgwFAooCDWljaQIQCE5qMHcNhCkjIQAh+QQJCgAAACwAAAAAEAAQAAAFeSAgAgIpnOSoLgxxvqgKLEcCC65KEAByKK8cSpA4DAiHQ/DkKhGKh4ZCtCyZGo6F6iYYPAqFgYy02xkSaLEMV34tELyRYNEsCQyHlvWkGCzsPgMCEAY7Cg04Uk48LAsDhRA8MVQPEF0GAgqYYwSRlycNcWskCkApIyEAOwAAAAAAAAAAAA==');
+}
+
+.x3dom-progress.bar span {
+  position: absolute;
+  left: 0;
+  top: 0;
+  line-height: 20px;
+  background-color: red;
+}
+
+
+.x3dom-statdiv {
+    margin: 0;
+    padding: 0;
+    right: 10px;
+    top: 10px;
+    position: absolute;
+    color: #0f0;
+    font-family: Helvetica, sans-serif;
+    line-height:10px;
+    font-size: 10px;
+    width: 75px;
+    height: 70px;
+    border: 0px;
+}
+
+#x3dom-state-canvas {
+    margin: 2px;
+    padding: 0;
+    right: 0%;
+    top: 0%;
+    position: absolute;
+}
+
+#x3dom-state-viewer {
+  position: absolute;
+  margin: 2px;
+  padding: 5px;
+  width: 135px;
+  top: 0%;
+  right: 0%;
+  opacity: 0.9;
+  background-color: #323232;
+  z-index: 1000;
+  font-family: Arial, sans-serif;
+  color: #C8C8C8;
+  font-weight: bold;
+  text-transform: uppercase;
+  cursor: help;
+}
+
+.x3dom-states-head {
+  display: block;
+  font-size: 26px;
+}
+
+.x3dom-states-head2 {
+  font-size: 10px;
+}
+
+.x3dom-states-list {
+  float: left;
+  width: 100%;
+  border-top: 1px solid #C8C8C8;
+  list-style: none;
+  font-size: 9px;
+  line-height: 16px;
+  margin:0;
+  padding: 0;
+  padding-top: 2px;
+}
+
+.x3dom-states-item  {
+  width: 100%;
+  float: left;
+}
+
+.x3dom-states-item-title {
+  float: left;
+  margin-left: 2px;
+}
+
+.x3dom-states-item-value {
+  float: right;
+  margin-right: 2px;
+}
+
+.x3dom-touch-marker {
+	display: inline;
+    padding: 5px;
+	border-radius: 10px;
+    position: absolute;
+    font-family: Helvetica, sans-serif;
+    line-height:10px;
+    font-size: 10px;
+    color: darkorange;
+    background: cornsilk;
+    opacity: 0.6;
+    border: 2px solid orange;
+	z-index: 200;
+}
+
+.x3dom-logContainer {
+    border: 2px solid olivedrab;
+    height: 200px;
+    padding: 4px;
+    overflow: auto;
+    white-space: pre-wrap;
+    font-family: sans-serif;
+    font-size: x-small;
+    color: #00ff00;
+    background-color: black;
+    margin-right: 10px;
+}
+
+.x3dom-nox3d {
+    font-family: Helvetica, sans-serif;
+    font-size: 14px;
+    background-color: #eb7a7a;
+    padding: 1em;
+    opacity: 0.75;
+}
+
+.x3dom-nox3d p { 
+    color: #fff;
+    font-size: 14px;
+}
+
+.x3dom-nox3d a { 
+    color: #fff;
+    font-size: 14px;
+}
+
+
+/* self-clearing floats */
+.group:after {
+  content: "."; 
+  display: block; 
+  height: 0; 
+  clear: both; 
+  visibility: hidden;
+}
diff --git a/public/X3DOMTutorial/x3dom.js b/public/X3DOMTutorial/x3dom.js
new file mode 100644
index 0000000000000000000000000000000000000000..59853451886c03ac9098488d46df1f5f5235469d
--- /dev/null
+++ b/public/X3DOMTutorial/x3dom.js
@@ -0,0 +1,3959 @@
+/** X3DOM Runtime, http://www.x3dom.org/ 1.6.0 - 5e8c0441fe2cbe9970ffd14f1546100672a95185 - Thu May 8 20:51:15 2014 +0200 */
+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:[],x3dNS:'http://www.web3d.org/specifications/x3d-namespace',x3dextNS:'http://philip.html5.org/x3d/ext',xsltNS:'http://www.w3.org/1999/XSL/x3dom.Transform',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){if(x3dom.components[componentName]===undefined){x3dom.components[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){var name=(node.nodeType===Node.ELEMENT_NODE&&node.localName)?node.localName.toLowerCase():null;return(name&&(x3dom.nodeTypes[node.localName]||x3dom.nodeTypesLC[name]||name=="x3d"||name=="websg"||name=="route"));};x3dom.extend=function(f){function G(){}
+G.prototype=f.prototype||f;return new G();};x3dom.getStyle=function(oElm,strCssRule){var strValue="";var style=document.defaultView.getComputedStyle?document.defaultView.getComputedStyle(oElm,null):null;if(style){strValue=style.getPropertyValue(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){if(parent){function Inheritance(){}
+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){return(object instanceof clazz);};x3dom.getGlobal=function(){return(function(){return this;}).call(null);};x3dom.loadJS=function(src,path_prefix,blocking){blocking=(blocking===false)?blocking:true;if(blocking){var url=(path_prefix)?path_prefix.trim()+src:src;var req=new XMLHttpRequest();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);}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,16);};})();x3dom.toggleFullScreen=function(){if(document.fullScreen||document.mozFullScreen||document.webkitIsFullScreen){if(document.cancelFullScreen){document.cancelFullScreen();}
+else if(document.mozCancelFullScreen){document.mozCancelFullScreen();}
+else if(document.webkitCancelFullScreen){document.webkitCancelFullScreen();}}
+else{var docElem=document.documentElement;if(docElem.requestFullScreen){docElem.requestFullScreen();}
+else if(docElem.mozRequestFullScreen){docElem.mozRequestFullScreen();}
+else if(docElem.webkitRequestFullScreen){docElem.webkitRequestFullScreen();}}};x3dom.debug={INFO:"INFO",WARNING:"WARNING",ERROR:"ERROR",EXCEPTION:"EXCEPTION",isActive:false,isFirebugAvailable:false,isSetup:false,isAppend:false,numLinesLogged:0,maxLinesToLog:10000,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.setAttribute("class","x3dom-logContainer");x3dom.debug.logContainer.style.clear="both";},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+", ");}
+str+='\n';x3dom.debug.logInfo(str);return str;}};x3dom.debug.setup();x3dom.arc={};x3dom.arc.instance=null;x3dom.arc.Limits=function(min,max,initial)
+{this._min=min;this._max=max;this.getValue=function(value)
+{value=this._min+(this._max-this._min)*value;return this._max>=value?(this._min<=value?value:this._min):this._max;};};x3dom.arc.ARF=function(name,min,max,dirFac,factorGetterFunc,factorSetterFunc,getterFunc,setterFunc)
+{this._name=name;this._stateValue=[0.5,0.5];this._limits=new x3dom.arc.Limits(min,max);this._factorGetterFunc=factorGetterFunc;this._factorSetterFunc=factorSetterFunc;this._setterFunc=setterFunc;this._getterFunc=getterFunc;this._dirFac=dirFac;this.getFactor=function()
+{return this._factorGetterFunc();};this.update=function(state,step)
+{var stateVal=this._stateValue[state]+step*this._dirFac;this._stateValue[state]=0<=stateVal?(1>=stateVal?stateVal:1):0;this._setterFunc(this._limits.getValue(this._stateValue[state]));};this.reset=function()
+{this._stateValue[0]=0.5;this._stateValue[1]=0.5;};};x3dom.arc.AdaptiveRenderControl=defineClass(null,function(scene)
+{x3dom.arc.instance=this;this._scene=scene;this._targetFrameRate=[];this._targetFrameRate[0]=this._scene._vf.minFrameRate;this._targetFrameRate[1]=this._scene._vf.maxFrameRate;this._currentState=0;var that=this;var environment=that._scene.getEnvironment();this._arfs=[];this._arfs.push(new x3dom.arc.ARF("smallFeatureCulling",0,10,-1,function()
+{return environment._vf.smallFeatureFactor;},function(value)
+{environment._vf.smallFeatureFactor=value;},function()
+{return environment._vf.smallFeatureThreshold;},function(value)
+{environment._vf.smallFeatureThreshold=value;}));this._arfs.push(new x3dom.arc.ARF("lowPriorityCulling",0,100,1,function()
+{return environment._vf.lowPriorityFactor;},function(value)
+{environment._vf.lowPriorityFactor=value;},function()
+{return environment._vf.lowPriorityThreshold*100;},function(value)
+{environment._vf.lowPriorityThreshold=value/100;}));this._arfs.push(new x3dom.arc.ARF("tessellationDetailCulling",1,12,-1,function()
+{return environment._vf.tessellationErrorFactor;},function(value)
+{environment._vf.tessellationErrorFactor=value;},function()
+{return environment.tessellationErrorThreshold;},function(value)
+{environment.tessellationErrorThreshold=value;}));this._stepWidth=0.1;},{update:function(state,fps)
+{this._currentState=state;var delta=fps-this._targetFrameRate[state];this._stepWidth=Math.abs(delta)>10?0.1:0.01;var factorSum=0;var normFactors=[];var i,n=this._arfs.length;for(i=0;i<n;++i)
+{normFactors[i]=this._arfs[i].getFactor();if(normFactors[i]>0)
+factorSum+=normFactors[i];}
+var dirFac=delta<0?-1:1;for(i=0;i<n;++i)
+{if(normFactors[i]>0)
+{normFactors[i]/=factorSum;this._arfs[i].update(state,this._stepWidth*normFactors[i]*dirFac);}}},reset:function()
+{for(var i=0,n=this._arfs.length;i<n;++i)
+{this._arfs[i].reset();}}});var Request=function(url,onloadCallback,priority){this.url=url;this.priority=priority;this.xhr=new XMLHttpRequest();this.onloadCallbacks=[onloadCallback];var self=this;this.xhr.onload=function(){if(x3dom.DownloadManager.debugOutput){x3dom.debug.logInfo('Download manager received data for URL \''+self.url+'\'.');}
+--x3dom.DownloadManager.activeDownloads;if((x3dom.DownloadManager.stallToKeepOrder===false)||(x3dom.DownloadManager.resultGetsStalled(self.priority)===false)){var i;for(i=0;i<self.onloadCallbacks.length;++i){self.onloadCallbacks[i](self.xhr.response);}
+x3dom.DownloadManager.removeDownload(self);x3dom.DownloadManager.updateStalledResults();}
+else if(x3dom.DownloadManager.debugOutput){x3dom.debug.logInfo('Download manager stalled downloaded result for URL \''+self.url+'\'.');}
+x3dom.DownloadManager.tryNextDownload();};};Request.prototype.send=function(){this.xhr.open('GET',encodeURI(this.url),true);this.xhr.responseType='arraybuffer';this.xhr.send(null);if(x3dom.DownloadManager.debugOutput){x3dom.debug.logInfo('Download manager posted XHR for URL \''+this.url+'\'.');}};x3dom.DownloadManager={requests:[],maxDownloads:6,activeDownloads:0,debugOutput:false,stallToKeepOrder:false,toggleDebugOutput:function(flag){this.debugOutput=flag;},toggleStrictReturnOrder:function(flag){this.stallToKeepOrder=false;},removeDownload:function(req){var i,j;var done=false;for(i=0;i<this.requests.length&&!done;++i){if(this.requests[i]){for(j=0;j<this.requests[i].length;++j){if(this.requests[i][j]===req){this.requests[i].splice(j,1);done=true;break;}}}}},tryNextDownload:function(){var firstRequest;var i,j;if(this.activeDownloads<this.maxDownloads){for(i=0;i<this.requests.length&&!firstRequest;++i){if(this.requests[i]){for(j=0;j<this.requests[i].length;++j){if(this.requests[i][j].xhr.readyState===XMLHttpRequest.UNSENT){firstRequest=this.requests[i][j];break;}}}}
+if(firstRequest){firstRequest.send();++this.activeDownloads;}}},resultGetsStalled:function(priority){var i;for(i=0;i<priority;++i){if(this.requests[i]&&this.requests[i].length){return true;}}
+return false;},updateStalledResults:function(){if(x3dom.DownloadManager.stallToKeepOrder){var i,j,k;var req,pendingRequestFound=false;for(i=0;i<this.requests.length&&!pendingRequestFound;++i){if(this.requests[i]){for(j=0;j<this.requests[i].length;++j){req=this.requests[i][j];if(req.xhr.readyState===XMLHttpRequest.DONE){if(x3dom.DownloadManager.debugOutput){x3dom.debug.logInfo('Download manager releases stalled result for URL \''+req.url+'\'.');}
+for(k=0;k<req.onloadCallbacks.length;++k){req.onloadCallbacks[k](req.xhr.response);}
+this.requests[i].splice(j,1);}
+else{pendingRequestFound=true;}}}}}},get:function(urls,onloadCallbacks,priorities){var i,j,k,r;var found=false;var url,onloadCallback,priority;if(urls.length!==onloadCallbacks.length||urls.length!==priorities.length)
+{x3dom.debug.logError('DownloadManager: The number of given urls, onload callbacks and priorities is not equal. Ignoring requests.');return;}
+for(k=0;k<urls.length;++k){if(!onloadCallbacks[k]===undefined||!priorities[k]===undefined){x3dom.debug.logError('DownloadManager: No onload callback and / or priority specified. Ignoring request for \"'+url+'\"');continue;}
+else{url=urls[k];onloadCallback=onloadCallbacks[k];priority=priorities[k];for(i=0;i<this.requests.length&&!found;++i){if(this.requests[i]){for(j=0;j<this.requests[i].length;++j){if(this.requests[i][j].url===url){this.requests[i][j].onloadCallbacks.push(onloadCallback);if(x3dom.DownloadManager.debugOutput){x3dom.debug.logInfo('Download manager appended onload callback for URL \''+url+'\' to a registered request using the same URL.');}
+found=true;break;}}}}
+if(!found){r=new Request(url,onloadCallback,priority);if(this.requests[priority]){this.requests[priority].push(r);}
+else{this.requests[priority]=[r];}}}}
+for(i=0;i<urls.length&&this.activeDownloads<this.maxDownloads;++i){this.tryNextDownload();}}};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;}}
+return null;};x3dom.DoublyLinkedList.prototype.invert=function(){var tmp=null;var 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=0;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{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={};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;},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));return(l>=0);},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=Math.abs(v1y*v2z-v1z*v2y);v3y=Math.abs(v1z*v2x-v1x*v2z);v3z=Math.abs(v1x*v2y-v1y*v2x);var angle=Math.max(v3x,v3y,v3z);if(angle==v3x){return'YZ';}else if(angle==v3y){return'XZ';}else if(angle==v3z){return'XY';}else{return'XZ';}}};x3dom.Utils={};x3dom.Utils.maxIndexableCoords=65535;x3dom.Utils.needLineWidth=false;x3dom.Utils.measurements=[];window.performance=window.performance||{};performance.now=(function(){return performance.now||performance.mozNow||performance.msNow||performance.oNow||performance.webkitNow||function(){return new Date().getTime();};})();x3dom.Utils.startMeasure=function(name){var uname=name.toUpperCase();if(!x3dom.Utils.measurements[uname]){if(performance&&performance.now){x3dom.Utils.measurements[uname]=performance.now();}else{x3dom.Utils.measurements[uname]=new Date().getTime();}}};x3dom.Utils.stopMeasure=function(name){var uname=name.toUpperCase();if(x3dom.Utils.measurements[uname]){var startTime=x3dom.Utils.measurements[uname];delete x3dom.Utils.measurements[uname];if(performance&&performance.now){return performance.now()-startTime;}else{return new Date().getTime()-startTime;}}
+return 0;};x3dom.Utils.isNumber=function(n){return!isNaN(parseFloat(n))&&isFinite(n);};x3dom.Utils.createTexture2D=function(gl,doc,src,bgnd,withCredentials,scale,genMipMaps)
+{var texture=gl.createTexture();var data=new Uint8Array([0,0,0,255,0,0,0,255,0,0,0,255,0,0,0,255]);gl.bindTexture(gl.TEXTURE_2D,texture);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,2,2,0,gl.RGBA,gl.UNSIGNED_BYTE,data);if(genMipMaps){gl.generateMipmap(gl.TEXTURE_2D);}
+gl.bindTexture(gl.TEXTURE_2D,null);texture.ready=false;if(src==null||src=='')
+return texture;var image=new Image();image.crossOrigin=withCredentials?'use-credentials':'';image.src=src;doc.downloadCount++;image.onload=function(){if(scale)
+image=x3dom.Utils.scaleImage(image);if(bgnd==true){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);if(genMipMaps){gl.generateMipmap(gl.TEXTURE_2D);}
+gl.bindTexture(gl.TEXTURE_2D,null);if(bgnd==true){gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL,false);}
+texture.width=image.width;texture.height=image.height;texture.ready=true;doc.downloadCount--;doc.needRender=true;};image.onerror=function(){x3dom.debug.logError("[Utils|createTexture2D] Can't load Image: "+src);doc.downloadCount--;};return texture;};x3dom.Utils.createTextureCube=function(gl,doc,url,bgnd,withCredentials,scale,genMipMaps)
+{var texture=gl.createTexture();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.ready=false;texture.pendingTextureLoads=-1;texture.textureCubeReady=false;var width=0,height=0;for(var i=0;i<faces.length;i++){var face=faces[i];var image=new Image();image.crossOrigin=withCredentials?'use-credentials':'';texture.pendingTextureLoads++;doc.downloadCount++;image.onload=(function(texture,face,image,swap){return function(){if(width==0&&height==0){width=image.width;height=image.height;}
+else if(scale&&(width!=image.width||height!=image.height)){x3dom.debug.logWarning("[Utils|createTextureCube] Rescaling CubeMap images, which are of different size!");image=x3dom.Utils.rescaleImage(image,width,height);}
+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--;if(texture.pendingTextureLoads<0){texture.width=width;texture.height=height;texture.textureCubeReady=true;if(genMipMaps){gl.bindTexture(gl.TEXTURE_CUBE_MAP,texture);gl.generateMipmap(gl.TEXTURE_CUBE_MAP);gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);}
+x3dom.debug.logInfo("[Utils|createTextureCube] Loading CubeMap finished...");doc.needRender=true;}};})(texture,face,image,bgnd);image.onerror=function()
+{doc.downloadCount--;x3dom.debug.logError("[Utils|createTextureCube] Can't load CubeMap!");};image.src=url[i];}
+return texture;};x3dom.Utils.initFBO=function(gl,w,h,type,mipMap,needRenderBuf,numMrt){var tex=gl.createTexture();tex.width=w;tex.height=h;gl.bindTexture(gl.TEXTURE_2D,tex);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,w,h,0,gl.RGBA,type,null);if(mipMap)
+gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null);var i,mrts=null;if(x3dom.caps.DRAW_BUFFERS&&numMrt!==undefined){mrts=[tex];for(i=1;i<numMrt;i++){mrts[i]=gl.createTexture();mrts[i].width=w;mrts[i].height=h;gl.bindTexture(gl.TEXTURE_2D,mrts[i]);gl.texImage2D(gl.TEXTURE_2D,0,gl.RGBA,w,h,0,gl.RGBA,type,null);if(mipMap)
+gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null);}}
+var fbo=gl.createFramebuffer();var rb=null;if(needRenderBuf){rb=gl.createRenderbuffer();gl.bindRenderbuffer(gl.RENDERBUFFER,rb);gl.renderbufferStorage(gl.RENDERBUFFER,gl.DEPTH_COMPONENT16,w,h);gl.bindRenderbuffer(gl.RENDERBUFFER,null);}
+gl.bindFramebuffer(gl.FRAMEBUFFER,fbo);gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0,gl.TEXTURE_2D,tex,0);if(x3dom.caps.DRAW_BUFFERS&&numMrt!==undefined){for(i=1;i<numMrt;i++){gl.framebufferTexture2D(gl.FRAMEBUFFER,gl.COLOR_ATTACHMENT0+i,gl.TEXTURE_2D,mrts[i],0);}}
+gl.framebufferRenderbuffer(gl.FRAMEBUFFER,gl.DEPTH_ATTACHMENT,gl.RENDERBUFFER,rb);var status=gl.checkFramebufferStatus(gl.FRAMEBUFFER);if(status!=gl.FRAMEBUFFER_COMPLETE){x3dom.debug.logWarning("[Utils|InitFBO] FBO-Status: "+status);}
+gl.bindFramebuffer(gl.FRAMEBUFFER,null);return{fbo:fbo,rbo:rb,tex:tex,texTargets:mrts,width:w,height:h,type:type,mipMap:mipMap};};x3dom.Utils.getFileName=function(url)
+{var filename;if(url.lastIndexOf("/")>-1){filename=url.substr(url.lastIndexOf("/")+1);}
+else if(url.lastIndexOf("\\")>-1){filename=url.substr(url.lastIndexOf("\\")+1);}
+else{filename=url;}
+return filename;};x3dom.Utils.findTextureByName=function(texture,name)
+{for(var i=0;i<texture.length;++i)
+{if(name==texture[i].samplerName)
+return texture[i];}
+return false;};x3dom.Utils.rescaleImage=function(image,width,height)
+{var canvas=document.createElement("canvas");canvas.width=width;canvas.height=height;canvas.getContext("2d").drawImage(image,0,0,image.width,image.height,0,0,canvas.width,canvas.height);return canvas;};x3dom.Utils.scaleImage=function(image)
+{if(!x3dom.Utils.isPowerOfTwo(image.width)||!x3dom.Utils.isPowerOfTwo(image.height)){var canvas=document.createElement("canvas");canvas.width=x3dom.Utils.nextHighestPowerOfTwo(image.width);canvas.height=x3dom.Utils.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;};x3dom.Utils.isPowerOfTwo=function(x)
+{return((x&(x-1))===0);};x3dom.Utils.nextHighestPowerOfTwo=function(x)
+{--x;for(var i=1;i<32;i<<=1){x=x|x>>i;}
+return(x+1);};x3dom.Utils.nextBestPowerOfTwo=function(x)
+{var log2x=Math.log(x)/0.693147180559945;return Math.pow(2,Math.round(log2x));};x3dom.Utils.getDataTypeSize=function(type)
+{switch(type)
+{case"Int8":case"Uint8":return 1;case"Int16":case"Uint16":return 2;case"Int32":case"Uint32":case"Float32":return 4;case"Float64":default:return 8;}};x3dom.Utils.getOffsetMultiplier=function(indexType,gl)
+{switch(indexType)
+{case gl.UNSIGNED_SHORT:return 1;case gl.UNSIGNED_INT:return 2;case gl.UNSIGNED_BYTE:return 0.5;default:return 1;}};x3dom.Utils.getByteAwareOffset=function(offset,indexType,gl)
+{switch(indexType)
+{case gl.UNSIGNED_SHORT:return 2*offset;case gl.UNSIGNED_INT:return 4*offset;case gl.UNSIGNED_BYTE:return offset;default:return 2*offset;}};x3dom.Utils.getVertexAttribType=function(type,gl)
+{var dataType=gl.NONE;switch(type)
+{case"Int8":dataType=gl.BYTE;break;case"Uint8":dataType=gl.UNSIGNED_BYTE;break;case"Int16":dataType=gl.SHORT;break;case"Uint16":dataType=gl.UNSIGNED_SHORT;break;case"Int32":dataType=gl.INT;break;case"Uint32":dataType=gl.UNSIGNED_INT;break;case"Float32":dataType=gl.FLOAT;break;case"Float64":default:x3dom.debug.logError("Can't find this.gl data type for "+type+", getting FLOAT...");dataType=gl.FLOAT;break;}
+return dataType;};x3dom.Utils.getArrayBufferView=function(type,buffer)
+{var array=null;switch(type)
+{case"Int8":array=new Int8Array(buffer);break;case"Uint8":array=new Uint8Array(buffer);break;case"Int16":array=new Int16Array(buffer);break;case"Uint16":array=new Uint16Array(buffer);break;case"Int32":array=new Int32Array(buffer);break;case"Uint32":array=new Uint32Array(buffer);break;case"Float32":array=new Float32Array(buffer);break;case"Float64":array=new Float64Array(buffer);break;default:x3dom.debug.logError("Can't create typed array view of type "+type+", trying Float32...");array=new Float32Array(buffer);break;}
+return array;};x3dom.Utils.isUnsignedType=function(str)
+{return(str=="Uint8"||str=="Uint16"||str=="Uint16"||str=="Uint32");};x3dom.Utils.checkDirtyLighting=function(viewarea)
+{return(viewarea.getLights().length+viewarea._scene.getNavigationInfo()._vf.headlight);};x3dom.Utils.checkDirtyEnvironment=function(viewarea,shaderProperties)
+{var environment=viewarea._scene.getEnvironment();return(shaderProperties.GAMMACORRECTION!=environment._vf.gammaCorrectionDefault);}
+x3dom.Utils.minFilterDic=function(gl,minFilter)
+{switch(minFilter.toUpperCase())
+{case"NEAREST":return gl.NEAREST;case"LINEAR":return gl.LINEAR;case"NEAREST_MIPMAP_NEAREST":return gl.NEAREST_MIPMAP_NEAREST;case"NEAREST_MIPMAP_LINEAR":return gl.NEAREST_MIPMAP_LINEAR;case"LINEAR_MIPMAP_NEAREST":return gl.LINEAR_MIPMAP_NEAREST;case"LINEAR_MIPMAP_LINEAR":return gl.LINEAR_MIPMAP_LINEAR;case"AVG_PIXEL":return gl.LINEAR;case"AVG_PIXEL_AVG_MIPMAP":return gl.LINEAR_MIPMAP_LINEAR;case"AVG_PIXEL_NEAREST_MIPMAP":return gl.LINEAR_MIPMAP_NEAREST;case"DEFAULT":return gl.LINEAR_MIPMAP_LINEAR;case"FASTEST":return gl.NEAREST;case"NEAREST_PIXEL":return gl.NEAREST;case"NEAREST_PIXEL_AVG_MIPMAP":return gl.NEAREST_MIPMAP_LINEAR;case"NEAREST_PIXEL_NEAREST_MIPMAP":return gl.NEAREST_MIPMAP_NEAREST;case"NICEST":return gl.LINEAR_MIPMAP_LINEAR;default:return gl.LINEAR;}};x3dom.Utils.magFilterDic=function(gl,magFilter)
+{switch(magFilter.toUpperCase())
+{case"NEAREST":return gl.NEAREST;case"LINEAR":return gl.LINEAR;case"AVG_PIXEL":return gl.LINEAR;case"DEFAULT":return gl.LINEAR;case"FASTEST":return gl.NEAREST;case"NEAREST_PIXEL":return gl.NEAREST;case"NICEST":return gl.LINEAR;default:return gl.LINEAR;}};x3dom.Utils.boundaryModesDic=function(gl,mode)
+{switch(mode.toUpperCase())
+{case"CLAMP":return gl.CLAMP_TO_EDGE;case"CLAMP_TO_EDGE":return gl.CLAMP_TO_EDGE;case"CLAMP_TO_BOUNDARY":return gl.CLAMP_TO_EDGE;case"MIRRORED_REPEAT":return gl.MIRRORED_REPEAT;case"REPEAT":return gl.REPEAT;default:return gl.REPEAT;}};x3dom.Utils.primTypeDic=function(gl,type)
+{switch(type.toUpperCase())
+{case"POINTS":return gl.POINTS;case"LINES":return gl.LINES;case"LINELOOP":return gl.LINE_LOOP;case"LINESTRIP":return gl.LINE_STRIP;case"TRIANGLES":return gl.TRIANGLES;case"TRIANGLESTRIP":return gl.TRIANGLE_STRIP;case"TRIANGLEFAN":return gl.TRIANGLE_FAN;default:return gl.TRIANGLES;}};x3dom.Utils.depthFunc=function(gl,func)
+{switch(func.toUpperCase())
+{case"NEVER":return gl.NEVER;case"ALWAYS":return gl.ALWAYS;case"LESS":return gl.LESS;case"EQUAL":return gl.EQUAL;case"LEQUAL":return gl.LEQUAL;case"GREATER":return gl.GREATER;case"GEQUAL":return gl.GEQUAL;case"NOTEQUAL":return gl.NOTEQUAL;default:return gl.LEQUAL;}};x3dom.Utils.blendFunc=function(gl,func)
+{switch(func.toLowerCase())
+{case"zero":return gl.ZERO;case"one":return gl.ONE;case"dst_color":return gl.DST_COLOR;case"dst_alpha":return gl.DST_ALPHA;case"src_color":return gl.SRC_COLOR;case"src_alpha":return gl.SRC_ALPHA;case"one_minus_dst_color":return gl.ONE_MINUS_DST_COLOR;case"one_minus_dst_alpha":return gl.ONE_MINUS_DST_ALPHA;case"one_minus_src_color":return gl.ONE_MINUS_SRC_COLOR;case"one_minus_src_alpha":return gl.ONE_MINUS_SRC_ALPHA;case"src_alpha_saturate":return gl.SRC_ALPHA_SATURATE;case"constant_color":return gl.CONSTANT_COLOR;case"constant_alpha":return gl.CONSTANT_ALPHA;case"one_minus_constant_color":return gl.ONE_MINUS_CONSTANT_COLOR;case"one_minus_constant_alpha":return gl.ONE_MINUS_CONSTANT_ALPHA;default:return 0;}};x3dom.Utils.blendEquation=function(gl,func)
+{switch(func.toLowerCase())
+{case"func_add":return gl.FUNC_ADD;case"func_subtract":return gl.FUNC_SUBTRACT;case"func_reverse_subtract":return gl.FUNC_REVERSE_SUBTRACT;case"min":return 0;case"max":return 0;case"logic_op":return 0;default:return 0;}};x3dom.Utils.generateProperties=function(viewarea,shape)
+{var property={};var geometry=shape._cf.geometry.node;var appearance=shape._cf.appearance.node;var texture=appearance?appearance._cf.texture.node:null;var material=appearance?appearance._cf.material.node:null;var environment=viewarea._scene.getEnvironment();if(appearance&&appearance._shader&&x3dom.isa(appearance._shader,x3dom.nodeTypes.ComposedShader)){property.CSHADER=appearance._shader._id;}
+else if(geometry){property.CSHADER=-1;property.SOLID=(shape.isSolid())?1:0;property.TEXT=(x3dom.isa(geometry,x3dom.nodeTypes.Text))?1:0;property.POPGEOMETRY=(x3dom.isa(geometry,x3dom.nodeTypes.PopGeometry))?1:0;property.IMAGEGEOMETRY=(x3dom.isa(geometry,x3dom.nodeTypes.ImageGeometry))?1:0;property.BINARYGEOMETRY=(x3dom.isa(geometry,x3dom.nodeTypes.BinaryGeometry))?1:0;property.IG_PRECISION=(property.IMAGEGEOMETRY)?geometry.numCoordinateTextures():0;property.IG_INDEXED=(property.IMAGEGEOMETRY&&geometry.getIndexTexture()!=null)?1:0;property.POINTLINE2D=!geometry.needLighting()?1:0;property.VERTEXID=(property.BINARYGEOMETRY&&geometry._vf.idsPerVertex)?1:0;property.APPMAT=(appearance&&(material||property.CSSHADER))?1:0;property.SHADOW=(viewarea.getLightsShadow())?1:0;property.FOG=(viewarea._scene.getFog()._vf.visibilityRange>0)?1:0;property.CSSHADER=(appearance&&appearance._shader&&x3dom.isa(appearance._shader,x3dom.nodeTypes.CommonSurfaceShader))?1:0;property.LIGHTS=(!property.POINTLINE2D&&appearance&&shape.isLit()&&(material||property.CSSHADER))?viewarea.getLights().length+(viewarea._scene.getNavigationInfo()._vf.headlight):0;property.TEXTURED=(texture||property.TEXT)?1:0;property.TEXTRAFO=(appearance&&appearance._cf.textureTransform.node)?1:0;property.DIFFUSEMAP=(property.CSSHADER&&appearance._shader.getDiffuseMap())?1:0;property.NORMALMAP=(property.CSSHADER&&appearance._shader.getNormalMap())?1:0;property.SPECMAP=(property.CSSHADER&&appearance._shader.getSpecularMap())?1:0;property.SHINMAP=(property.CSSHADER&&appearance._shader.getShininessMap())?1:0;property.DISPLACEMENTMAP=(property.CSSHADER&&appearance._shader.getDisplacementMap())?1:0;property.DIFFPLACEMENTMAP=(property.CSSHADER&&appearance._shader.getDiffuseDisplacementMap())?1:0;property.MULTIDIFFALPMAP=(property.VERTEXID&&property.CSSHADER&&appearance._shader.getMultiDiffuseAlphaMap())?1:0;property.MULTIVISMAP=(property.VERTEXID&&property.CSSHADER&&appearance._shader.getMultiVisibilityMap())?1:0;property.CUBEMAP=(texture&&x3dom.isa(texture,x3dom.nodeTypes.X3DEnvironmentTextureNode))?1:0;property.BLENDING=(property.TEXT||property.CUBEMAP||(texture&&texture._blending))?1:0;property.REQUIREBBOX=(geometry._vf.coordType!==undefined&&geometry._vf.coordType!="Float32")?1:0;property.REQUIREBBOXNOR=(geometry._vf.normalType!==undefined&&geometry._vf.normalType!="Float32")?1:0;property.REQUIREBBOXCOL=(geometry._vf.colorType!==undefined&&geometry._vf.colorType!="Float32")?1:0;property.REQUIREBBOXTEX=(geometry._vf.texCoordType!==undefined&&geometry._vf.texCoordType!="Float32")?1:0;property.COLCOMPONENTS=geometry._mesh._numColComponents;property.NORCOMPONENTS=geometry._mesh._numNormComponents;property.POSCOMPONENTS=geometry._mesh._numPosComponents;property.SPHEREMAPPING=(geometry._cf.texCoord!==undefined&&geometry._cf.texCoord.node!==null&&geometry._cf.texCoord.node._vf.mode&&geometry._cf.texCoord.node._vf.mode.toLowerCase()=="sphere")?1:0;property.VERTEXCOLOR=(geometry._mesh._colors[0].length>0||(property.IMAGEGEOMETRY&&geometry.getColorTexture())||(property.POPGEOMETRY&&geometry.hasColor())||(geometry._vf.color!==undefined&&geometry._vf.color.length>0))?1:0;property.GAMMACORRECTION=environment._vf.gammaCorrectionDefault;}
+property.toIdentifier=function(){var id="";for(var p in this){if(this[p]!=this.toIdentifier&&this[p]!=this.toString){id+=this[p];}}
+this.id=id;return id;};property.toString=function(){var str="";for(var p in this){if(this[p]!=this.toIdentifier&&this[p]!=this.toString){str+=p+": "+this[p]+", ";}}
+return str;};property.toIdentifier();return property;};x3dom.Utils.wrapProgram=function(gl,program,shaderID)
+{var shader={shaderID:shaderID,program:program};shader.bind=function(){gl.useProgram(program);};var loc=null;var obj=null;var i,glErr;var numUniforms=gl.getProgramParameter(program,gl.ACTIVE_UNIFORMS);for(i=0;i<numUniforms;++i){try{obj=gl.getActiveUniform(program,i);}
+catch(eu){if(!obj)continue;}
+glErr=gl.getError();if(glErr){x3dom.debug.logError("GL-Error (on searching uniforms): "+glErr);}
+loc=gl.getUniformLocation(program,obj.name);switch(obj.type){case gl.SAMPLER_2D:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.SAMPLER_CUBE:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.BOOL:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform1i(loc,val);};})(loc));break;case gl.FLOAT:if(obj.name.indexOf("[0]")!=-1)
+shader.__defineSetter__(obj.name.substring(0,obj.name.length-3),(function(loc){return function(val){gl.uniform1fv(loc,new Float32Array(val));};})(loc));else
+shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform1f(loc,val);};})(loc));break;case gl.FLOAT_VEC2:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform2f(loc,val[0],val[1]);};})(loc));break;case gl.FLOAT_VEC3:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform3f(loc,val[0],val[1],val[2]);};})(loc));break;case gl.FLOAT_VEC4:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniform4f(loc,val[0],val[1],val[2],val[3]);};})(loc));break;case gl.FLOAT_MAT2:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniformMatrix2fv(loc,false,new Float32Array(val));};})(loc));break;case gl.FLOAT_MAT3:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniformMatrix3fv(loc,false,new Float32Array(val));};})(loc));break;case gl.FLOAT_MAT4:shader.__defineSetter__(obj.name,(function(loc){return function(val){gl.uniformMatrix4fv(loc,false,new Float32Array(val));};})(loc));break;case gl.INT:shader.__defineSetter__(obj.name,(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(program,gl.ACTIVE_ATTRIBUTES);for(i=0;i<numAttribs;++i){try{obj=gl.getActiveAttrib(program,i);}
+catch(ea){if(!obj)continue;}
+glErr=gl.getError();if(glErr){x3dom.debug.logError("GL-Error (on searching attributes): "+glErr);}
+loc=gl.getAttribLocation(program,obj.name);shader[obj.name]=loc;}
+return shader;};x3dom.States=function(x3dElem){var that=this;this.active=false;this.viewer=document.createElement('div');this.viewer.id='x3dom-state-viewer';var title=document.createElement('div');title.className='x3dom-states-head';var subTitle=document.createElement('span');subTitle.className='x3dom-states-head2';title.appendChild(subTitle);this.measureList=document.createElement('ul');this.measureList.className='x3dom-states-list';this.infoList=document.createElement('ul');this.infoList.className='x3dom-states-list';this.viewer.appendChild(title);this.viewer.appendChild(this.measureList);this.viewer.appendChild(this.infoList);this.disableContextMenu=function(e){e.preventDefault();e.stopPropagation();e.returnValue=false;return false;};this.thousandSeperator=function(value){return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g,",");};this.toFixed=function(value){var fixed=(value<1)?2:(value<10)?2:2;return value.toFixed(fixed);};this.update=function(){if(!x3dElem.runtime&&this.updateMethodID!==undefined){clearInterval(this.updateMethodID);return;}
+var infos=x3dElem.runtime.states.infos;var measurements=x3dElem.runtime.states.measurements;this.measureList.innerHTML="";for(var m in measurements){infoItem=document.createElement('li');infoItem.className='x3dom-states-item';infoTitle=document.createElement('div');infoTitle.className='x3dom-states-item-title';infoTitle.appendChild(document.createTextNode(m));infoValue=document.createElement('div');infoValue.className='x3dom-states-item-value';infoValue.appendChild(document.createTextNode(this.toFixed(measurements[m])));infoItem.appendChild(infoTitle);infoItem.appendChild(infoValue);this.measureList.appendChild(infoItem);}
+this.infoList.innerHTML="";for(var i in infos){var infoItem=document.createElement('li');infoItem.className='x3dom-states-item';var infoTitle=document.createElement('div');infoTitle.className='x3dom-states-item-title';infoTitle.appendChild(document.createTextNode(i));var infoValue=document.createElement('div');infoValue.className='x3dom-states-item-value';infoValue.appendChild(document.createTextNode(this.thousandSeperator(infos[i])));infoItem.appendChild(infoTitle);infoItem.appendChild(infoValue);this.infoList.appendChild(infoItem);}};this.updateMethodID=window.setInterval(function(){that.update();},1000);this.viewer.addEventListener("contextmenu",that.disableContextMenu);};x3dom.States.prototype.display=function(value){this.active=(value!==undefined)?value:!this.active;this.viewer.style.display=(this.active)?"block":"none";};x3dom.StateManager=function(ctx3d)
+{this.gl=ctx3d;this.states=[];this.initStates();};x3dom.StateManager.prototype.initStates=function()
+{this.states['shaderID']=null;this.states['colorMask']={red:null,green:null,blue:null,alpha:null};this.states['depthMask']=null;this.states['stencilMask']=null;this.states['cullFace']=null;this.states['frontFace']=null;this.states['lineWidth']=null;this.states['blendColor']={red:null,green:null,blue:null,alpha:null};this.states['blendEquation']=null;this.states['blendEquationSeparate']={modeRGB:null,modeAlpha:null};this.states['blendFunc']={sfactor:null,dfactor:null};this.states['blendFuncSeparate']={srcRGB:null,dstRGB:null,srcAlpha:null,dstAlpha:null};this.states['depthFunc']=null;this.states['viewport']={x:null,y:null,width:null,height:null};this.states['depthRange']={zNear:null,zFar:null};};x3dom.StateManager.prototype.useProgram=function(shader)
+{if(this.states['shaderID']!=shader.shaderID)
+{this.gl.useProgram(shader.program);this.states['shaderID']=shader.shaderID;return true;}
+return false;};x3dom.StateManager.prototype.unsetProgram=function()
+{this.states['shaderID']=null;};x3dom.StateManager.prototype.enable=function(cap)
+{if(this.states[cap]!==true)
+{this.gl.enable(cap);this.states[cap]=true;}};x3dom.StateManager.prototype.disable=function(cap)
+{if(this.states[cap]!==false)
+{this.gl.disable(cap);this.states[cap]=false;}};x3dom.StateManager.prototype.colorMask=function(red,green,blue,alpha)
+{if(this.states['colorMask'].red!=red||this.states['colorMask'].green!=green||this.states['colorMask'].blue!=blue||this.states['colorMask'].alpha!=alpha)
+{this.gl.colorMask(red,green,blue,alpha);this.states['colorMask'].red=red;this.states['colorMask'].green=green;this.states['colorMask'].blue=blue;this.states['colorMask'].alpha=alpha;}};x3dom.StateManager.prototype.depthMask=function(flag)
+{if(this.states['depthMask']!=flag)
+{this.gl.depthMask(flag);this.states['depthMask']=flag;}};x3dom.StateManager.prototype.stencilMask=function(mask)
+{if(this.states['stencilMask']!=mask)
+{this.gl.stencilMask(mask);this.states['stencilMask']=mask;}};x3dom.StateManager.prototype.cullFace=function(mode)
+{if(this.states['cullFace']!=mode)
+{this.gl.cullFace(mode);this.states['cullFace']=mode;}};x3dom.StateManager.prototype.frontFace=function(mode)
+{if(this.states['frontFace']!=mode)
+{this.gl.frontFace(mode);this.states['frontFace']=mode;}};x3dom.StateManager.prototype.lineWidth=function(width)
+{width=(width<=1)?1:width;if(this.states['lineWidth']!=width)
+{this.gl.lineWidth(width);this.states['lineWidth']=width;}};x3dom.StateManager.prototype.blendColor=function(red,green,blue,alpha)
+{if(this.states['blendColor'].red!=red||this.states['blendColor'].green!=green||this.states['blendColor'].blue!=blue||this.states['blendColor'].alpha!=alpha)
+{this.gl.blendColor(red,green,blue,alpha);this.states['blendColor'].red=red;this.states['blendColor'].green=green;this.states['blendColor'].blue=blue;this.states['blendColor'].alpha=alpha;}};x3dom.StateManager.prototype.blendEquation=function(mode)
+{if(mode&&this.states['blendEquation']!=mode)
+{this.gl.blendEquation(mode);this.states['blendEquation']=mode;}};x3dom.StateManager.prototype.blendEquationSeparate=function(modeRGB,modeAlpha)
+{if(this.states['blendEquationSeparate'].modeRGB!=modeRGB||this.states['blendEquationSeparate'].modeAlpha!=modeAlpha)
+{this.gl.blendEquationSeparate(modeRGB,modeAlpha);this.states['blendEquationSeparate'].modeRGB=modeRGB;this.states['blendEquationSeparate'].modeAlpha=modeAlpha;}};x3dom.StateManager.prototype.blendFunc=function(sfactor,dfactor)
+{if(this.states['blendFunc'].sfactor!=sfactor||this.states['blendFunc'].dfactor!=dfactor)
+{this.gl.blendFunc(sfactor,dfactor);this.states['blendFunc'].sfactor=sfactor;this.states['blendFunc'].dfactor=dfactor;}};x3dom.StateManager.prototype.blendFuncSeparate=function(srcRGB,dstRGB,srcAlpha,dstAlpha)
+{if(this.states['blendFuncSeparate'].srcRGB!=srcRGB||this.states['blendFuncSeparate'].dstRGB!=dstRGB||this.states['blendFuncSeparate'].srcAlpha!=srcAlpha||this.states['blendFuncSeparate'].dstAlpha!=dstAlpha)
+{this.gl.blendFuncSeparate(srcRGB,dstRGB,srcAlpha,dstAlpha);this.states['blendFuncSeparate'].srcRGB=srcRGB;this.states['blendFuncSeparate'].dstRGB=dstRGB;this.states['blendFuncSeparate'].srcAlpha=srcAlpha;this.states['blendFuncSeparate'].dstAlpha=dstAlpha;}};x3dom.StateManager.prototype.depthFunc=function(func)
+{if(this.states['depthFunc']!=func)
+{this.gl.depthFunc(func);this.states['depthFunc']=func;}};x3dom.StateManager.prototype.depthRange=function(zNear,zFar)
+{if(zNear<0||zFar<0||zNear>zFar)
+{return;}
+zNear=(zNear>1)?1:zNear;zFar=(zFar>1)?1:zFar;if(this.states['depthRange'].zNear!=zNear||this.states['depthRange'].zFar!=zFar)
+{this.gl.depthRange(zNear,zFar);this.states['depthRange'].zNear=zNear;this.states['depthRange'].zFar=zFar;}};x3dom.StateManager.prototype.viewport=function(x,y,width,height)
+{if(this.states['viewport'].x!=x||this.states['viewport'].y!=y||this.states['viewport'].width!=width||this.states['viewport'].height!=height)
+{this.gl.viewport(x,y,width,height);this.states['viewport'].x=x;this.states['viewport'].y=y;this.states['viewport'].width=width;this.states['viewport'].height=height;}};x3dom.StateManager.prototype.bindFramebuffer=function(target,framebuffer)
+{this.gl.bindFramebuffer(target,framebuffer);this.initStates();};x3dom.BinaryContainerLoader={outOfMemory:false,checkError:function(gl){var glErr=gl.getError();if(glErr){if(glErr==gl.OUT_OF_MEMORY){this.outOfMemory=true;x3dom.debug.logError("GL-Error "+glErr+" on loading binary container (out of memory).");console.error("WebGL: OUT_OF_MEMORY");}
+else{x3dom.debug.logError("GL-Error "+glErr+" on loading binary container.");}}}};x3dom.BinaryContainerLoader.setupBinGeo=function(shape,sp,gl,viewarea,currContext)
+{if(this.outOfMemory){return;}
+var t00=new Date().getTime();var that=this;var binGeo=shape._cf.geometry.node;shape._webgl.binaryGeometry=-1;shape._webgl.internalDownloadCount=((binGeo._vf.index.length>0)?1:0)+
+((binGeo._hasStrideOffset&&binGeo._vf.coord.length>0)?1:0)+
+((!binGeo._hasStrideOffset&&binGeo._vf.coord.length>0)?1:0)+
+((!binGeo._hasStrideOffset&&binGeo._vf.normal.length>0)?1:0)+
+((!binGeo._hasStrideOffset&&binGeo._vf.texCoord.length>0)?1:0)+
+((!binGeo._hasStrideOffset&&binGeo._vf.color.length>0)?1:0);var createTriangleSoup=(binGeo._vf.normalPerVertex==false)||((binGeo._vf.index.length>0)&&(binGeo._vf.indexType=="Int32"||(binGeo._vf.indexType=="Uint32"&&!x3dom.caps.INDEX_UINT)));shape._webgl.makeSeparateTris={index:null,coord:null,normal:null,texCoord:null,color:null,pushBuffer:function(name,buf){this[name]=buf;if(--shape._webgl.internalDownloadCount==0){if(this.coord)
+this.createMesh();shape._nameSpace.doc.needRender=true;}
+if(--shape._nameSpace.doc.downloadCount==0)
+shape._nameSpace.doc.needRender=true;},createMesh:function(){var geoNode=binGeo;if(geoNode._hasStrideOffset){x3dom.debug.logError(geoNode._vf.indexType+" index type and per-face normals not supported for interleaved arrays.");return;}
+for(var k=0;k<shape._webgl.primType.length;k++){if(shape._webgl.primType[k]==gl.TRIANGLE_STRIP){x3dom.debug.logError("makeSeparateTris: triangle strips not yet supported for per-face normals.");return;}}
+var attribTypeStr=geoNode._vf.coordType;shape._webgl.coordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);var bgCenter,bgSize,bgPrecisionMax;if(shape._webgl.coordType!=gl.FLOAT)
+{if(geoNode._mesh._numPosComponents==4&&x3dom.Utils.isUnsignedType(geoNode._vf.coordType))
+bgCenter=x3dom.fields.SFVec3f.copy(geoNode.getMin());else
+bgCenter=x3dom.fields.SFVec3f.copy(geoNode._vf.position);bgSize=x3dom.fields.SFVec3f.copy(geoNode._vf.size);bgPrecisionMax=geoNode.getPrecisionMax('coordType');}
+else
+{bgCenter=new x3dom.fields.SFVec3f(0,0,0);bgSize=new x3dom.fields.SFVec3f(1,1,1);bgPrecisionMax=1.0;}
+var dataLen=shape._coordStrideOffset[0]/x3dom.Utils.getDataTypeSize(geoNode._vf.coordType);dataLen=(dataLen==0)?3:dataLen;x3dom.debug.logWarning("makeSeparateTris.createMesh called with coord length "+dataLen);if(this.color&&dataLen!=shape._colorStrideOffset[0]/x3dom.Utils.getDataTypeSize(geoNode._vf.colorType))
+{this.color=null;x3dom.debug.logWarning("Color format not supported.");}
+var texDataLen=this.texCoord?(shape._texCoordStrideOffset[0]/x3dom.Utils.getDataTypeSize(geoNode._vf.texCoordType)):0;geoNode._vf.normalType="Float32";shape._webgl.normalType=gl.FLOAT;geoNode._mesh._numNormComponents=3;shape._normalStrideOffset=[0,0];var posBuf=[],normBuf=[],texcBuf=[],colBuf=[];var i,j,l,n=this.index?(this.index.length-2):(this.coord.length/3-2);for(i=0;i<n;i+=3)
+{j=dataLen*(this.index?this.index[i]:i);var p0=new x3dom.fields.SFVec3f(bgSize.x*this.coord[j]/bgPrecisionMax,bgSize.y*this.coord[j+1]/bgPrecisionMax,bgSize.z*this.coord[j+2]/bgPrecisionMax);posBuf.push(this.coord[j]);posBuf.push(this.coord[j+1]);posBuf.push(this.coord[j+2]);if(dataLen>3)posBuf.push(this.coord[j+3]);if(this.color){colBuf.push(this.color[j]);colBuf.push(this.color[j+1]);colBuf.push(this.color[j+2]);if(dataLen>3)colBuf.push(this.color[j+3]);}
+if(this.texCoord){l=texDataLen*(this.index?this.index[i]:i);texcBuf.push(this.texCoord[l]);texcBuf.push(this.texCoord[l+1]);if(texDataLen>3){texcBuf.push(this.texCoord[l+2]);texcBuf.push(this.texCoord[l+3]);}}
+j=dataLen*(this.index?this.index[i+1]:i+1);var p1=new x3dom.fields.SFVec3f(bgSize.x*this.coord[j]/bgPrecisionMax,bgSize.y*this.coord[j+1]/bgPrecisionMax,bgSize.z*this.coord[j+2]/bgPrecisionMax);posBuf.push(this.coord[j]);posBuf.push(this.coord[j+1]);posBuf.push(this.coord[j+2]);if(dataLen>3)posBuf.push(this.coord[j+3]);if(this.color){colBuf.push(this.color[j]);colBuf.push(this.color[j+1]);colBuf.push(this.color[j+2]);if(dataLen>3)colBuf.push(this.color[j+3]);}
+if(this.texCoord){l=texDataLen*(this.index?this.index[i+1]:i+1);texcBuf.push(this.texCoord[l]);texcBuf.push(this.texCoord[l+1]);if(texDataLen>3){texcBuf.push(this.texCoord[l+2]);texcBuf.push(this.texCoord[l+3]);}}
+j=dataLen*(this.index?this.index[i+2]:i+2);var p2=new x3dom.fields.SFVec3f(bgSize.x*this.coord[j]/bgPrecisionMax,bgSize.y*this.coord[j+1]/bgPrecisionMax,bgSize.z*this.coord[j+2]/bgPrecisionMax);posBuf.push(this.coord[j]);posBuf.push(this.coord[j+1]);posBuf.push(this.coord[j+2]);if(dataLen>3)posBuf.push(this.coord[j+3]);if(this.color){colBuf.push(this.color[j]);colBuf.push(this.color[j+1]);colBuf.push(this.color[j+2]);if(dataLen>3)colBuf.push(this.color[j+3]);}
+if(this.texCoord){l=texDataLen*(this.index?this.index[i+2]:i+2);texcBuf.push(this.texCoord[l]);texcBuf.push(this.texCoord[l+1]);if(texDataLen>3){texcBuf.push(this.texCoord[l+2]);texcBuf.push(this.texCoord[l+3]);}}
+var a=p0.subtract(p1);var b=p1.subtract(p2);var norm=a.cross(b).normalize();for(j=0;j<3;j++){normBuf.push(norm.x);normBuf.push(norm.y);normBuf.push(norm.z);}}
+var buffer=gl.createBuffer();shape._webgl.buffers[1]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,x3dom.Utils.getArrayBufferView(geoNode._vf.coordType,posBuf),gl.STATIC_DRAW);gl.vertexAttribPointer(sp.position,geoNode._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);buffer=gl.createBuffer();shape._webgl.buffers[2]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(normBuf),gl.STATIC_DRAW);gl.vertexAttribPointer(sp.normal,geoNode._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);if(this.texCoord)
+{buffer=gl.createBuffer();shape._webgl.buffers[3]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,x3dom.Utils.getArrayBufferView(geoNode._vf.texCoordType,texcBuf),gl.STATIC_DRAW);gl.vertexAttribPointer(sp.texcoord,geoNode._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+if(this.color)
+{buffer=gl.createBuffer();shape._webgl.buffers[4]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,x3dom.Utils.getArrayBufferView(geoNode._vf.colorType,colBuf),gl.STATIC_DRAW);gl.vertexAttribPointer(sp.color,geoNode._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);}
+geoNode._vf.vertexCount=[];geoNode._vf.vertexCount[0]=posBuf.length/dataLen;geoNode._mesh._numCoords=geoNode._vf.vertexCount[0];geoNode._mesh._numFaces=geoNode._vf.vertexCount[0]/3;shape._webgl.primType=[];shape._webgl.primType[0]=gl.TRIANGLES;posBuf=null;normBuf=null;texcBuf=null;colBuf=null;this.index=null;this.coord=null;this.normal=null;this.texCoord=null;this.color=null;that.checkError(gl);delete shape._webgl.shader;shape._webgl.shader=currContext.cache.getDynamicShader(gl,viewarea,shape);}};if(binGeo._vf.index.length>0)
+{var xmlhttp0=new XMLHttpRequest();xmlhttp0.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.index)),true);xmlhttp0.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp0.send(null);xmlhttp0.onload=function()
+{if(!shape._webgl)
+return;var XHR_buffer=xmlhttp0.response;var geoNode=binGeo;var attribTypeStr=geoNode._vf.indexType;var indexArray=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);if(createTriangleSoup){shape._webgl.makeSeparateTris.pushBuffer("index",indexArray);return;}
+var indicesBuffer=gl.createBuffer();shape._webgl.buffers[0]=indicesBuffer;if(x3dom.caps.INDEX_UINT&&attribTypeStr=="Uint32"){shape._webgl.indexType=gl.UNSIGNED_INT;}
+else{shape._webgl.indexType=gl.UNSIGNED_SHORT;}
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indicesBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexArray,gl.STATIC_DRAW);shape._webgl.binaryGeometry=1;if(geoNode._vf.vertexCount[0]==0)
+geoNode._vf.vertexCount[0]=indexArray.length;geoNode._mesh._numFaces=0;for(var i=0;i<geoNode._vf.vertexCount.length;i++){if(shape._webgl.primType[i]==gl.TRIANGLE_STRIP)
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]-2;else
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]/3;}
+indexArray=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR0/ index load time: "+t11+" ms");};}
+if(binGeo._hasStrideOffset&&binGeo._vf.coord.length>0)
+{var xmlhttp=new XMLHttpRequest();xmlhttp.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.coord)),true);xmlhttp.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp.send(null);xmlhttp.onload=function()
+{if(!shape._webgl)
+return;var XHR_buffer=xmlhttp.response;var geoNode=binGeo;var attribTypeStr=geoNode._vf.coordType;shape._webgl.coordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);shape._webgl.normalType=shape._webgl.coordType;shape._webgl.texCoordType=shape._webgl.coordType;shape._webgl.colorType=shape._webgl.coordType;var attributes=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);var dataLen=shape._coordStrideOffset[0]/x3dom.Utils.getDataTypeSize(attribTypeStr);if(dataLen)
+geoNode._mesh._numCoords=attributes.length/dataLen;if(geoNode._vf.index.length==0){for(var i=0;i<geoNode._vf.vertexCount.length;i++){if(shape._webgl.primType[i]==gl.TRIANGLE_STRIP)
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]-2;else
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]/3;}}
+var buffer=gl.createBuffer();shape._webgl.buffers[1]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,attributes,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.position,geoNode._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(geoNode._vf.normal.length>0)
+{shape._webgl.buffers[2]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,attributes,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.normal,geoNode._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);}
+if(geoNode._vf.texCoord.length>0)
+{shape._webgl.buffers[3]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,attributes,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.texcoord,geoNode._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+if(geoNode._vf.color.length>0)
+{shape._webgl.buffers[4]=buffer;gl.bindBuffer(gl.ARRAY_BUFFER,buffer);gl.bufferData(gl.ARRAY_BUFFER,attributes,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.color,geoNode._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);}
+attributes=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR/ interleaved array load time: "+t11+" ms");};}
+if(!binGeo._hasStrideOffset&&binGeo._vf.coord.length>0)
+{var xmlhttp1=new XMLHttpRequest();xmlhttp1.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.coord)),true);xmlhttp1.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp1.send(null);xmlhttp1.onload=function()
+{if(!shape._webgl)
+return;var XHR_buffer=xmlhttp1.response;var geoNode=binGeo;var i=0;var attribTypeStr=geoNode._vf.coordType;shape._webgl.coordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);var vertices=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);if(createTriangleSoup){shape._webgl.makeSeparateTris.pushBuffer("coord",vertices);return;}
+gl.bindAttribLocation(sp.program,0,"position");var positionBuffer=gl.createBuffer();shape._webgl.buffers[1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.vertexAttribPointer(sp.position,geoNode._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);geoNode._mesh._numCoords=vertices.length/geoNode._mesh._numPosComponents;if(geoNode._vf.index.length==0){for(i=0;i<geoNode._vf.vertexCount.length;i++){if(shape._webgl.primType[i]==gl.TRIANGLE_STRIP)
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]-2;else
+geoNode._mesh._numFaces+=geoNode._vf.vertexCount[i]/3;}}
+if((attribTypeStr=="Float32")&&(shape._vf.bboxSize.x<0||shape._vf.bboxSize.y<0||shape._vf.bboxSize.z<0))
+{var min=new x3dom.fields.SFVec3f(vertices[0],vertices[1],vertices[2]);var max=new x3dom.fields.SFVec3f(vertices[0],vertices[1],vertices[2]);for(i=3;i<vertices.length;i+=3)
+{if(min.x>vertices[i+0]){min.x=vertices[i+0];}
+if(min.y>vertices[i+1]){min.y=vertices[i+1];}
+if(min.z>vertices[i+2]){min.z=vertices[i+2];}
+if(max.x<vertices[i+0]){max.x=vertices[i+0];}
+if(max.y<vertices[i+1]){max.y=vertices[i+1];}
+if(max.z<vertices[i+2]){max.z=vertices[i+2];}}
+shape._vf.bboxCenter.setValues(min.add(max).multiply(0.5));shape._vf.bboxSize.setValues(max.subtract(min));}
+vertices=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR1/ coord load time: "+t11+" ms");};}
+if(!binGeo._hasStrideOffset&&binGeo._vf.normal.length>0)
+{var xmlhttp2=new XMLHttpRequest();xmlhttp2.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.normal)),true);xmlhttp2.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp2.send(null);xmlhttp2.onload=function()
+{if(!shape._webgl)
+return;var XHR_buffer=xmlhttp2.response;var attribTypeStr=binGeo._vf.normalType;shape._webgl.normalType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);var normals=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);if(createTriangleSoup){shape._webgl.makeSeparateTris.pushBuffer("normal",normals);return;}
+var normalBuffer=gl.createBuffer();shape._webgl.buffers[2]=normalBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,normalBuffer);gl.bufferData(gl.ARRAY_BUFFER,normals,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.normal,binGeo._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);normals=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR2/ normal load time: "+t11+" ms");};}
+if(!binGeo._hasStrideOffset&&binGeo._vf.texCoord.length>0)
+{var xmlhttp3=new XMLHttpRequest();xmlhttp3.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.texCoord)),true);xmlhttp3.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp3.send(null);xmlhttp3.onload=function()
+{var i,j;var tmp;if(!shape._webgl)
+return;var XHR_buffer=xmlhttp3.response;var attribTypeStr=binGeo._vf.texCoordType;shape._webgl.texCoordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);var texCoords=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);if(createTriangleSoup){shape._webgl.makeSeparateTris.pushBuffer("texCoord",texCoords);return;}
+if(binGeo._vf["idsPerVertex"])
+{var idBuffer=gl.createBuffer();shape._webgl.buffers[5]=idBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,idBuffer);var texCoordStride=(shape._texCoordStrideOffset[0]===0)?2:shape._texCoordStrideOffset[0]/4;var ids=x3dom.Utils.getArrayBufferView(attribTypeStr,texCoords.length/2);for(i=0,j=0;i<texCoords.length;i+=2,j++)
+{ids[j]=texCoords[i+1]*65536+texCoords[i];}
+gl.bufferData(gl.ARRAY_BUFFER,ids,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.id,1,gl.FLOAT,false,4,0);gl.enableVertexAttribArray(sp.id);}
+else
+{var texcBuffer=gl.createBuffer();shape._webgl.buffers[3]=texcBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,texcBuffer);gl.bufferData(gl.ARRAY_BUFFER,texCoords,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.texcoord,binGeo._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+texCoords=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR3/ texCoord load time: "+t11+" ms");};}
+if(!binGeo._hasStrideOffset&&binGeo._vf.color.length>0)
+{var xmlhttp4=new XMLHttpRequest();xmlhttp4.open("GET",encodeURI(shape._nameSpace.getURL(binGeo._vf.color)),true);xmlhttp4.responseType="arraybuffer";shape._nameSpace.doc.downloadCount+=1;xmlhttp4.send(null);xmlhttp4.onload=function()
+{if(!shape._webgl)
+return;var XHR_buffer=xmlhttp4.response;var attribTypeStr=binGeo._vf.colorType;shape._webgl.colorType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);var colors=x3dom.Utils.getArrayBufferView(attribTypeStr,XHR_buffer);if(createTriangleSoup){shape._webgl.makeSeparateTris.pushBuffer("color",colors);return;}
+var colorBuffer=gl.createBuffer();shape._webgl.buffers[4]=colorBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,colorBuffer);gl.bufferData(gl.ARRAY_BUFFER,colors,gl.STATIC_DRAW);gl.vertexAttribPointer(sp.color,binGeo._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);colors=null;shape._nameSpace.doc.downloadCount-=1;shape._webgl.internalDownloadCount-=1;if(shape._webgl.internalDownloadCount==0)
+shape._nameSpace.doc.needRender=true;that.checkError(gl);var t11=new Date().getTime()-t00;x3dom.debug.logInfo("XHR4/ color load time: "+t11+" ms");};}};x3dom.BinaryContainerLoader.setupPopGeo=function(shape,sp,gl,viewarea,currContext)
+{if(this.outOfMemory){return;}
+var popGeo=shape._cf.geometry.node;if(popGeo.hasIndex()){shape._webgl.popGeometry=1;shape._webgl.buffers[0]=gl.createBuffer();gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[0]);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,popGeo.getTotalNumberOfIndices()*2,gl.STATIC_DRAW);shape._webgl.buffers[5]=gl.createBuffer();var idBuffer=new Float32Array(popGeo._vf.vertexBufferSize);(function(){for(var i=0;i<idBuffer.length;++i)idBuffer[i]=i;})();gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[5]);gl.bufferData(gl.ARRAY_BUFFER,idBuffer,gl.STATIC_DRAW);}
+else{shape._webgl.popGeometry=-1;}
+shape._webgl.buffers[1]=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[1]);gl.bufferData(gl.ARRAY_BUFFER,(popGeo._vf.attributeStride*popGeo._vf.vertexBufferSize),gl.STATIC_DRAW);var attribTypeStr=popGeo._vf.coordType;shape._webgl.coordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);shape._coordStrideOffset[0]=popGeo.getAttributeStride();shape._coordStrideOffset[1]=popGeo.getPositionOffset();gl.vertexAttribPointer(sp.position,shape._cf.geometry.node._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(popGeo.hasNormal()){attribTypeStr=popGeo._vf.normalType;shape._webgl.normalType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);shape._normalStrideOffset[0]=popGeo.getAttributeStride();shape._normalStrideOffset[1]=popGeo.getNormalOffset();shape._webgl.buffers[2]=shape._webgl.buffers[1];gl.vertexAttribPointer(sp.normal,shape._cf.geometry.node._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);}
+if(popGeo.hasTexCoord()){attribTypeStr=popGeo._vf.texCoordType;shape._webgl.texCoordType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);shape._webgl.buffers[3]=shape._webgl.buffers[1];shape._texCoordStrideOffset[0]=popGeo.getAttributeStride();shape._texCoordStrideOffset[1]=popGeo.getTexCoordOffset();gl.vertexAttribPointer(sp.texcoord,shape._cf.geometry.node._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+if(popGeo.hasColor()){attribTypeStr=popGeo._vf.colorType;shape._webgl.colorType=x3dom.Utils.getVertexAttribType(attribTypeStr,gl);shape._webgl.buffers[4]=shape._webgl.buffers[1];shape._colorStrideOffset[0]=popGeo.getAttributeStride();shape._colorStrideOffset[1]=popGeo.getColorOffset();gl.vertexAttribPointer(sp.color,shape._cf.geometry.node._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);}
+shape._webgl.currentNumIndices=0;shape._webgl.currentNumVertices=0;shape._webgl.numVerticesAtLevel=[];shape._webgl.levelsAvailable=0;this.checkError(gl);shape._webgl.levelLoaded=[];(function(){for(var i=0;i<popGeo.getNumLevels();++i)
+shape._webgl.levelLoaded.push(false);})();var uploadDataToGPU=function(data,lvl){shape._webgl.levelLoaded[lvl]=true;shape._webgl.numVerticesAtLevel[lvl]=0;if(data){var indexDataLengthInBytes=0;var redrawNeeded=false;if(popGeo.hasIndex()){indexDataLengthInBytes=popGeo.getNumIndicesByLevel(lvl)*2;if(indexDataLengthInBytes>0){redrawNeeded=true;var indexDataView=new Uint8Array(data,0,indexDataLengthInBytes);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[0]);(function(){var indexDataOffset=0;for(var i=0;i<lvl;++i){indexDataOffset+=popGeo.getNumIndicesByLevel(i);}
+gl.bufferSubData(gl.ELEMENT_ARRAY_BUFFER,indexDataOffset*2,indexDataView);})();}}
+var vertexDataLengthInBytes=data.byteLength-indexDataLengthInBytes;if(vertexDataLengthInBytes>0){redrawNeeded=true;var attributeDataView=new Uint8Array(data,indexDataLengthInBytes,vertexDataLengthInBytes);gl.bindBuffer(gl.ARRAY_BUFFER,shape._webgl.buffers[1]);if(!popGeo.hasIndex()){gl.bufferSubData(gl.ARRAY_BUFFER,shape._webgl.currentNumVertices*popGeo.getAttributeStride(),attributeDataView);}
+else{gl.bufferSubData(gl.ARRAY_BUFFER,popGeo.getVertexDataBufferOffset(lvl)*popGeo.getAttributeStride(),attributeDataView);}
+shape._webgl.numVerticesAtLevel[lvl]=vertexDataLengthInBytes/popGeo.getAttributeStride();shape._webgl.currentNumVertices+=shape._webgl.numVerticesAtLevel[lvl];}
+(function(){var numValidIndices=0;for(var i=shape._webgl.levelsAvailable;i<popGeo.getNumLevels();++i){if(shape._webgl.levelLoaded[i]===false){break;}
+else{numValidIndices+=popGeo.getNumIndicesByLevel(i);++shape._webgl.levelsAvailable;}}
+shape._webgl.currentNumIndices=numValidIndices;})();popGeo._mesh._numCoords=shape._webgl.currentNumVertices;popGeo._mesh._numFaces=(popGeo.hasIndex()?shape._webgl.currentNumIndices:shape._webgl.currentNumVertices)/3;popGeo.adaptVertexCount(popGeo.hasIndex()?popGeo._mesh._numFaces*3:popGeo._mesh._numCoords);if(redrawNeeded){shape._nameSpace.doc.needRender=true;}}};var dataURLs=popGeo.getDataURLs();var downloadCallbacks=[];var priorities=[];shape._webgl.downloadStartTimer=new Date().getTime();for(var i=0;i<dataURLs.length;++i){shape._nameSpace.doc.downloadCount+=1;(function(idx){downloadCallbacks.push(function(data){shape._nameSpace.doc.downloadCount-=1;return uploadDataToGPU(data,idx);});})(i);priorities.push(i);}
+x3dom.DownloadManager.get(dataURLs,downloadCallbacks,priorities);};x3dom.BinaryContainerLoader.setupImgGeo=function(shape,sp,gl,viewarea,currContext)
+{if(this.outOfMemory){return;}
+var imageGeometry=shape._cf.geometry.node;if(imageGeometry.getIndexTexture()){shape._webgl.imageGeometry=1;}else{shape._webgl.imageGeometry=-1;}
+imageGeometry.unsetGeoDirty();if(currContext.IG_PositionBuffer==null){currContext.IG_PositionBuffer=gl.createBuffer();}
+shape._webgl.buffers[1]=currContext.IG_PositionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,currContext.IG_PositionBuffer);var vertices=new Float32Array(shape._webgl.positions[0]);gl.bufferData(gl.ARRAY_BUFFER,vertices,gl.STATIC_DRAW);gl.bindBuffer(gl.ARRAY_BUFFER,currContext.IG_PositionBuffer);gl.vertexAttribPointer(sp.position,imageGeometry._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);vertices=null;this.checkError(gl);};x3dom.DrawableCollection=function(drawableCollectionConfig){this.collection=[];this.viewMatrix=drawableCollectionConfig.viewMatrix;this.projMatrix=drawableCollectionConfig.projMatrix;this.sceneMatrix=drawableCollectionConfig.sceneMatrix;this.viewarea=drawableCollectionConfig.viewArea;var scene=this.viewarea._scene;var env=scene.getEnvironment();var viewpoint=scene.getViewpoint();this.near=viewpoint.getNear();this.pixelHeightAtDistOne=viewpoint.getImgPlaneHeightAtDistOne()/this.viewarea._height;this.context=drawableCollectionConfig.context;this.gl=drawableCollectionConfig.gl;this.viewFrustum=this.viewarea.getViewfrustum(this.sceneMatrix);this.worldVol=new x3dom.fields.BoxVolume();this.frustumCulling=drawableCollectionConfig.frustumCulling&&(this.viewFrustum!=null);this.smallFeatureThreshold=drawableCollectionConfig.smallFeatureThreshold;this.sortOpaque=(this.smallFeatureThreshold>0&&env._lowPriorityThreshold<1);this.sortTrans=drawableCollectionConfig.sortTrans;this.prioLevels=10;this.maxTreshold=100;this.sortBySortKey=false;this.sortByPriority=false;this.numberOfNodes=0;this.length=0;};x3dom.DrawableCollection.prototype.cull=function(transform,graphState,singlePath,planeMask){var node=graphState.boundedNode;if(!node||!node._vf.render){return 0;}
+var volume=node.getVolume();var MASK_SET=63;if(this.frustumCulling&&graphState.needCulling){var wvol;if(singlePath&&!graphState.worldVolume.isValid()){graphState.worldVolume.transformFrom(transform,volume);wvol=graphState.worldVolume;}
+else if(planeMask<MASK_SET){this.worldVol.transformFrom(transform,volume);wvol=this.worldVol;}
+if(planeMask<MASK_SET)
+planeMask=this.viewFrustum.intersect(wvol,planeMask);if(planeMask<=0){return-1;}}
+else{planeMask=MASK_SET;}
+graphState.coverage=-1;if(this.smallFeatureThreshold>0||node.forceUpdateCoverage()){var modelViewMat=this.viewMatrix.mult(transform);graphState.center=modelViewMat.multMatrixPnt(volume.getCenter());var rVec=modelViewMat.multMatrixVec(volume.getRadialVec());var r=rVec.length();var dist=Math.max(-graphState.center.z-r,this.near);var projPixelLength=dist*this.pixelHeightAtDistOne;graphState.coverage=(r*2.0)/projPixelLength;if(this.smallFeatureThreshold>0&&graphState.coverage<this.smallFeatureThreshold&&graphState.needCulling){return 0;}}
+this.numberOfNodes++;return planeMask;};x3dom.DrawableCollection.prototype.addShape=function(shape,transform,graphState){var drawable={};drawable.shape=shape;drawable.transform=transform;drawable.localTransform=graphState.localMatrix;drawable.localVolume=graphState.volume;drawable.worldVolume=x3dom.fields.BoxVolume.copy(graphState.worldVolume);drawable.priority=Math.max(0,graphState.coverage);drawable.shaderID=shape.getShaderProperties(this.viewarea).id;var appearance=shape._cf.appearance.node;drawable.sortType=appearance?appearance._vf.sortType.toLowerCase():"opaque";drawable.sortKey=appearance?appearance._vf.sortKey:0;if(drawable.sortType=='transparent'){if(this.smallFeatureThreshold>0){drawable.zPos=graphState.center.z;}
+else{var center=transform.multMatrixPnt(shape.getCenter());center=this.viewMatrix.multMatrixPnt(center);drawable.zPos=center.z;}}
+if(!this.sortBySortKey&&drawable.sortKey!=0){this.sortBySortKey=true;}
+if(this.collection[drawable.sortType]===undefined){this.collection[drawable.sortType]=[];}
+this.collection[drawable.sortType].push(drawable);this.length++;if(this.context&&this.gl){this.context.setupShape(this.gl,drawable,this.viewarea);}};x3dom.DrawableCollection.prototype.addDrawable=function(drawable){drawable.shaderID=drawable.shape.getShaderProperties(this.viewarea).id;var appearance=drawable.shape._cf.appearance.node;drawable.sortType=appearance?appearance._vf.sortType.toLowerCase():"opaque";drawable.sortKey=appearance?appearance._vf.sortKey:0;if(drawable.sortType=='transparent'){var center=drawable.transform.multMatrixPnt(drawable.shape.getCenter());center=this.viewMatrix.multMatrixPnt(center);drawable.zPos=center.z;}
+if(!this.sortBySortKey&&drawable.sortKey!=0){this.sortBySortKey=true;}
+if(this.collection[drawable.sortType]===undefined){this.collection[drawable.sortType]=[];}
+this.collection[drawable.sortType].push(drawable);this.length++;if(this.context&&this.gl){this.context.setupShape(this.gl,drawable,this.viewarea);}};x3dom.DrawableCollection.prototype.calculatePriority=function(graphState){var priority=Math.max(0,graphState.coverage);var pl=this.prioLevels-1;priority=Math.min(Math.round(priority/(this.maxTreshold/pl)),pl);return priority;};x3dom.DrawableCollection.prototype.concat=function(){var opaque=(this.collection['opaque']!==undefined)?this.collection['opaque']:[];var transparent=(this.collection['transparent']!==undefined)?this.collection['transparent']:[];this.collection=opaque.concat(transparent);};x3dom.DrawableCollection.prototype.get=function(idx){return this.collection[idx];};x3dom.DrawableCollection.prototype.sort=function(){var opaque=[];var transparent=[];var that=this;if(this.collection['opaque']!==undefined){if(this.sortOpaque){this.collection['opaque'].sort(function(a,b){if(a.sortKey==b.sortKey||!that.sortBySortKey){return b.priority-a.priority;}
+return a.sortKey-b.sortKey;});}
+opaque=this.collection['opaque'];}
+if(this.collection['transparent']!==undefined){if(this.sortTrans){this.collection['transparent'].sort(function(a,b){if(a.sortKey==b.sortKey||!that.sortBySortKey){if(a.priority==b.priority||!that.sortByPriority){return a.zPos-b.zPos;}
+return b.priority-a.priority;}
+return a.sortKey-b.sortKey;});}
+transparent=this.collection['transparent'];}
+this.collection=opaque.concat(transparent);};x3dom.DrawableCollection.prototype.forEach=function(fnc,maxPriority){maxPriority=(maxPriority!==undefined)?Math.min(maxPriority,this.prioLevels):this.prioLevels;var sortKey,priority,shaderID,drawable;for(sortKey=0;sortKey<this.collection['opaque'].length;++sortKey)
+{if(this.collection['opaque'][sortKey]!==undefined)
+{for(priority=this.collection['opaque'][sortKey].length;priority>0;--priority)
+{if(this.collection['opaque'][sortKey][priority]!==undefined)
+{for(shaderID in this.collection['opaque'][sortKey][priority])
+{for(drawable=0;drawable<this.collection['opaque'][sortKey][priority][shaderID].length;++drawable)
+{fnc(this.collection['opaque'][sortKey][priority][shaderID][drawable]);}}}}}}
+for(sortKey=0;sortKey<this.collection['transparent'].length;++sortKey)
+{if(this.collection['transparent'][sortKey]!==undefined)
+{for(priority=this.collection['transparent'][sortKey].length;priority>0;--priority)
+{if(this.collection['transparent'][sortKey][priority]!==undefined)
+{for(var shaderId in this.collection['transparent'][sortKey][priority])
+{this.collection['transparent'][sortKey][priority][shaderId].sort(function(a,b){return a.zPos-b.zPos});for(drawable=0;drawable<this.collection['transparent'][sortKey][priority][shaderId].length;++drawable)
+{fnc(this.collection['transparent'][sortKey][priority][shaderId][drawable]);}}}}}}};x3dom.Moveable=function(x3domElem,boundedObj,callback,gridSize,mode){this._x3domRoot=x3domElem;this._runtime=x3domElem.runtime;this._callback=callback;this._gridSize=gridSize?gridSize:0;this._moveable=boundedObj;this._drag=false;this._w=0;this._h=0;this._uPlane=null;this._vPlane=null;this._pPlane=null;this._isect=null;this._translationOffset=null;this._rotationOffset=null;this._scaleOffset=null;this._lastX=0;this._lastY=0;this._buttonState=0;this._mode=(mode&&mode.length)?mode.toLowerCase():"translation";this._firstRay=null;this._matrixTrafo=null;this._navType="examine";this.attachHandlers();};x3dom.Moveable.prototype.setGridSize=function(gridSize){this._gridSize=gridSize;};x3dom.Moveable.prototype.setMode=function(mode){this._mode=mode.toLowerCase();};x3dom.Moveable.prototype.attachHandlers=function(){this._moveable._iMove=this;if(!this._x3domRoot._iMove)
+this._x3domRoot._iMove=[];this._x3domRoot._iMove.push(this);this._moveable.addEventListener('mousedown',this.start,false);this._moveable.addEventListener('mouseover',this.over,false);this._moveable.addEventListener('mouseout',this.out,false);if(this._x3domRoot._iMove.length==1){this._x3domRoot.addEventListener('mouseup',this.stop,false);this._x3domRoot.addEventListener('mouseout',this.stop,false);this._x3domRoot.addEventListener('mousemove',this.move,true);if(!this._runtime.canvas.disableTouch){this._x3domRoot.addEventListener('MozTouchDown',this.touchStartHandlerMoz,false);this._x3domRoot.addEventListener('MozTouchMove',this.touchMoveHandlerMoz,true);this._x3domRoot.addEventListener('MozTouchUp',this.touchEndHandlerMoz,false);this._x3domRoot.addEventListener('touchstart',this.touchStartHandler,false);this._x3domRoot.addEventListener('touchmove',this.touchMoveHandler,true);this._x3domRoot.addEventListener('touchend',this.touchEndHandler,false);}}};x3dom.Moveable.prototype.detachHandlers=function(){var iMove=this._x3domRoot._iMove;if(iMove){for(var i=0,n=iMove.length;i<n;i++){if(iMove[i]==this){iMove.splice(i,1);break;}}}
+this._moveable.removeEventListener('mousedown',this.start,false);this._moveable.removeEventListener('mouseover',this.over,false);this._moveable.removeEventListener('mouseout',this.out,false);if(iMove.length==0){this._x3domRoot.removeEventListener('mouseup',this.stop,false);this._x3domRoot.removeEventListener('mouseout',this.stop,false);this._x3domRoot.removeEventListener('mousemove',this.move,true);if(!this._runtime.canvas.disableTouch){this._x3domRoot.removeEventListener('MozTouchDown',this.touchStartHandlerMoz,false);this._x3domRoot.removeEventListener('MozTouchMove',this.touchMoveHandlerMoz,true);this._x3domRoot.removeEventListener('MozTouchUp',this.touchEndHandlerMoz,false);this._x3domRoot.removeEventListener('touchstart',this.touchStartHandler,false);this._x3domRoot.removeEventListener('touchmove',this.touchMoveHandler,true);this._x3domRoot.removeEventListener('touchend',this.touchEndHandler,false);}}
+if(this._moveable._iMove)
+delete this._moveable._iMove;};x3dom.Moveable.prototype.calcViewPlane=function(origin){this._w=this._runtime.getWidth();this._h=this._runtime.getHeight();var ray=this._runtime.getViewingRay(0,this._h-1);var r=ray.pos.add(ray.dir);ray=this._runtime.getViewingRay(this._w-1,this._h-1);var s=ray.pos.add(ray.dir);ray=this._runtime.getViewingRay(0,0);var t=ray.pos.add(ray.dir);this._uPlane=s.subtract(r).normalize();this._vPlane=t.subtract(r).normalize();if(arguments.length===0)
+this._pPlane=r;else
+this._pPlane=x3dom.fields.SFVec3f.copy(origin);};x3dom.Moveable.prototype.det=function(mat){return mat[0][0]*mat[1][1]*mat[2][2]+mat[0][1]*mat[1][2]*mat[2][0]+
+mat[0][2]*mat[2][1]*mat[1][0]-mat[2][0]*mat[1][1]*mat[0][2]-
+mat[0][0]*mat[2][1]*mat[1][2]-mat[1][0]*mat[0][1]*mat[2][2];};x3dom.Moveable.prototype.translateXY=function(l){var track=null;var z=[],n=[];for(var i=0;i<3;i++){z[i]=[];n[i]=[];z[i][0]=this._uPlane.at(i);n[i][0]=z[i][0];z[i][1]=this._vPlane.at(i);n[i][1]=z[i][1];z[i][2]=(l.pos.subtract(this._pPlane)).at(i);n[i][2]=-l.dir.at(i);}
+var s=this.det(n);if(s!==0){var t=this.det(z)/s;track=l.pos.addScaled(l.dir,t);}
+if(track){if(this._isect){track=track.subtract(this._isect);}
+track=track.add(this._translationOffset);}
+return track;};x3dom.Moveable.prototype.translateZ=function(l,currY){var vol=this._runtime.getSceneBBox();var sign=(currY<this._lastY)?1:-1;var fact=sign*(vol.max.subtract(vol.min)).length()/100;this._translationOffset=this._translationOffset.addScaled(l.dir,fact);return this._translationOffset;};x3dom.Moveable.prototype.rotate=function(posX,posY){var twoPi=2*Math.PI;var alpha=((posY-this._lastY)*twoPi)/this._w;var beta=((posX-this._lastX)*twoPi)/this._h;var q=x3dom.fields.Quaternion.axisAngle(this._uPlane,alpha);var h=q.toMatrix();this._rotationOffset=h.mult(this._rotationOffset);q=x3dom.fields.Quaternion.axisAngle(this._vPlane,beta);h=q.toMatrix();this._rotationOffset=h.mult(this._rotationOffset);var mat=this._rotationOffset.mult(x3dom.fields.SFMatrix4f.scale(this._scaleOffset));var rot=new x3dom.fields.Quaternion(0,0,1,0);rot.setValue(mat);return rot;};x3dom.Moveable.prototype.over=function(event){var that=this._iMove;that._runtime.getCanvas().style.cursor="crosshair";};x3dom.Moveable.prototype.out=function(event){var that=this._iMove;if(!that._drag)
+that._runtime.getCanvas().style.cursor="pointer";};x3dom.Moveable.prototype.start=function(event){var that=this._iMove;switch(that._mode){case"translation":that._buttonState=(event.button==4)?1:(event.button&3);break;case"rotation":that._buttonState=4;break;case"all":default:that._buttonState=event.button;break;}
+if(!that._drag&&that._buttonState){that._lastX=event.layerX;that._lastY=event.layerY;that._drag=true;that._navType=that._runtime.navigationType();that._runtime.noNav();that._isect=new x3dom.fields.SFVec3f(event.worldX,event.worldY,event.worldZ);that.calcViewPlane(that._isect);that._firstRay=that._runtime.getViewingRay(event.layerX,event.layerY);var mTrans=that._moveable.getAttribute("translation");that._matrixTrafo=null;if(mTrans){that._translationOffset=x3dom.fields.SFVec3f.parse(mTrans);var mRot=that._moveable.getAttribute("rotation");mRot=mRot?x3dom.fields.Quaternion.parseAxisAngle(mRot):new x3dom.fields.Quaternion(0,0,1,0);that._rotationOffset=mRot.toMatrix();var mScal=that._moveable.getAttribute("scale");that._scaleOffset=mScal?x3dom.fields.SFVec3f.parse(mScal):new x3dom.fields.SFVec3f(1,1,1);}
+else{mTrans=that._moveable.getAttribute("matrix");if(mTrans){that._matrixTrafo=x3dom.fields.SFMatrix4f.parse(mTrans).transpose();var translation=new x3dom.fields.SFVec3f(0,0,0),scaleFactor=new x3dom.fields.SFVec3f(1,1,1);var rotation=new x3dom.fields.Quaternion(0,0,1,0),scaleOrientation=new x3dom.fields.Quaternion(0,0,1,0);that._matrixTrafo.getTransform(translation,rotation,scaleFactor,scaleOrientation);that._translationOffset=translation;that._rotationOffset=rotation.toMatrix();that._scaleOffset=scaleFactor;}
+else{that._translationOffset=new x3dom.fields.SFVec3f(0,0,0);that._rotationOffset=new x3dom.fields.SFMatrix4f();that._scaleOffset=new x3dom.fields.SFVec3f(1,1,1);}}
+that._runtime.getCanvas().style.cursor="crosshair";}};x3dom.Moveable.prototype.move=function(event){for(var i=0,n=this._iMove.length;i<n;i++){var that=this._iMove[i];if(that._drag){var pos=that._runtime.mousePosition(event);var ray=that._runtime.getViewingRay(pos[0],pos[1]);var track=null;if(that._buttonState==2)
+track=that.translateZ(that._firstRay,pos[1]);else if(that._buttonState==1)
+track=that.translateXY(ray);else
+track=that.rotate(pos[0],pos[1]);if(track){if(that._gridSize>0&&that._buttonState!=4){var x=that._gridSize*Math.round(track.x/that._gridSize);var y=that._gridSize*Math.round(track.y/that._gridSize);var z=that._gridSize*Math.round(track.z/that._gridSize);track=new x3dom.fields.SFVec3f(x,y,z);}
+if(!that._matrixTrafo){if(that._buttonState==4){that._moveable.setAttribute("rotation",track.toAxisAngle().toString());}
+else{that._moveable.setAttribute("translation",track.toString());}}
+else{if(that._buttonState==4){that._matrixTrafo.setRotate(track);}
+else{that._matrixTrafo.setTranslate(track);}
+that._moveable.setAttribute("matrix",that._matrixTrafo.toGL().toString());}
+if(that._callback){that._callback(that._moveable,track);}}
+that._lastX=pos[0];that._lastY=pos[1];}}};x3dom.Moveable.prototype.stop=function(event){for(var i=0,n=this._iMove.length;i<n;i++){var that=this._iMove[i];if(that._drag){that._lastX=event.layerX;that._lastY=event.layerY;that._isect=null;that._drag=false;var navi=that._runtime.canvas.doc._scene.getNavigationInfo();navi.setType(that._navType);that._runtime.getCanvas().style.cursor="pointer";}}};x3dom.Moveable.prototype.touchStartHandler=function(evt){evt.preventDefault();};x3dom.Moveable.prototype.touchStartHandlerMoz=function(evt){evt.preventDefault();};x3dom.Moveable.prototype.touchMoveHandler=function(evt){evt.preventDefault();};x3dom.Moveable.prototype.touchMoveHandlerMoz=function(evt){evt.preventDefault();};x3dom.Moveable.prototype.touchEndHandler=function(evt){if(this._iMove.length){var that=this._iMove[0];that.stop.apply(that._x3domRoot,[evt]);}
+evt.preventDefault();};x3dom.Moveable.prototype.touchEndHandlerMoz=function(evt){if(this._iMove.length){var that=this._iMove[0];that.stop.apply(that._x3domRoot,[evt]);}
+evt.preventDefault();};x3dom.X3DCanvas=function(x3dElem,canvasIdx)
+{var that=this;this._canvasIdx=canvasIdx;this.isFlashReady=false;this.x3dElem=x3dElem;this._current_dim=[0,0];this.fps_t0=new Date().getTime();this.lastTimeFPSWasTaken=0;this.framesSinceLastTime=0;this.doc=null;x3dom.caps.DOMNodeInsertedEvent_perSubtree=(navigator.userAgent.indexOf('MSIE')!=-1||navigator.userAgent.indexOf('Trident'))?true:false;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&&that.doc._viewarea){that.doc._viewarea._width=parseInt(that.canvas.getAttribute("width"),0);that.doc.needRender=true;}
+break;case"height":that.canvas.setAttribute("height",newVal);if(that.doc&&that.doc._viewarea){that.doc._viewarea._height=parseInt(that.canvas.getAttribute("height"),0);that.doc.needRender=true;}
+break;default:break;}};x3dom.caps.MOBILE=(navigator.appVersion.indexOf("Mobile")>-1);this.backend=this.x3dElem.getAttribute('backend');if(this.backend)
+this.backend=this.backend.toLowerCase();else
+this.backend='none';if(this.backend=='flash'){this.backend='flash';this.canvas=this._createFlashObject(x3dElem);if(this.canvas!=null){this.canvas.parent=this;this.gl=this._initFlashContext(this.canvas,this.flash_renderType);}else{this._createInitFailedDiv(x3dElem);return;}}else{this.canvas=this._createHTMLCanvas(x3dElem);this.canvas.parent=this;this.gl=this._initContext(this.canvas,(this.backend.search("desktop")>=0),(this.backend.search("mobile")>=0),(this.backend.search("flashie")>=0),(this.backend.search("webgl2")>=0));this.backend='webgl';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,this.flash_renderType);}else{this._createInitFailedDiv(x3dElem);return;}}}
+x3dom.caps.BACKEND=this.backend;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;}
+if(this.backend!="flash"){this.showStat=x3dElem.getAttribute("showStat");this.stateViewer=new x3dom.States(x3dElem);if(this.showStat!==null&&this.showStat=="true"){this.stateViewer.display(true);}
+this.x3dElem.appendChild(this.stateViewer.viewer);}
+this.showProgress=x3dElem.getAttribute("showProgress");this.progressDiv=this._createProgressDiv();this.progressDiv.style.display=(this.showProgress!==null&&this.showProgress=="true")?"inline":"none";this.x3dElem.appendChild(this.progressDiv);this.showTouchpoints=x3dElem.getAttribute("showTouchpoints");this.showTouchpoints=this.showTouchpoints?!(this.showTouchpoints.toLowerCase()=="false"):true;this.disableTouch=x3dElem.getAttribute("disableTouch");this.disableTouch=this.disableTouch?(this.disableTouch.toLowerCase()=="true"):false;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();return false;};this.canvas.addEventListener("webglcontextlost",function(event){x3dom.debug.logError("WebGL context lost");event.preventDefault();},false);this.canvas.addEventListener("webglcontextrestored",function(event){x3dom.debug.logError("recover WebGL state and resources on context lost NYI");event.preventDefault();},false);this.canvas.addEventListener('mousedown',function(evt){if(!this.isMulti){this.focus();this.classList.add('x3dom-canvas-mousedown');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;}
+if(evt.shiftKey){this.mouse_button=1;}
+if(evt.ctrlKey){this.mouse_button=4;}
+if(evt.altKey){this.mouse_button=2;}
+var pos=this.parent.mousePosition(evt);this.mouse_drag_x=pos.x;this.mouse_drag_y=pos.y;this.mouse_dragging=true;this.parent.doc.onMousePress(that.gl,this.mouse_drag_x,this.mouse_drag_y,this.mouse_button);this.parent.doc.needRender=true;}},false);this.canvas.addEventListener('mouseup',function(evt){if(!this.isMulti){var prev_mouse_button=this.mouse_button;this.classList.remove('x3dom-canvas-mousedown');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,prev_mouse_button);this.parent.doc.needRender=true;}},false);this.canvas.addEventListener('mouseover',function(evt){if(!this.isMulti){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;}},false);this.canvas.addEventListener('mouseout',function(evt){if(!this.isMulti){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;}},false);this.canvas.addEventListener('dblclick',function(evt){if(!this.isMulti){this.mouse_button=0;var pos=this.parent.mousePosition(evt);this.mouse_drag_x=pos.x;this.mouse_drag_y=pos.y;this.mouse_dragging=false;this.parent.doc.onDoubleClick(that.gl,this.mouse_drag_x,this.mouse_drag_y);this.parent.doc.needRender=true;}},false);this.canvas.addEventListener('mousemove',function(evt){if(!this.isMulti){if(evt.shiftKey){this.mouse_button=1;}
+if(evt.ctrlKey){this.mouse_button=4;}
+if(evt.altKey){this.mouse_button=2;}
+var pos=this.parent.mousePosition(evt);this.mouse_drag_x=pos.x;this.mouse_drag_y=pos.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.preventDefault();evt.stopPropagation();}},false);this.canvas.addEventListener('DOMMouseScroll',function(evt){if(!this.isMulti){this.focus();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;evt.preventDefault();evt.stopPropagation();}},false);this.canvas.addEventListener('mousewheel',function(evt){if(!this.isMulti){this.focus();this.mouse_drag_y-=0.1*evt.wheelDelta;this.parent.doc.onDrag(that.gl,this.mouse_drag_x,this.mouse_drag_y,2);this.parent.doc.needRender=true;evt.preventDefault();evt.stopPropagation();}},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;},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;},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;},true);var touches={numTouches:0,firstTouchTime:new Date().getTime(),firstTouchPoint:new x3dom.fields.SFVec2f(0,0),lastDrag:new x3dom.fields.SFVec2f(),lastMiddle:new x3dom.fields.SFVec2f(),lastDistance:new x3dom.fields.SFVec2f(),lastSquareDistance:0,lastAngle:0,lastLayer:[],examineNavType:true,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;},disableTouch:this.disableTouch,visMarker:this.showTouchpoints,visMarkerBag:[],visualizeTouches:function(evt)
+{if(!this.visMarker)
+return;var touchBag=[];var marker=null;for(var i=0;i<evt.touches.length;i++){var id=evt.touches[i].identifier||evt.touches[i].streamId;if(!id)id=0;var index=this.visMarkerBag.indexOf(id);if(index>=0){marker=document.getElementById("visMarker"+id);marker.style.left=(evt.touches[i].pageX)+"px";marker.style.top=(evt.touches[i].pageY)+"px";}
+else{marker=document.createElement("div");marker.appendChild(document.createTextNode("#"+id));marker.id="visMarker"+id;marker.className="x3dom-touch-marker";document.body.appendChild(marker);index=this.visMarkerBag.length;this.visMarkerBag[index]=id;}
+touchBag.push(id);}
+for(var j=this.visMarkerBag.length-1;j>=0;j--){var oldId=this.visMarkerBag[j];if(touchBag.indexOf(oldId)<0){this.visMarkerBag.splice(j,1);marker=document.getElementById("visMarker"+oldId);document.body.removeChild(marker);}}}};var mozilla_ids=[];var mozilla_touches={touches:[],preventDefault:function(){}};var touchStartHandler=function(evt,doc)
+{this.isMulti=true;evt.preventDefault();touches.visualizeTouches(evt);this.focus();if(doc==null)
+doc=this.parent.doc;var navi=doc._scene.getNavigationInfo();touches.examineNavType=(navi.getType()=="examine");touches.lastLayer=[];var i,pos;for(i=0;i<evt.touches.length;i++){pos=this.parent.mousePosition(evt.touches[i]);touches.lastLayer.push([evt.touches[i].identifier,new x3dom.fields.SFVec2f(pos.x,pos.y)]);}
+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);}
+doc._scene.updateVolume();if(touches.examineNavType){for(i=0;i<evt.touches.length;i++){pos=this.parent.mousePosition(evt.touches[i]);doc.onPick(that.gl,pos.x,pos.y);doc._viewarea.prepareEvents(pos.x,pos.y,1,"onmousedown");doc._viewarea._pickingInfo.lastClickObj=doc._viewarea._pickingInfo.pickObj;}}
+else if(evt.touches.length){pos=this.parent.mousePosition(evt.touches[0]);doc.onMousePress(that.gl,pos.x,pos.y,1);}
+doc.needRender=true;};var touchStartHandlerMoz=function(evt)
+{this.isMulti=true;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,this.parent.doc);};var touchMoveHandler=function(evt,doc)
+{evt.preventDefault();touches.visualizeTouches(evt);if(doc==null)
+doc=this.parent.doc;var pos=null;var rotMatrix=null;if(touches.examineNavType){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);rotMatrix=mx.mult(my);doc.onMoveView(that.gl,null,rotMatrix);}
+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;rotMatrix=x3dom.fields.SFMatrix4f.rotationZ(angleDelta);touches.lastMiddle=middle;touches.lastDistance=distance;touches.lastSquareDistance=squareDistance;doc.onMoveView(that.gl,deltaMove,rotMatrix);}}
+else if(evt.touches.length){pos=this.parent.mousePosition(evt.touches[0]);doc.onDrag(that.gl,pos.x,pos.y,1);}
+doc.needRender=true;};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,doc)
+{this.isMulti=false;evt.preventDefault();touches.visualizeTouches(evt);if(doc==null)
+doc=this.parent.doc;doc._viewarea._isMoving=false;if(touches.numTouches==2&&evt.touches.length==1)
+touches.lastDrag=new x3dom.fields.SFVec2f(evt.touches[0].screenX,evt.touches[0].screenY);var dblClick=false;if(evt.touches.length<2){if(touches.numTouches==1)
+dblClick=true;touches.numTouches=evt.touches.length;}
+if(touches.examineNavType){for(var i=0;i<touches.lastLayer.length;i++){var pos=touches.lastLayer[i][1];doc.onPick(that.gl,pos.x,pos.y);if(doc._scene._vf.pickMode.toLowerCase()!=="box"){doc._viewarea.prepareEvents(pos.x,pos.y,1,"onmouseup");doc._viewarea._pickingInfo.lastClickObj=doc._viewarea._pickingInfo.pickObj;if(doc._viewarea._pickingInfo.pickObj&&doc._viewarea._pickingInfo.pickObj===doc._viewarea._pickingInfo.lastClickObj){doc._viewarea.prepareEvents(pos.x,pos.y,1,"onclick");}}
+else{var line=doc._viewarea.calcViewRay(pos.x,pos.y);var isect=doc._scene.doIntersect(line);var obj=line.hitObject;if(isect&&obj){doc._viewarea._pick.setValues(line.hitPoint);doc._viewarea.checkEvents(obj,pos.x,pos.y,1,"onclick");x3dom.debug.logInfo("Hit '"+obj._xmlNode.localName+"/ "+
+obj._DEF+"' at pos "+doc._viewarea._pick);}}}
+if(dblClick){var now=new Date().getTime();var dist=touches.firstTouchPoint.subtract(touches.lastDrag).length();if(dist<18&&now-touches.firstTouchTime<180)
+doc.onDoubleClick(that.gl,0,0);touches.firstTouchTime=now;touches.firstTouchPoint=touches.lastDrag;}}
+else if(touches.lastLayer.length){pos=touches.lastLayer[0][1];doc.onMouseRelease(that.gl,pos.x,pos.y,0,1);}
+doc.needRender=true;};var touchEndHandlerMoz=function(evt)
+{this.isMulti=false;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.parent.doc);};if(!this.disableTouch)
+{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',touchMoveHandler,true);this.canvas.addEventListener('touchend',touchEndHandler,true);}}};x3dom.X3DCanvas.prototype._initContext=function(canvas,forbidMobileShaders,forceMobileShaders,forceFlashForIE,tryWebGL2)
+{x3dom.debug.logInfo("Initializing X3DCanvas for ["+canvas.id+"]");var gl=x3dom.gfx_webgl(canvas,forbidMobileShaders,forceMobileShaders,tryWebGL2,this.x3dElem);if(!gl)
+{x3dom.debug.logError("No 3D context found...");this.x3dElem.removeChild(canvas);return null;}
+else
+{var webglVersion=parseFloat(x3dom.caps.VERSION.match(/\d+\.\d+/)[0]);if(webglVersion<1.0){console.log(forceFlashForIE);if(forceFlashForIE){x3dom.debug.logError("No valid 3D context found...");this.x3dElem.removeChild(canvas);return null;}else{x3dom.debug.logError("WebGL version "+x3dom.caps.VERSION+" lacks important WebGL/GLSL features needed for shadows, special vertex attribute types, etc.!");}}}
+return gl;};x3dom.X3DCanvas.prototype._initFlashContext=function(canvas,renderType){x3dom.debug.logInfo("Initializing X3DObject for ["+canvas.id+"]");return x3dom.gfx_flash(canvas,renderType);};x3dom.X3DCanvas.prototype.appendParam=function(node,name,value){var param=document.createElement('param');param.setAttribute('name',name);param.setAttribute('value',value);node.appendChild(param);};x3dom.X3DCanvas.prototype._fileExists=function(url){var xhr=new XMLHttpRequest();try{xhr.open("HEAD",url,false);xhr.send(null);return(xhr.status!=404);}catch(e){return true;}};x3dom.X3DCanvas.prototype._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];};x3dom.X3DCanvas.prototype._createInitFailedDiv=function(x3dElem){var div=document.createElement('div');div.setAttribute("id","x3dom-create-init-failed");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="Helvetica";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 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);var altImg=x3dElem.getAttribute("altImg")||null;if(altImg){var altImgObj=new Image();altImgObj.src=altImg;div.style.backgroundImage="url("+altImg+")";div.style.backgroundRepeat="no-repeat";div.style.backgroundPosition="50% 50%";}
+x3dElem.appendChild(div);x3dom.debug.logError("Your Browser does not support X3DOM!");};x3dom.X3DCanvas.prototype._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=this.x3dElem.getAttribute("id");if(id!==null){id="x3dom-"+id+"-object";}else{var index=new Date().getTime();id="x3dom-"+index+"-object";}
+var swf_path=this.x3dElem.getAttribute("swfpath");if(swf_path===null){swf_path="x3dom.swf";}
+if(!this._fileExists(swf_path)){var version;if(x3dom.versionInfo===undefined||x3dom.versionInfo.version.indexOf('dev')!=-1)
+{version="dev";}
+else{var modification=test.substr(test.length-1);if(modification>0){version=x3dom.versionInfo.version;}else{version=x3dom.versionInfo.version.substr(3);}}
+swf_path="http://www.x3dom.org/download/"+version+"/x3dom.swf";x3dom.debug.logWarning("Can't find local x3dom.swf ("+version+"). X3DOM now using the online version from x3dom.org."+"The online version needs a <a href='http://examples.x3dom.org/crossdomain.xml'>crossdomain.xml</a> "+"file in the root directory of your domain to access textures");}
+var width=this.x3dElem.getAttribute("width");var idx=-1;if(width==null){width=550;}else{idx=width.indexOf("px");if(idx!=-1){width=width.substr(0,idx);}}
+var height=this.x3dElem.getAttribute("height");if(height==null){height=400;}else{idx=height.indexOf("px");if(idx!=-1){height=height.substr(0,idx);}}
+var renderType=this.x3dElem.getAttribute("flashrenderer");if(renderType==null){this.flash_renderType="forward";}else{this.flash_renderType="deferred";}
+var obj=document.createElement('object');obj.setAttribute('width','100%');obj.setAttribute('height','100%');obj.setAttribute('id',id);if(!document.doctype||document.doctype&&document.doctype.publicId.search(/DTD XHTML/i)!=-1){x3dom.debug.logWarning("Flash backend doesn't like XHTML, please use HTML5!");obj.setAttribute('style','width:'+width+'px; height:'+height+'px;');}else{if(x3dElem.getAttribute('style')==null){x3dElem.setAttribute('style','width:'+width+'px; height:'+height+'px;');}}
+this.appendParam(obj,'menu','false');this.appendParam(obj,'quality','high');this.appendParam(obj,'wmode','direct');this.appendParam(obj,'allowScriptAccess','always');this.appendParam(obj,'flashvars','canvasIdx='+this._canvasIdx+'&renderType='+this.flash_renderType);this.appendParam(obj,'movie',swf_path);if(navigator.appName=="Microsoft Internet Explorer"){x3dElem.appendChild(obj);obj.setAttribute('classid','clsid:d27cdb6e-ae6d-11cf-96b8-444553540000');}else{obj.setAttribute('type','application/x-shockwave-flash');obj.setAttribute('data',swf_path);x3dElem.appendChild(obj);}
+return obj;}};x3dom.X3DCanvas.prototype._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","onMozTouchDown","onMozTouchMove","onMozTouchUp","ondragstart","ondrop","ondragover"];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);x3dElem.removeAttribute(evtName);}}
+var userProp=x3dElem.getAttribute("draggable");if(userProp){x3dom.debug.logInfo("draggable="+userProp);canvas.setAttribute("draggable",userProp);}
+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,h;if((w=x3dElem.getAttribute("width"))!==null){if(w.indexOf("%")>=0){x3dom.debug.logWarning("The width attribute is to be specified in pixels not in percent.");}
+canvas.style.width=w;canvas.setAttribute("width",w);}
+if((h=x3dElem.getAttribute("height"))!==null){if(h.indexOf("%")>=0){x3dom.debug.logWarning("The height attribute is to be specified in pixels not in percent.");}
+canvas.style.height=h;canvas.setAttribute("height",h);}
+canvas.setAttribute("tabindex","0");return canvas;};x3dom.X3DCanvas.prototype._watchForResize=function(){var new_dim=[parseInt(x3dom.getStyle(this.canvas,"width")),parseInt(x3dom.getStyle(this.canvas,"height"))];if((this._current_dim[0]!=new_dim[0])||(this._current_dim[1]!=new_dim[1])){this._current_dim=new_dim;this.x3dElem.setAttribute("width",new_dim[0]+"px");this.x3dElem.setAttribute("height",new_dim[1]+"px");}};x3dom.X3DCanvas.prototype._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);progressDiv.oncontextmenu=progressDiv.onmousedown=function(evt){evt.preventDefault();evt.stopPropagation();return false;};return progressDiv;};x3dom.X3DCanvas.prototype.mousePosition=function(evt)
+{var x=0,y=0;if("getBoundingClientRect"in document.documentElement){var elem=evt.target.offsetParent;var box=elem.getBoundingClientRect();var scrollLeft=window.pageXOffset||document.documentElement.scrollLeft;var scrollTop=window.pageYOffset||document.documentElement.scrollTop;var compStyle=document.defaultView.getComputedStyle(elem,null);var paddingLeft=parseFloat(compStyle.getPropertyValue('padding-left'));var borderLeftWidth=parseFloat(compStyle.getPropertyValue('border-left-width'));var paddingTop=parseFloat(compStyle.getPropertyValue('padding-top'));var borderTopWidth=parseFloat(compStyle.getPropertyValue('border-top-width'));x=Math.round(evt.pageX-(box.left+paddingLeft+borderLeftWidth+scrollLeft));y=Math.round(evt.pageY-(box.top+paddingTop+borderTopWidth+scrollTop));}
+else{x3dom.debug.logError('NO getBoundingClientRect');}
+return new x3dom.fields.SFVec2f(x,y);};x3dom.X3DCanvas.prototype.tick=function()
+{var runtime=this.x3dElem.runtime;var d=new Date().getTime();var diff=d-this.lastTimeFPSWasTaken;var fps=1000.0/(d-this.fps_t0);this.fps_t0=d;this.doc.advanceTime(d/1000.0);var animD=new Date().getTime()-d;if(this.doc.needRender){if(diff>=1000){runtime.fps=this.framesSinceLastTime/(diff/1000.0);runtime.addMeasurement('FPS',runtime.fps);this.framesSinceLastTime=0;this.lastTimeFPSWasTaken=d;}
+this.framesSinceLastTime++;runtime.addMeasurement('ANIM',animD);if(runtime.isReady==false){runtime.ready();runtime.isReady=true;}
+runtime.enterFrame();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.doc._scene._vf.doPickPass)
+runtime.removeMeasurement('PICKING');}
+runtime.exitFrame();}
+if(this.progressDiv){if(this.doc.downloadCount>0){runtime.addInfo("#LOADS:",this.doc.downloadCount);}else{runtime.removeInfo("#LOADS:");}
+if(this.doc.properties.getProperty("showProgress")!=='false'){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';}}}else{this.progressDiv.style.display='none';}}};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(){if(x3dCanvas.hasRuntime){(function mainloop(){if(x3dCanvas.doc&&x3dCanvas.x3dElem.runtime){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.config={};this.isReady=false;this.fps=0;this.states={measurements:[],infos:[]};};x3dom.Runtime.prototype.addMeasurement=function(title,value){this.states.measurements[title]=value;};x3dom.Runtime.prototype.removeMeasurement=function(title){if(this.states.measurements[title]){delete this.states.measurements[title];}};x3dom.Runtime.prototype.addInfo=function(title,value){this.states.infos[title]=value;};x3dom.Runtime.prototype.removeInfo=function(title){delete this.states.infos[title];};x3dom.Runtime.prototype.initialize=function(doc,canvas){this.doc=doc;this.canvas=canvas;this.config={};this.isReady=false;this.fps=0;};x3dom.Runtime.prototype.noBackendFound=function(){x3dom.debug.logInfo('No backend found. Unable to render.');};x3dom.Runtime.prototype.ready=function(){x3dom.debug.logInfo('System ready.');};x3dom.Runtime.prototype.enterFrame=function(){};x3dom.Runtime.prototype.exitFrame=function(){};x3dom.Runtime.prototype.triggerRedraw=function(){this.canvas.doc.needRender=true;};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.viewMatrix=function(){return this.canvas.doc._viewarea.getViewMatrix();};x3dom.Runtime.prototype.projectionMatrix=function(){return this.canvas.doc._viewarea.getProjectionMatrix();};x3dom.Runtime.prototype.getWorldToCameraCoordinatesMatrix=function(){return this.canvas.doc._viewarea.getWCtoCCMatrix();};x3dom.Runtime.prototype.getCameraToWorldCoordinatesMatrix=function(){return this.canvas.doc._viewarea.getCCtoWCMatrix();};x3dom.Runtime.prototype.getViewingRay=function(x,y){return this.canvas.doc._viewarea.calcViewRay(x,y);};x3dom.Runtime.prototype.shootRay=function(x,y){var doc=this.canvas.doc;var info=doc._viewarea._pickingInfo;doc.onPick(this.canvas.gl,x,y);return{pickPosition:info.pickObj?info.pickPos:null,pickNormal:info.pickObj?info.pickNorm:null,pickObject:info.pickObj?info.pickObj._xmlNode:null};};x3dom.Runtime.prototype.getWidth=function(){return this.canvas.doc._viewarea._width;};x3dom.Runtime.prototype.getHeight=function(){return this.canvas.doc._viewarea._height;};x3dom.Runtime.prototype.mousePosition=function(event){var pos=this.canvas.mousePosition(event);return[pos.x,pos.y];};x3dom.Runtime.prototype.calcCanvasPos=function(wx,wy,wz){var pnt=new x3dom.fields.SFVec3f(wx,wy,wz);var mat=this.canvas.doc._viewarea.getWCtoCCMatrix();var pos=mat.multFullMatrixPnt(pnt);var w=this.canvas.doc._viewarea._width;var h=this.canvas.doc._viewarea._height;var x=Math.round((pos.x+1)*(w-1)/2);var y=Math.round((h-1)*(1-pos.y)/2);return[x,y];};x3dom.Runtime.prototype.calcPagePos=function(wx,wy,wz){var elem=this.canvas.canvas.offsetParent;if(!elem){x3dom.debug.logError("Can't calc page pos without offsetParent.");return[0,0];}
+var canvasPos=elem.getBoundingClientRect();var mousePos=this.calcCanvasPos(wx,wy,wz);var scrollLeft=window.pageXOffset||document.body.scrollLeft;var scrollTop=window.pageYOffset||document.body.scrollTop;var compStyle=document.defaultView.getComputedStyle(elem,null);var paddingLeft=parseFloat(compStyle.getPropertyValue('padding-left'));var borderLeftWidth=parseFloat(compStyle.getPropertyValue('border-left-width'));var paddingTop=parseFloat(compStyle.getPropertyValue('padding-top'));var borderTopWidth=parseFloat(compStyle.getPropertyValue('border-top-width'));var x=canvasPos.left+paddingLeft+borderLeftWidth+scrollLeft+mousePos[0];var y=canvasPos.top+paddingTop+borderTopWidth+scrollTop+mousePos[1];return[x,y];};x3dom.Runtime.prototype.calcClientPos=function(wx,wy,wz){var elem=this.canvas.canvas.offsetParent;if(!elem){x3dom.debug.logError("Can't calc client pos without offsetParent.");return[0,0];}
+var canvasPos=elem.getBoundingClientRect();var mousePos=this.calcCanvasPos(wx,wy,wz);var compStyle=document.defaultView.getComputedStyle(elem,null);var paddingLeft=parseFloat(compStyle.getPropertyValue('padding-left'));var borderLeftWidth=parseFloat(compStyle.getPropertyValue('border-left-width'));var paddingTop=parseFloat(compStyle.getPropertyValue('padding-top'));var borderTopWidth=parseFloat(compStyle.getPropertyValue('border-top-width'));var x=canvasPos.left+paddingLeft+borderLeftWidth+mousePos[0];var y=canvasPos.top+paddingTop+borderTopWidth+mousePos[1];return[x,y];};x3dom.Runtime.prototype.getScreenshot=function(){var url="";var backend=this.canvas.backend;var canvas=this.canvas.canvas;if(canvas){if(backend=="flash"){url=canvas.getScreenshot();}
+else{var canvas2d=document.createElement("canvas");canvas2d.width=canvas.width;canvas2d.height=canvas.height;var ctx=canvas2d.getContext("2d");ctx.drawImage(canvas,0,0,canvas.width,canvas.height);ctx.scale(1,-1);ctx.translate(0,-canvas.height);url=canvas2d.toDataURL();}}
+return url;};x3dom.Runtime.prototype.getCanvas=function(){return this.canvas.canvas;};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.fitAll=function(updateCenterOfRotation)
+{if(updateCenterOfRotation===undefined){updateCenterOfRotation=true;}
+var scene=this.canvas.doc._scene;scene.updateVolume();this.canvas.doc._viewarea.fit(scene._lastMin,scene._lastMax,updateCenterOfRotation);};x3dom.Runtime.prototype.fitObject=function(obj,updateCenterOfRotation)
+{if(obj&&obj._x3domNode)
+{if(updateCenterOfRotation===undefined){updateCenterOfRotation=true;}
+var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var vol=obj._x3domNode.getVolume();vol.getBounds(min,max);var mat=obj._x3domNode.getCurrentTransform();min=mat.multMatrixPnt(min);max=mat.multMatrixPnt(max);if(x3dom.isa(obj._x3domNode,x3dom.nodeTypes.X3DTransformNode))
+{var invMat=obj._x3domNode._trafo.inverse();min=invMat.multMatrixPnt(min);max=invMat.multMatrixPnt(max);}
+this.canvas.doc._viewarea.fit(min,max,updateCenterOfRotation);}};x3dom.Runtime.prototype.showAll=function(axis){this.canvas.doc._viewarea.showAll(axis);};x3dom.Runtime.prototype.showObject=function(obj)
+{if(obj&&obj._x3domNode)
+{var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var vol=obj._x3domNode.getVolume();vol.getBounds(min,max);var mat=obj._x3domNode.getCurrentTransform();min=mat.multMatrixPnt(min);max=mat.multMatrixPnt(max);var viewarea=this.canvas.doc._viewarea;var focalLen=(viewarea._width<viewarea._height)?viewarea._width:viewarea._height;var n0=new x3dom.fields.SFVec3f(0,0,1);var viewpoint=this.canvas.doc._scene.getViewpoint();var fov=viewpoint.getFieldOfView()/2.0;var ta=Math.tan(fov);if(Math.abs(ta)>x3dom.fields.Eps){focalLen/=ta;}
+var w=viewarea._width-1;var h=viewarea._height-1;var frame=0.25;var minScreenPos=new x3dom.fields.SFVec2f(frame*w,frame*h);frame=0.75;var maxScreenPos=new x3dom.fields.SFVec2f(frame*w,frame*h);var dia2=max.subtract(min).multiply(0.5);var rw=dia2.length();var pc=min.add(dia2);var vc=maxScreenPos.subtract(minScreenPos).multiply(0.5);var rs=1.5*vc.length();vc=vc.add(minScreenPos);var dist=1.0;if(rs>x3dom.fields.Eps){dist=(rw/rs)*Math.sqrt(vc.x*vc.x+vc.y*vc.y+focalLen*focalLen);}
+n0=mat.multMatrixVec(n0).normalize();n0=n0.multiply(dist);var p0=pc.add(n0);var qDir=x3dom.fields.Quaternion.rotateFromTo(new x3dom.fields.SFVec3f(0,0,1),n0);var R=qDir.toMatrix();var T=x3dom.fields.SFMatrix4f.translation(p0.negate());var M=x3dom.fields.SFMatrix4f.translation(p0);M=M.mult(R).mult(T).mult(M);var viewmat=M.inverse();viewarea.animateTo(viewmat,viewpoint);}};x3dom.Runtime.prototype.getCenter=function(domNode){if(domNode&&domNode._x3domNode&&(this.isA(domNode,"X3DShapeNode")||this.isA(domNode,"X3DGeometryNode")))
+{return domNode._x3domNode.getCenter();}
+return null;};x3dom.Runtime.prototype.getCurrentTransform=function(domNode){if(domNode&&domNode._x3domNode)
+{return domNode._x3domNode.getCurrentTransform();}
+return null;};x3dom.Runtime.prototype.getBBox=function(domNode){if(domNode&&domNode._x3domNode&&this.isA(domNode,"X3DBoundedObject"))
+{var vol=domNode._x3domNode.getVolume();return{min:x3dom.fields.SFVec3f.copy(vol.min),max:x3dom.fields.SFVec3f.copy(vol.max)}}
+return null;};x3dom.Runtime.prototype.getSceneBBox=function(){var scene=this.canvas.doc._scene;scene.updateVolume();return{min:x3dom.fields.SFVec3f.copy(scene._lastMin),max:x3dom.fields.SFVec3f.copy(scene._lastMax)}};x3dom.Runtime.prototype.debug=function(show){var doc=this.canvas.doc;if(doc._viewarea._visDbgBuf===undefined)
+doc._viewarea._visDbgBuf=(doc._x3dElem.getAttribute("showLog")==='true');if(arguments.length>0){if(show===true){doc._viewarea._visDbgBuf=true;x3dom.debug.logContainer.style.display="block";}
+else{doc._viewarea._visDbgBuf=false;x3dom.debug.logContainer.style.display="none";}}
+else{doc._viewarea._visDbgBuf=!doc._viewarea._visDbgBuf;x3dom.debug.logContainer.style.display=(doc._viewarea._visDbgBuf==true)?"block":"none";}
+doc.needRender=true;return doc._viewarea._visDbgBuf;};x3dom.Runtime.prototype.navigationType=function(){return this.canvas.doc._scene.getNavigationInfo().getType();};x3dom.Runtime.prototype.noNav=function(){this.canvas.doc._scene.getNavigationInfo().setType("none");};x3dom.Runtime.prototype.examine=function(){this.canvas.doc._scene.getNavigationInfo().setType("examine");};x3dom.Runtime.prototype.turnTable=function(){this.canvas.doc._scene.getNavigationInfo().setType("turntable");};x3dom.Runtime.prototype.fly=function(){this.canvas.doc._scene.getNavigationInfo().setType("fly");};x3dom.Runtime.prototype.freeFly=function(){this.canvas.doc._scene.getNavigationInfo().setType("freefly");};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.helicopter=function(){this.canvas.doc._scene.getNavigationInfo().setType("helicopter");};x3dom.Runtime.prototype.resetExamin=function(){var viewarea=this.canvas.doc._viewarea;viewarea._rotMat=x3dom.fields.SFMatrix4f.identity();viewarea._transMat=x3dom.fields.SFMatrix4f.identity();viewarea._movement=new x3dom.fields.SFVec3f(0,0,0);viewarea._needNavigationMatrixUpdate=true;this.canvas.doc.needRender=true;};x3dom.Runtime.prototype.togglePoints=function(lines){var doc=this.canvas.doc;var mod=(lines===true)?3:2;doc._viewarea._points=++doc._viewarea._points%mod;doc.needRender=true;return doc._viewarea._points;};x3dom.Runtime.prototype.pickRect=function(x1,y1,x2,y2){return this.canvas.doc.onPickRect(this.canvas.gl,x1,y1,x2,y2);};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){type=type.toLowerCase();switch(type){case'idbuf':type='idBuf';break;case'idbuf24':type='idBuf24';break;case'idbufid':type='idBufId';break;case'texcoord':type='texCoord';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 true;}
+return false;};x3dom.Runtime.prototype.speed=function(newSpeed){var navi=this.canvas.doc._scene.getNavigationInfo();if(newSpeed){navi._vf.speed=newSpeed;x3dom.debug.logInfo("Changed navigation speed to "+navi._vf.speed);}
+return navi._vf.speed;};x3dom.Runtime.prototype.statistics=function(mode){var states=this.canvas.stateViewer;if(states){this.canvas.doc.needRender=true;if(mode===true){states.display(mode);return true;}
+else if(mode===false){states.display(mode);return false;}
+else{states.display(!states.active);return states.active;}}
+return false;};x3dom.Runtime.prototype.processIndicator=function(mode){var processDiv=this.canvas.progressDiv;if(processDiv){if(mode===true){processDiv.style.display='inline';return true;}
+else if(mode===false){processDiv.style.display='none';return false;}
+return processDiv.style.display!='none'}
+return false;};x3dom.Runtime.prototype.properties=function(){return this.canvas.doc.properties;};x3dom.Runtime.prototype.backendName=function(){return this.canvas.backend;};x3dom.Runtime.prototype.getFPS=function(){return this.fps;};x3dom.Runtime.prototype.isA=function(domNode,nodeType){var inherits=false;if(nodeType&&domNode&&domNode._x3domNode){if(nodeType===""){nodeType="X3DNode";}
+inherits=x3dom.isa(domNode._x3domNode,x3dom.nodeTypesLC[nodeType.toLowerCase()]);}
+return inherits;};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 loadX3DOM(){"use strict";var onload=function(){var i,j;var x3ds_unfiltered=document.getElementsByTagName('X3D');var x3ds=[];for(i=0;i<x3ds_unfiltered.length;i++){if(x3ds_unfiltered[i].hasRuntime===undefined)
+x3ds.push(x3ds_unfiltered[i]);}
+var params;var settings=new x3dom.Properties();var validParams=array_to_object(['showLog','showStat','showProgress','PrimitiveQuality','components','loadpath','disableDoubleClick','backend','altImg','flashrenderer','swfpath','runtimeEnabled','keysEnabled','showTouchpoints','disableTouch','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(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);}
+x3ds=Array.map(x3ds,function(n){n.hasRuntime=true;return n;});var w3sg=document.getElementsByTagName('webSG');for(i=0;i<w3sg.length;i++){w3sg[i].hasRuntime=false;x3ds.push(w3sg[i]);}
+if(x3dom.versionInfo!==undefined){x3dom.debug.logInfo("X3DOM version "+x3dom.versionInfo.version+", "+"Revison <a href='https://github.com/x3dom/x3dom/tree/"+x3dom.versionInfo.revision+"'>"
++x3dom.versionInfo.revision+"</a>, "+"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;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,x3dom.canvases.length);x3dom.canvases.push(x3dcanvas);if(x3dcanvas.gl===null){altDiv=document.createElement("div");altDiv.setAttribute("class","x3dom-nox3d");altDiv.setAttribute("id","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.stateViewer){x3d_element.removeChild(x3dcanvas.stateViewer.viewer);}
+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;}
+if(x3dcanvas.backend==''){x3dom.runtime.noBackendFound();}
+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);}
+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(){if(x3dom.canvases){for(var i=0;i<x3dom.canvases.length;i++){x3dom.canvases[i].doc.shutdown(x3dom.canvases[i].gl);}
+x3dom.canvases=[];}};x3dom.reload=function(){onload();};if(navigator.userAgent.indexOf("Chrome")!=-1){document.__getElementsByTagName=document.getElementsByTagName;document.getElementsByTagName=function(tag){var obj=[];var elems=this.__getElementsByTagName("*");if(tag=="*"){obj=elems;}else{tag=tag.toUpperCase();for(var i=0;i<elems.length;i++){var tagName=elems[i].tagName.toUpperCase();if(tagName===tag){obj.push(elems[i]);}}}
+return obj;};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{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;};}
+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);}
+if(document.readyState==="complete"){window.setTimeout(function(){onload();},20);}})();x3dom.Cache=function(){this.textures=[];this.shaders=[];};x3dom.Cache.prototype.getTexture2D=function(gl,doc,url,bgnd,withCredentials,scale,genMipMaps){var textureIdentifier=url;if(this.textures[textureIdentifier]===undefined){this.textures[textureIdentifier]=x3dom.Utils.createTexture2D(gl,doc,url,bgnd,withCredentials,scale,genMipMaps);}
+return this.textures[textureIdentifier];};x3dom.Cache.prototype.getTextureCube=function(gl,doc,url,bgnd,withCredentials,scale,genMipMaps){var textureIdentifier="";for(var i=0;i<url.length;++i){textureIdentifier+=url[i]+"|";}
+if(this.textures[textureIdentifier]===undefined){this.textures[textureIdentifier]=x3dom.Utils.createTextureCube(gl,doc,url,bgnd,withCredentials,scale,genMipMaps);}
+return this.textures[textureIdentifier];};x3dom.Cache.prototype.getShader=function(gl,shaderIdentifier){var program=null;if(this.shaders[shaderIdentifier]===undefined){switch(shaderIdentifier){case x3dom.shader.PICKING:program=new x3dom.shader.PickingShader(gl);break;case x3dom.shader.PICKING_24:program=new x3dom.shader.Picking24Shader(gl);break;case x3dom.shader.PICKING_ID:program=new x3dom.shader.PickingIdShader(gl);break;case x3dom.shader.PICKING_COLOR:program=new x3dom.shader.PickingColorShader(gl);break;case x3dom.shader.PICKING_TEXCOORD:program=new x3dom.shader.PickingTexcoordShader(gl);break;case x3dom.shader.FRONTGROUND_TEXTURE:program=new x3dom.shader.FrontgroundTextureShader(gl);break;case x3dom.shader.BACKGROUND_TEXTURE:program=new x3dom.shader.BackgroundTextureShader(gl);break;case x3dom.shader.BACKGROUND_SKYTEXTURE:program=new x3dom.shader.BackgroundSkyTextureShader(gl);break;case x3dom.shader.BACKGROUND_CUBETEXTURE:program=new x3dom.shader.BackgroundCubeTextureShader(gl);break;case x3dom.shader.SHADOW:program=new x3dom.shader.ShadowShader(gl);break;case x3dom.shader.BLUR:program=new x3dom.shader.BlurShader(gl);break;case x3dom.shader.DEPTH:break;case x3dom.shader.NORMAL:program=new x3dom.shader.NormalShader(gl);break;case x3dom.shader.TEXTURE_REFINEMENT:program=new x3dom.shader.TextureRefinementShader(gl);break;default:break;}
+if(program)
+this.shaders[shaderIdentifier]=x3dom.Utils.wrapProgram(gl,program,shaderIdentifier);else
+x3dom.debug.logError("Couldn't create shader: "+shaderIdentifier);}
+return this.shaders[shaderIdentifier];};x3dom.Cache.prototype.getDynamicShader=function(gl,viewarea,shape){var properties=x3dom.Utils.generateProperties(viewarea,shape);var shaderID=properties.id;if(this.shaders[shaderID]===undefined){var program;if(properties.CSHADER!=-1){program=new x3dom.shader.ComposedShader(gl,shape);}else{program=(x3dom.caps.MOBILE&&!properties.CSSHADER)?new x3dom.shader.DynamicMobileShader(gl,properties):new x3dom.shader.DynamicShader(gl,properties);}
+this.shaders[shaderID]=x3dom.Utils.wrapProgram(gl,program,shaderID);}
+return this.shaders[shaderID];};x3dom.Cache.prototype.getShaderByProperties=function(gl,shape,properties){var shaderID=properties.id;if(this.shaders[shaderID]===undefined)
+{var program;if(properties.CSHADER!=-1){program=new x3dom.shader.ComposedShader(gl,shape);}else{program=(x3dom.caps.MOBILE&&!properties.CSSHADER)?new x3dom.shader.DynamicMobileShader(gl,properties):new x3dom.shader.DynamicShader(gl,properties);}
+this.shaders[shaderID]=x3dom.Utils.wrapProgram(gl,program,shaderID);}
+return this.shaders[shaderID];};x3dom.Cache.prototype.getShadowRenderingShader=function(gl,shadowedLights){var ID="shadow";for(var i=0;i<shadowedLights.length;i++){if(x3dom.isa(shadowedLights[i],x3dom.nodeTypes.SpotLight))
+ID+="S";else if(x3dom.isa(shadowedLights[i],x3dom.nodeTypes.PointLight))
+ID+="P";else
+ID+="D";}
+if(this.shaders[ID]===undefined){var program=new x3dom.shader.ShadowRenderingShader(gl,shadowedLights);this.shaders[ID]=x3dom.Utils.wrapProgram(gl,program,ID);}
+return this.shaders[ID];};x3dom.Cache.prototype.Release=function(gl){for(var texture in this.textures){gl.deleteTexture(this.textures[texture]);}
+this.textures=[];for(var shaderId in this.shaders){var shader=this.shaders[shaderId];var glShaders=gl.getAttachedShaders(shader.program);for(var i=0;i<glShaders.length;++i){gl.detachShader(shader.program,glShaders[i]);gl.deleteShader(glShaders[i]);}
+gl.deleteProgram(shader.program)}
+this.shaders=[];};function startDashVideo(recurl,texturediv){var vars=function(){var vars={};var parts=window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(m,key,value){vars[key]=value;});return vars;},url=recurl,video,context,player;if(vars&&vars.hasOwnProperty("url")){url=vars.url;}
+video=document.querySelector(texturediv);context=new Dash.di.DashContext();player=new MediaPlayer(context);player.startup();player.attachView(video);player.setAutoPlay(false);player.attachSource(url);}
+x3dom.Texture=function(gl,doc,cache,node){this.gl=gl;this.doc=doc;this.cache=cache;this.node=node;this.samplerName="diffuseMap";this.type=gl.TEXTURE_2D;this.format=gl.RGBA;this.magFilter=gl.LINEAR;this.minFilter=gl.LINEAR;this.wrapS=gl.REPEAT;this.wrapT=gl.REPEAT;this.genMipMaps=false;this.texture=null;this.ready=false;this.dashtexture=false;var tex=this.node;var suffix="mpd";if(x3dom.isa(tex,x3dom.nodeTypes.MovieTexture)){if(tex._vf.url[0].indexOf(suffix,tex._vf.url[0].length-suffix.length)!==-1){this.dashtexture=true;var js=document.getElementById("AdditionalDashVideoScript");if(!js){js=document.createElement("script");js.setAttribute("type","text/javascript");js.setAttribute("src",x3dom.Texture.dashVideoScriptFile);js.setAttribute("id","AdditionalDashVideoScript");js.onload=function(){var texObj;while((texObj=x3dom.Texture.loadDashVideos.pop())){x3dom.Texture.textNum++;texObj.update();}
+js.ready=true;};document.getElementsByTagName('head')[0].appendChild(js);}
+if(js.ready===true){x3dom.Texture.textNum++;this.update();}
+else{x3dom.Texture.loadDashVideos.push(this);}}}
+if(!this.dashtexture){this.update();}};x3dom.Texture.dashVideoScriptFile="dash.all.js";x3dom.Texture.loadDashVideos=[];x3dom.Texture.textNum=0;x3dom.Texture.clampFontSize=false;x3dom.Texture.prototype.update=function()
+{if(x3dom.isa(this.node,x3dom.nodeTypes.Text))
+{this.updateText();}
+else
+{this.updateTexture();}};x3dom.Texture.prototype.updateTexture=function()
+{var gl=this.gl;var doc=this.doc;var tex=this.node;this.samplerName=tex._type;if(x3dom.isa(tex,x3dom.nodeTypes.X3DEnvironmentTextureNode)){this.type=gl.TEXTURE_CUBE_MAP;}else{this.type=gl.TEXTURE_2D;}
+if(x3dom.isa(tex,x3dom.nodeTypes.PixelTexture)){switch(tex._vf.image.comp)
+{case 1:this.format=gl.LUMINANCE;break;case 2:this.format=gl.LUMINANCE_ALPHA;break;case 3:this.format=gl.RGB;break;case 4:this.format=gl.RGBA;break;}}else{this.format=gl.RGBA;}
+if(tex._cf.textureProperties.node!==null){var texProp=tex._cf.textureProperties.node;this.wrapS=x3dom.Utils.boundaryModesDic(gl,texProp._vf.boundaryModeS);this.wrapT=x3dom.Utils.boundaryModesDic(gl,texProp._vf.boundaryModeT);this.minFilter=x3dom.Utils.minFilterDic(gl,texProp._vf.minificationFilter);this.magFilter=x3dom.Utils.magFilterDic(gl,texProp._vf.magnificationFilter);if(texProp._vf.generateMipMaps===true){this.genMipMaps=true;if(this.minFilter==gl.NEAREST){this.minFilter=gl.NEAREST_MIPMAP_NEAREST;}else if(this.minFilter==gl.LINEAR){this.minFilter=gl.LINEAR_MIPMAP_LINEAR;}
+if(this.texture&&(this.texture.ready||this.texture.textureCubeReady)){gl.bindTexture(this.type,this.texture);gl.generateMipmap(this.type);gl.bindTexture(this.type,null);}}else{this.genMipMaps=false;if((this.minFilter==gl.LINEAR_MIPMAP_LINEAR)||(this.minFilter==gl.LINEAR_MIPMAP_NEAREST)){this.minFilter=gl.LINEAR;}else if((this.minFilter==gl.NEAREST_MIPMAP_LINEAR)||(this.minFilter==gl.NEAREST_MIPMAP_NEAREST)){this.minFilter=gl.NEAREST;}}}else{if(tex._vf.repeatS==false){this.wrapS=gl.CLAMP_TO_EDGE;}
+else
+{this.wrapS=gl.REPEAT;}
+if(tex._vf.repeatT==false){this.wrapT=gl.CLAMP_TO_EDGE;}
+else
+{this.wrapT=gl.REPEAT;}
+if(this.samplerName=="displacementMap"||this.samplerName=="multiDiffuseAlphaMap"||this.samplerName=="multiVisibilityMap")
+{this.wrapS=gl.CLAMP_TO_EDGE;this.wrapT=gl.CLAMP_TO_EDGE;this.minFilter=gl.NEAREST;this.magFilter=gl.NEAREST;}}
+var childTex=(tex._video&&tex._needPerFrameUpdate===true);if(tex._isCanvas&&tex._canvas)
+{if(this.texture==null){this.texture=gl.createTexture()}
+this.texture.width=tex._canvas.width;this.texture.height=tex._canvas.height;this.texture.ready=true;gl.bindTexture(this.type,this.texture);gl.texImage2D(this.type,0,this.format,this.format,gl.UNSIGNED_BYTE,tex._canvas);if(this.genMipMaps){gl.generateMipmap(this.type);}
+gl.bindTexture(this.type,null);}
+else if(x3dom.isa(tex,x3dom.nodeTypes.RenderedTexture))
+{if(tex._webgl&&tex._webgl.fbo){this.texture=tex._webgl.fbo.tex;}
+else{this.texture=null;x3dom.debug.logError("Try updating RenderedTexture without FBO initialized!");}
+if(this.texture){this.texture.ready=true;}}
+else if(x3dom.isa(tex,x3dom.nodeTypes.PixelTexture))
+{if(this.texture==null){this.texture=gl.createTexture()}
+this.texture.width=tex._vf.image.width;this.texture.height=tex._vf.image.height;this.texture.ready=true;var pixelArr=tex._vf.image.toGL();var pixelArrfont_size=tex._vf.image.width*tex._vf.image.height*tex._vf.image.comp;while(pixelArr.length<pixelArrfont_size){pixelArr.push(0);}
+var pixels=new Uint8Array(pixelArr);gl.bindTexture(this.type,this.texture);gl.pixelStorei(gl.UNPACK_ALIGNMENT,1);gl.texImage2D(this.type,0,this.format,tex._vf.image.width,tex._vf.image.height,0,this.format,gl.UNSIGNED_BYTE,pixels);if(this.genMipMaps){gl.generateMipmap(this.type);}
+gl.bindTexture(this.type,null);}
+else if(x3dom.isa(tex,x3dom.nodeTypes.MovieTexture)||childTex)
+{var that=this;var p=document.getElementsByTagName('body')[0];if(this.texture==null){this.texture=gl.createTexture();}
+if(this.dashtexture){var element_vid=document.createElement('div');element_vid.setAttribute('class','dash-video-player'+x3dom.Texture.textNum);tex._video=document.createElement('video');tex._video.setAttribute('preload','auto');tex._video.setAttribute('muted','muted');var scriptToRun=document.createElement('script');scriptToRun.setAttribute('type','text/javascript');scriptToRun.innerHTML='startDashVideo("'+tex._vf.url[0]+'",".dash-video-player'+x3dom.Texture.textNum+' video")';element_vid.appendChild(scriptToRun);element_vid.appendChild(tex._video);p.appendChild(element_vid);tex._video.style.visibility="hidden";tex._video.style.display="none";}
+else{if(!childTex){tex._video=document.createElement('video');tex._video.setAttribute('preload','auto');tex._video.setAttribute('muted','muted');p.appendChild(tex._video);tex._video.style.visibility="hidden";tex._video.style.display="none";}
+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()
+{gl.bindTexture(that.type,that.texture);gl.texImage2D(that.type,0,that.format,that.format,gl.UNSIGNED_BYTE,tex._video);if(that.genMipMaps){gl.generateMipmap(that.type);}
+gl.bindTexture(that.type,null);that.texture.ready=true;doc.needRender=true;};var startVideo=function()
+{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))
+{this.texture=this.cache.getTextureCube(gl,doc,tex.getTexUrl(),false,tex._vf.withCredentials,tex._vf.scale,this.genMipMaps);}
+else
+{this.texture=this.cache.getTexture2D(gl,doc,tex._nameSpace.getURL(tex._vf.url[0]),false,tex._vf.withCredentials,tex._vf.scale,this.genMipMaps);}};x3dom.Texture.prototype.updateText=function()
+{var gl=this.gl;this.wrapS=gl.CLAMP_TO_EDGE;this.wrapT=gl.CLAMP_TO_EDGE;var fontStyleNode=this.node._cf.fontStyle.node;var font_family='serif';var font_style='normal';var font_justify='left';var font_size=1.0;var font_spacing=1.0;var font_horizontal=true;var font_language="";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';}
+var leftToRight=fontStyleNode._vf.leftToRight?'ltr':'rtl';var topToBottom=fontStyleNode._vf.topToBottom;font_justify=fontStyleNode._vf.justify[0].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';break;}
+font_size=fontStyleNode._vf.size;font_spacing=fontStyleNode._vf.spacing;font_horizontal=fontStyleNode._vf.horizontal;font_language=fontStyleNode._vf.language;if(font_size<0.1)font_size=0.1;if(x3dom.Texture.clampFontSize&&font_size>2.3)
+{font_size=2.3;}}
+var textX,textY;var paragraph=this.node._vf.string;var text_canvas=document.createElement('canvas');text_canvas.dir=leftToRight;var textHeight=font_size*42;var textAlignment=font_justify;document.body.appendChild(text_canvas);var text_ctx=text_canvas.getContext('2d');text_ctx.font=font_style+" "+textHeight+"px "+font_family;var maxWidth=text_ctx.measureText(paragraph[0]).width;var i;for(i=1;i<paragraph.length;i++){if(text_ctx.measureText(paragraph[i]).width>maxWidth)
+maxWidth=text_ctx.measureText(paragraph[i]).width;}
+var canvas_scale=1.1;text_canvas.width=maxWidth*canvas_scale;text_canvas.height=textHeight*paragraph.length*canvas_scale;switch(textAlignment){case"left":textX=0;break;case"center":textX=text_canvas.width/2;break;case"right":textX=text_canvas.width;break;}
+var txtW=text_canvas.width;var txtH=text_canvas.height;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+" "+textHeight+"px "+font_family;text_ctx.textAlign=textAlignment;for(i=0;i<paragraph.length;i++){textY=i*textHeight;text_ctx.fillText(paragraph[i],textX,textY);}
+if(this.texture===null)
+{this.texture=gl.createTexture();}
+gl.bindTexture(this.type,this.texture);gl.texImage2D(this.type,0,this.format,this.format,gl.UNSIGNED_BYTE,text_canvas);gl.bindTexture(this.type,null);document.body.removeChild(text_canvas);var w=txtW/100.0;var h=txtH/100.0;this.node._mesh._positions[0]=[-w,-h+.4,0,w,-h+.4,0,w,h+.4,0,-w,h+.4,0];this.node.invalidateVolume();Array.forEach(this.node._parentNodes,function(node){node.setAllDirty();});};x3dom.X3DDocument=function(canvas,ctx,settings){this.canvas=canvas;this.ctx=ctx;this.properties=settings;this.needRender=true;this._x3dElem=null;this._scene=null;this._viewarea=null;this.downloadCount=0;this._nodeBag={timer:[],lights:[],clipPlanes:[],followers:[],trans:[],renderTextures:[],viewarea:[],affectedPointingSensors:[]};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;doc._x3dElem=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;function cleanNodeBag(bag,node){for(var i=0,n=bag.length;i<n;i++){if(bag[i]===node){bag.splice(i,1);break;}}}
+function removeX3DOMBackendGraph(domNode){var children=domNode.childNodes;for(var i=0,n=children.length;i<n;i++){removeX3DOMBackendGraph(children[i]);}
+if(domNode._x3domNode){var node=domNode._x3domNode;var nameSpace=node._nameSpace;if(x3dom.isa(node,x3dom.nodeTypes.X3DShapeNode)){if(node._cleanupGLObjects){node._cleanupGLObjects(true);}
+if(x3dom.nodeTypes.Shape.idMap.nodeID[node._objectID]){delete x3dom.nodeTypes.Shape.idMap.nodeID[node._objectID];}}
+else if(x3dom.isa(node,x3dom.nodeTypes.TimeSensor)){cleanNodeBag(doc._nodeBag.timer,node);}
+else if(x3dom.isa(node,x3dom.nodeTypes.X3DLightNode)){cleanNodeBag(doc._nodeBag.lights,node);}
+else if(x3dom.isa(node,x3dom.nodeTypes.X3DFollowerNode)){cleanNodeBag(doc._nodeBag.followers,node);}
+else if(x3dom.isa(node,x3dom.nodeTypes.X3DTransformNode)){cleanNodeBag(doc._nodeBag.trans,node);}
+else if(x3dom.isa(node,x3dom.nodeTypes.RenderedTexture)){cleanNodeBag(doc._nodeBag.renderTextures,node);if(node._cleanupGLObjects){node._cleanupGLObjects();}}
+else if(x3dom.isa(node,x3dom.nodeTypes.X3DPointingDeviceSensorNode)){cleanNodeBag(doc._nodeBag.affectedPointingSensors,node);}
+else if(x3dom.isa(node,x3dom.nodeTypes.Texture)){node.shutdown();}
+else if(x3dom.isa(node,x3dom.nodeTypes.AudioClip)){node.shutdown();}
+else if(x3dom.isa(node,x3dom.nodeTypes.X3DBindableNode)){var stack=node._stack;if(stack){node.bind(false);cleanNodeBag(stack._bindBag,node);}
+if(node._cleanupGLObjects){node._cleanupGLObjects();}}
+else if(x3dom.isa(node,x3dom.nodeTypes.Scene)){if(node._webgl){node._webgl=null;}}
+if(nameSpace&&!domNode.getAttribute('use'))
+{nameSpace.removeNode(node._DEF);}
+node._xmlNode=null;delete domNode._x3domNode;}}
+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){var domNode=e.target;if(!domNode)
+return;if('_x3domNode'in domNode.parentNode&&'_x3domNode'in domNode){var parent=domNode.parentNode._x3domNode;var child=domNode._x3domNode;if(parent&&child){parent.removeChild(child);parent.nodeChanged();removeX3DOMBackendGraph(domNode);if(doc._viewarea&&doc._viewarea._scene){doc._viewarea._scene.nodeChanged();doc._viewarea._scene.updateVolume();doc.needRender=true;}}}
+else if(domNode.localName&&domNode.localName.toUpperCase()=="ROUTE"&&domNode._nodeNameSpace){var fromNode=domNode._nodeNameSpace.defMap[domNode.getAttribute('fromNode')];var toNode=domNode._nodeNameSpace.defMap[domNode.getAttribute('toNode')];if(fromNode&&toNode){fromNode.removeRoute(domNode.getAttribute('fromField'),toNode,domNode.getAttribute('toField'));}}
+else if(domNode.localName&&domNode.localName.toUpperCase()=="X3D"){var runtime=domNode.runtime;if(runtime&&runtime.canvas&&runtime.canvas.doc&&runtime.canvas.doc._scene){var sceneNode=runtime.canvas.doc._scene._xmlNode;removeX3DOMBackendGraph(sceneNode);for(var i=0;i<x3dom.canvases.length;i++){if(x3dom.canvases[i]===runtime.canvas){x3dom.canvases[i].doc.shutdown(x3dom.canvases[i].gl);x3dom.canvases.splice(i,1);break;}}
+runtime.canvas.doc._scene=null;runtime.canvas.doc._viewarea=null;runtime.canvas.doc=null;runtime.canvas=null;runtime=null;domNode.context=null;domNode.runtime=null;}}},onNodeInserted:function(e){var child=e.target;var parentNode=child.parentNode;if('_x3domNode'in parentNode){if(parentNode.tagName&&parentNode.tagName.toLowerCase()=='inline'||parentNode.tagName.toLowerCase()=='multipart'){}
+else{var parent=parentNode._x3domNode;if(parent&&parent._nameSpace&&(child instanceof Element)){if(x3dom.caps.DOMNodeInsertedEvent_perSubtree)
+{removeX3DOMBackendGraph(child);}
+var newNode=parent._nameSpace.setupTree(child);parent.addChild(newNode,child.getAttribute("containerField"));parent.nodeChanged();var grandParentNode=parentNode.parentNode;if(grandParentNode&&grandParentNode._x3domNode)
+grandParentNode._x3domNode.nodeChanged();if(doc._viewarea&&doc._viewarea._scene){doc._viewarea._scene.nodeChanged();doc._viewarea._scene.updateVolume();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 i=0;if(this._nodeBag.timer.length){for(i=0;i<this._nodeBag.timer.length;i++)
+{this.needRender|=this._nodeBag.timer[i].tick(t);}}
+if(this._nodeBag.followers.length){for(i=0;i<this._nodeBag.followers.length;i++)
+{this.needRender|=this._nodeBag.followers[i].tick(t);}}
+if(this._nodeBag.trans.length){for(i=0;i<this._nodeBag.trans.length;i++)
+{this.needRender|=this._nodeBag.trans[i].tick(t);}}
+if(this._nodeBag.viewarea.length){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.onPick=function(ctx,x,y){if(!ctx||!this._viewarea){return;}
+ctx.pickValue(this._viewarea,x,y,1);};x3dom.X3DDocument.prototype.onPickRect=function(ctx,x1,y1,x2,y2){if(!ctx||!this._viewarea){return[];}
+return ctx.pickRect(this._viewarea,x1,y1,x2,y2);};x3dom.X3DDocument.prototype.onMove=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
+if(this._viewarea._scene._vf.doPickPass)
+ctx.pickValue(this._viewarea,x,y,buttonState);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;}
+if(this._viewarea._scene._vf.doPickPass)
+ctx.pickValue(this._viewarea,x,y,buttonState);this._viewarea.onDrag(x,y,buttonState);};x3dom.X3DDocument.prototype.onMousePress=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
+this._viewarea._scene.updateVolume();ctx.pickValue(this._viewarea,x,y,buttonState);this._viewarea.onMousePress(x,y,buttonState);};x3dom.X3DDocument.prototype.onMouseRelease=function(ctx,x,y,buttonState,prevButton){if(!ctx||!this._viewarea){return;}
+var button=(prevButton<<8)|buttonState;ctx.pickValue(this._viewarea,x,y,button);this._viewarea.onMouseRelease(x,y,buttonState,prevButton);};x3dom.X3DDocument.prototype.onMouseOver=function(ctx,x,y,buttonState){if(!ctx||!this._viewarea){return;}
+ctx.pickValue(this._viewarea,x,y,buttonState);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,buttonState);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.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 13:x3dom.toggleFullScreen();break;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();var env=this._scene.getEnvironment();switch(charCode)
+{case 32:var states=this.canvas.parent.stateViewer;if(states){states.display();}
+x3dom.debug.logInfo("a: show all | d: show helper buffers | s: small feature culling | t: light view | "+"m: toggle render mode | c: frustum culling | p: intersect type | r: reset view | \n"+"e: examine mode | f: fly mode | y: freefly mode | w: walk mode | h: helicopter mode | "+"l: lookAt mode | o: lookaround | g: game mode | n: turntable | u: upright position | \n"+"v: print viewpoint info | pageUp: next view | pageDown: prev. view | "+"+: increase speed | -: decrease speed ");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 51:x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor+=0.5;x3dom.debug.logInfo("Changed POP error tolerance to "+x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor);break;case 52:x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor-=0.5;x3dom.debug.logInfo("Changed POP error tolerance to "+x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor);break;case 54:nav._vf.typeParams[1]+=1.0;nav._heliUpdated=false;x3dom.debug.logInfo("Changed helicopter height to "+nav._vf.typeParams[1]);break;case 55:nav._vf.typeParams[1]-=1.0;nav._heliUpdated=false;x3dom.debug.logInfo("Changed helicopter height to "+nav._vf.typeParams[1]);break;case 56:nav._vf.typeParams[0]-=0.02;nav._heliUpdated=false;x3dom.debug.logInfo("Changed helicopter angle to "+nav._vf.typeParams[0]);break;case 57:nav._vf.typeParams[0]+=0.02;nav._heliUpdated=false;x3dom.debug.logInfo("Changed helicopter angle to "+nav._vf.typeParams[0]);break;case 97:this._viewarea.showAll();break;case 99:env._vf.frustumCulling=!env._vf.frustumCulling;x3dom.debug.logInfo("Viewfrustum culling "+(env._vf.frustumCulling?"on":"off"));break;case 100:if(this._viewarea._visDbgBuf===undefined){this._viewarea._visDbgBuf=(this._x3dElem.getAttribute("showLog")==='true');}
+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 104:nav.setType("helicopter",this._viewarea);break;case 105:this._viewarea.fit(this._scene._lastMin,this._scene._lastMax);break;case 108:nav.setType("lookat",this._viewarea);break;case 109:this._viewarea._points=++this._viewarea._points%3;break;case 110:nav.setType("turntable",this._viewarea);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:env._vf.smallFeatureCulling=!env._vf.smallFeatureCulling;x3dom.debug.logInfo("Small feature culling "+(env._vf.smallFeatureCulling?"on":"off"));break;case 116:if(this._nodeBag.lights.length>0){this._viewarea.animateTo(this._viewarea.getLightMatrix()[0],this._scene.getViewpoint());}
+break;case 117:this._viewarea.uprightView();break;case 118:var that=this;(function(){var viewpoint=that._viewarea._scene.getViewpoint();var mat_view=that._viewarea.getViewMatrix().inverse();var rotation=new x3dom.fields.Quaternion(0,0,1,0);rotation.setValue(mat_view);var rot=rotation.toAxisAngle();var translation=mat_view.e3();x3dom.debug.logInfo('\n&lt;Viewpoint position="'+translation.x.toFixed(5)+' '
++translation.y.toFixed(5)+' '+translation.z.toFixed(5)+'" '+'orientation="'+rot[0].x.toFixed(5)+' '+rot[0].y.toFixed(5)+' '
++rot[0].z.toFixed(5)+' '+rot[1].toFixed(5)+'" \n\t'+'zNear="'+viewpoint.getNear().toFixed(5)+'" '+'zFar="'+viewpoint.getFar().toFixed(5)+'" '+'description="'+viewpoint._vf.description+'"&gt;'+'&lt;/Viewpoint&gt;');})();break;case 119:nav.setType("walk",this._viewarea);break;case 121:nav.setType("freefly",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=1;}
+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();this._logDiffMat=this._endLogMat.addScaled(this._beginLogMat,-1);};x3dom.MatrixMixer.prototype.mix=function(time){var mat=null;if(time<=this._beginTime)
+{mat=x3dom.fields.SFMatrix4f.copy(this._beginLogMat);}
+else
+{if(time>=this._endTime)
+{mat=x3dom.fields.SFMatrix4f.copy(this._endLogMat);}
+else
+{var fraction=this.calcFraction(time);mat=this._logDiffMat.multiply(fraction).add(this._beginLogMat);}}
+return mat.exp().mult(this._beginMat);};x3dom.InputTypes={};x3dom.InputTypes.NAVIGATION=1;x3dom.InputTypes.INTERACTION=2;x3dom.Viewarea=function(document,scene){this._doc=document;this._scene=scene;document._nodeBag.viewarea.push(this);this._pickingInfo={pickPos:new x3dom.fields.SFVec3f(0,0,0),pickNorm:new x3dom.fields.SFVec3f(0,0,1),pickObj:null,firstObj:null,lastObj:null,lastClickObj:null,shadowObjectId:-1};this._currentInputType=x3dom.InputTypes.NAVIGATION;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._points=0;this._numRenderedNodes=0;this._pick=new x3dom.fields.SFVec3f(0,0,0);this._pickNorm=new x3dom.fields.SFVec3f(0,0,1);this._isAnimating=false;this._isMoving=false;this._lastTS=0;this._mixer=new x3dom.MatrixMixer();this.arc=null;};x3dom.Viewarea.prototype.tick=function(timeStamp)
+{var needMixAnim=false;var env=this._scene.getEnvironment();if(env._vf.enableARC&&this.arc==null)
+{this.arc=new x3dom.arc.AdaptiveRenderControl(this._scene);}
+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._mixer._beginTime=0;this._mixer._endTime=0;this._scene.getViewpoint().setView(this._mixer._beginMat);}}
+var needNavAnim=this.navigateTo(timeStamp);var lastIsAnimating=this._isAnimating;this._lastTS=timeStamp;this._isAnimating=(needMixAnim||needNavAnim);if(this.arc!=null)
+{this.arc.update(this.isMovingOrAnimating()?1:0,this._doc._x3dElem.runtime.getFPS());}
+return(this._isAnimating||lastIsAnimating);};x3dom.Viewarea.prototype.isMoving=function()
+{return this._isMoving;};x3dom.Viewarea.prototype.isAnimating=function()
+{return this._isAnimating;};x3dom.Viewarea.prototype.isMovingOrAnimating=function()
+{return(this._isMoving||this._isAnimating);};x3dom.Viewarea.prototype.navigateTo=function(timeStamp)
+{var navi=this._scene.getNavigationInfo();var navType=navi.getType();var needNavAnim=(this._currentInputType==x3dom.InputTypes.NAVIGATION)&&(navType==="game"||(this._lastButton>0&&(navType.indexOf("fly")>=0||navType==="walk"||navType==="helicopter"||navType.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=2*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());if(navType==="helicopter")
+this._at.y=this._from.y;if(navType.substr(0,5)!=="looka")
+this._up=new x3dom.fields.SFVec3f(0,1,0);else
+this._up=this._flyMat.e1();this._pitch=angleX*180/Math.PI;this._yaw=angleY*180/Math.PI;this._eyePos=this._from.negate();}
+var tmpAt=null,tmpUp=null,tmpMat=null;var q,temp,fin;var lv,sv,up;if(navType==="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,this._lastButton,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;}
+else if(navType==="helicopter")
+{var typeParams=navi.getTypeParams();if(this._lastButton&2)
+{var stepUp=this._deltaT*this._deltaT*navi._vf.speed;stepUp*=0.1*(this._pressY-this._lastY)*Math.abs(this._pressY-this._lastY);typeParams[1]+=stepUp;navi.setTypeParams(typeParams);}
+if(this._lastButton&1){step*=0.01*(this._pressY-this._lastY)*Math.abs(this._pressY-this._lastY);}
+else{step=0;}
+theta=typeParams[0];this._from.y=typeParams[1];this._at.y=this._from.y;q=x3dom.fields.Quaternion.axisAngle(this._up,phi);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);lv=this._at.subtract(this._from).normalize();sv=lv.cross(this._up).normalize();up=sv.cross(lv).normalize();lv=lv.multiply(step);this._from=this._from.add(lv);this._at=this._at.add(lv);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);var at=fin.multMatrixPnt(this._at);this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,at,up);this._scene.getViewpoint().setView(this._flyMat.inverse());return needNavAnim;}
+q=x3dom.fields.Quaternion.axisAngle(this._up,phi);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);lv=this._at.subtract(this._from).normalize();sv=lv.cross(this._up).normalize();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(navType.substr(0,5)!=="looka")
+{var currProjMat=this.getProjectionMatrix();if(navType!=="freefly"){if(step<0){tmpMat=new x3dom.fields.SFMatrix4f();tmpMat.setValue(this._last_mat_view.e0(),this._last_mat_view.e1(),this._last_mat_view.e2().negate(),this._last_mat_view.e3());this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2,this._lastButton,tmpMat,currProjMat.mult(tmpMat));}
+else{this._scene._nameSpace.doc.ctx.pickValue(this,this._width/2,this._height/2,this._lastButton);}
+if(this._pickingInfo.pickObj)
+{dist=this._pickingInfo.pickPos.subtract(this._from).length();if(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(navType==="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,this._lastButton,tmpMat,currProjMat.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.getType()==="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,this._lastButton);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.getType()==="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.getType()==="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.getType()==="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.X3DViewpointNode)){target=target.getViewMatrix().mult(target.getCurrentTransform().inverse());}
+if(navi._vf.transitionType[0].toLowerCase()!=="teleport"&&navi.getType()!=="game")
+{if(prev&&x3dom.isa(prev,x3dom.nodeTypes.X3DViewpointNode)){prev=prev.getViewMatrix().mult(prev.getCurrentTransform().inverse()).mult(this._transMat).mult(this._rotMat);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);this._scene.getViewpoint().setView(prev);}
+else{this._scene.getViewpoint().setView(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(){var enabledLights=[];for(var i=0;i<this._doc._nodeBag.lights.length;i++)
+{if(this._doc._nodeBag.lights[i]._vf.on==true)
+{enabledLights.push(this._doc._nodeBag.lights[i]);}}
+return enabledLights;};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;}}
+return false;};x3dom.Viewarea.prototype.updateSpecialNavigation=function(viewpoint,mat_viewpoint){var navi=this._scene.getNavigationInfo();var navType=navi.getType();if(navType=="helicopter"&&!navi._heliUpdated)
+{var typeParams=navi.getTypeParams();var theta=typeParams[0];var currViewMat=viewpoint.getViewMatrix().mult(mat_viewpoint.inverse()).inverse();this._from=currViewMat.e3();this._at=this._from.subtract(currViewMat.e2());this._up=new x3dom.fields.SFVec3f(0,1,0);this._from.y=typeParams[1];this._at.y=this._from.y;var sv=currViewMat.e0();var q=x3dom.fields.Quaternion.axisAngle(sv,theta);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);this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,this._at,this._up);this._scene.getViewpoint().setView(this._flyMat.inverse());navi._heliUpdated=true;}};x3dom.Viewarea.prototype.getViewpointMatrix=function()
+{var viewpoint=this._scene.getViewpoint();var mat_viewpoint=viewpoint.getCurrentTransform();this.updateSpecialNavigation(viewpoint,mat_viewpoint);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 vol=this._scene.getVolume();if(vol.isValid())
+{var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();vol.getBounds(min,max);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)){var wcLoc=lights[i].getCurrentTransform().multMatrixPnt(lights[i]._vf.location);dia=dia.subtract(wcLoc).normalize();}
+else{var dir=lights[i].getCurrentTransform().multMatrixVec(lights[i]._vf.direction);dir=dir.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.getWCtoLCMatricesPointLight=function(view,lightNode,mat_proj)
+{var zNear=lightNode._vf.zNear;var zFar=lightNode._vf.zFar;var proj=this.getLightProjectionMatrix(view,zNear,zFar,false,mat_proj);proj._00=1;proj._11=1;var matrices=[];matrices[0]=proj.mult(view);var rotationMatrix;for(var i=1;i<=3;i++){rotationMatrix=x3dom.fields.SFMatrix4f.rotationY(i*Math.PI/2);matrices[i]=proj.mult(rotationMatrix.mult(view));}
+rotationMatrix=x3dom.fields.SFMatrix4f.rotationX(Math.PI/2);matrices[4]=proj.mult(rotationMatrix.mult(view));rotationMatrix=x3dom.fields.SFMatrix4f.rotationX(3*Math.PI/2);matrices[5]=proj.mult(rotationMatrix.mult(view));return matrices;};x3dom.Viewarea.prototype.getWCtoLCMatricesCascaded=function(view,lightNode,mat_proj)
+{var numCascades=Math.max(1,Math.min(lightNode._vf.shadowCascades,6));var splitFactor=Math.max(0,Math.min(lightNode._vf.shadowSplitFactor,1));var splitOffset=Math.max(0,Math.min(lightNode._vf.shadowSplitOffset,1));var isSpotLight=x3dom.isa(lightNode,x3dom.nodeTypes.SpotLight);var zNear=lightNode._vf.zNear;var zFar=lightNode._vf.zFar;var proj=this.getLightProjectionMatrix(view,zNear,zFar,true,mat_proj);if(isSpotLight){proj._00=1;proj._11=1;}
+var viewProj=proj.mult(view);var matrices=[];if(numCascades==1){matrices[0]=viewProj;return matrices;}
+var cascadeSplits=this.getShadowSplitDepths(numCascades,splitFactor,splitOffset,true,mat_proj);for(var i=0;i<numCascades;i++){var fittingMat=this.getLightFittingMatrix(viewProj,cascadeSplits[i],cascadeSplits[i+1],mat_proj);matrices[i]=fittingMat.mult(viewProj);}
+return matrices;};x3dom.Viewarea.prototype.getLightProjectionMatrix=function(lMat,zNear,zFar,highPrecision,mat_proj)
+{var proj=x3dom.fields.SFMatrix4f.copy(mat_proj);if(!highPrecision||zNear>0||zFar>0){var lightPos=lMat.inverse().e3();var nearScale=0.8;var farScale=1.2;var min=x3dom.fields.SFVec3f.copy(this._scene._lastMin);var max=x3dom.fields.SFVec3f.copy(this._scene._lastMax);var dia=max.subtract(min);var sRad=dia.length()/2;var sCenter=min.add(dia.multiply(0.5));var vDist=(lightPos.subtract(sCenter)).length();var near,far;if(sRad){if(vDist>sRad)
+near=(vDist-sRad)*nearScale;else
+near=1;far=(vDist+sRad)*farScale;}
+if(zNear>0)near=zNear;if(zFar>0)far=zFar;proj._22=-(far+near)/(far-near);proj._23=-2.0*far*near/(far-near);return proj;}
+else{var cropMatrix=this.getLightCropMatrix(proj.mult(lMat));return cropMatrix.mult(proj);}};x3dom.Viewarea.prototype.getProjectionMatrix=function()
+{var viewpoint=this._scene.getViewpoint();return viewpoint.getProjectionMatrix(this._width/this._height);};x3dom.Viewarea.prototype.getViewfrustum=function(clipMat)
+{var env=this._scene.getEnvironment();if(env._vf.frustumCulling==true)
+{if(arguments.length==0){var proj=this.getProjectionMatrix();var view=this.getViewMatrix();return new x3dom.fields.FrustumVolume(proj.mult(view));}
+else{return new x3dom.fields.FrustumVolume(clipMat);}}
+return null;};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,mat)
+{var cctowc=mat?mat: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.Ray(from,dir);};x3dom.Viewarea.prototype.showAll=function(axis)
+{if(axis===undefined)
+axis="negZ";var scene=this._scene;scene.updateVolume();var min=x3dom.fields.SFVec3f.copy(scene._lastMin);var max=x3dom.fields.SFVec3f.copy(scene._lastMax);var x="x",y="y",z="z";var sign=1;var to,from=new x3dom.fields.SFVec3f(0,0,-1);switch(axis){case"posX":sign=-1;case"negX":z="x";x="y";y="z";to=new x3dom.fields.SFVec3f(sign,0,0);break;case"posY":sign=-1;case"negY":z="y";x="z";y="x";to=new x3dom.fields.SFVec3f(0,sign,0);break;case"posZ":sign=-1;case"negZ":default:to=new x3dom.fields.SFVec3f(0,0,-sign);break;}
+var viewpoint=scene.getViewpoint();var fov=viewpoint.getFieldOfView();var dia=max.subtract(min);var diaz2=dia[z]/2.0,tanfov2=Math.tan(fov/2.0);var dist1=(dia[y]/2.0)/tanfov2+diaz2;var dist2=(dia[x]/2.0)/tanfov2+diaz2;dia=min.add(dia.multiply(0.5));dia[z]+=sign*(dist1>dist2?dist1:dist2)*1.01;var quat=x3dom.fields.Quaternion.rotateFromTo(from,to);var viewmat=quat.toMatrix();viewmat=viewmat.mult(x3dom.fields.SFMatrix4f.translation(dia.negate()));this.animateTo(viewmat,viewpoint);};x3dom.Viewarea.prototype.fit=function(min,max,updateCenterOfRotation)
+{if(updateCenterOfRotation===undefined){updateCenterOfRotation=true;}
+var dia2=max.subtract(min).multiply(0.5);var center=min.add(dia2);var bsr=dia2.length();var viewpoint=this._scene.getViewpoint();var fov=viewpoint.getFieldOfView();var viewmat=x3dom.fields.SFMatrix4f.copy(this.getViewMatrix());var rightDir=new x3dom.fields.SFVec3f(viewmat._00,viewmat._01,viewmat._02);var upDir=new x3dom.fields.SFVec3f(viewmat._10,viewmat._11,viewmat._12);var viewDir=new x3dom.fields.SFVec3f(viewmat._20,viewmat._21,viewmat._22);var tanfov2=Math.tan(fov/2.0);var dist=bsr/tanfov2;var eyePos=center.add(viewDir.multiply(dist));viewmat._03=-rightDir.dot(eyePos);viewmat._13=-upDir.dot(eyePos);viewmat._23=-viewDir.dot(eyePos);if(updateCenterOfRotation){viewpoint.setCenterOfRotation(center);}
+if(x3dom.isa(viewpoint,x3dom.nodeTypes.OrthoViewpoint))
+{viewpoint._vf.fieldOfView[0]=-dist;viewpoint._vf.fieldOfView[1]=-dist;viewpoint._vf.fieldOfView[2]=dist;viewpoint._vf.fieldOfView[3]=dist;viewpoint._projMatrix=null;this.animateTo(viewmat,viewpoint,0);}
+else
+{this.animateTo(viewmat,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());var target=this._scene.getViewpoint();target.resetView();target=target.getViewMatrix().mult(target.getCurrentTransform().inverse());this._mixer.setEndMatrix(target);}
+else
+{this._scene.getViewpoint().resetView();}
+this.resetNavHelpers();navi._heliUpdated=false;};x3dom.Viewarea.prototype.resetNavHelpers=function()
+{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)
+{if(!node||!node._xmlNode)
+return null;try{var attrib=node._xmlNode[eventType];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(e){x3dom.debug.logException(e);}
+return event.cancelBubble;};x3dom.Viewarea.prototype.checkEvents=function(obj,x,y,buttonState,eventType)
+{var that=this;var needRecurse=true;var childNode;var i;var target=(obj&&obj._xmlNode)?obj._xmlNode:{};var affectedPointingSensorsList=this._doc._nodeBag.affectedPointingSensors;var event={viewarea:that,target: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,normalX:that._pickNorm.x,normalY:that._pickNorm.y,normalZ:that._pickNorm.z,hitPnt:that._pick.toGL(),hitObject:target,shadowObjectId:that._pickingInfo.shadowObjectId,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;},preventDefault:function(){this.cancelBubble=true;}};try{var anObj=obj;if(anObj&&anObj._xmlNode&&anObj._cf.geometry&&!anObj._xmlNode[eventType]&&!anObj._xmlNode.hasAttribute(eventType)&&!anObj._listeners[event.type]){anObj=anObj._cf.geometry.node;}
+if(anObj&&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(buttonState==0&&affectedPointingSensorsList.length==0&&(eventType=='onmousemove'||eventType=='onmouseover'||eventType=='onmouseout'))
+{for(i=0;i<node._childNodes.length;++i)
+{childNode=node._childNodes[i];if(x3dom.isa(childNode,x3dom.nodeTypes.X3DPointingDeviceSensorNode))
+{affectedPointingSensorsList.push(childNode);}}}
+if(x3dom.isa(node,x3dom.nodeTypes.Anchor)&&eventType==='onclick'){node.handleTouch();needRecurse=false;}
+else if(needRecurse){recurse(node);}});};if(needRecurse&&obj){recurse(obj);}
+return needRecurse;};x3dom.Viewarea.prototype._notifyAffectedPointingSensors=function(event)
+{var i;var affectedPointingSensorsList=this._doc._nodeBag.affectedPointingSensors;if(affectedPointingSensorsList.length>0)
+{if(event.type=='mousedown')
+{for(i=0;i<affectedPointingSensorsList.length;++i)
+{affectedPointingSensorsList[i].pointerPressedOverSibling(event);}}
+else if(event.type=='mousemove')
+{for(i=0;i<affectedPointingSensorsList.length;++i)
+{affectedPointingSensorsList[i].pointerMoved(event);}}
+else if(event.type=='mouseover')
+{for(i=0;i<affectedPointingSensorsList.length;++i)
+{affectedPointingSensorsList[i].pointerMovedOver(event);}}
+else if(event.type=='mouseout')
+{for(i=0;i<affectedPointingSensorsList.length;++i)
+{affectedPointingSensorsList[i].pointerMovedOut(event);}}}}
+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._isMoving=false;this._needNavigationMatrixUpdate=true;};x3dom.Viewarea.prototype.initTurnTable=function(navi)
+{var currViewMat=this.getViewMatrix();var viewpoint=this._scene.getViewpoint();var center=x3dom.fields.SFVec3f.copy(viewpoint.getCenterOfRotation());this._flyMat=currViewMat.inverse();this._from=this._flyMat.e3();this._at=center;this._up=this._flyMat.e1();this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,this._at,this._up);this._flyMat=this.calcOrbit(0,0,navi);var dur=0.2/navi._vf.speed;this.animateTo(this._flyMat.inverse(),viewpoint,dur);this.resetNavHelpers();};x3dom.Viewarea.prototype.onMousePress=function(x,y,buttonState)
+{this._needNavigationMatrixUpdate=true;this.prepareEvents(x,y,buttonState,"onmousedown");this._pickingInfo.lastClickObj=this._pickingInfo.pickObj;this._pickingInfo.firstObj=this._pickingInfo.pickObj;this._dx=0;this._dy=0;this._lastX=x;this._lastY=y;this._pressX=x;this._pressY=y;this._lastButton=buttonState;this._isMoving=false;if(this._currentInputType==x3dom.InputTypes.NAVIGATION)
+{var navi=this._scene.getNavigationInfo();if(navi.getType()==="turntable"){this.initTurnTable(navi);}}};x3dom.Viewarea.prototype.onMouseRelease=function(x,y,buttonState,prevButton)
+{var i;var affectedPointingSensorsList=this._doc._nodeBag.affectedPointingSensors;for(i=0;i<affectedPointingSensorsList.length;++i)
+{affectedPointingSensorsList[i].pointerReleased();}
+this._doc._nodeBag.affectedPointingSensors=[];var tDist=3.0;var dir;var navi=this._scene.getNavigationInfo();var navType=navi.getType();if(this._scene._vf.pickMode.toLowerCase()!=="box"){this.prepareEvents(x,y,prevButton,"onmouseup");if(this._pickingInfo.pickObj&&this._pickingInfo.pickObj===this._pickingInfo.lastClickObj)
+{this.prepareEvents(x,y,prevButton,"onclick");}
+else if(!this._pickingInfo.pickObj&&!this._pickingInfo.lastClickObj&&!this._pickingInfo.firstObj)
+{var eventType="backgroundClicked";try{if(this._scene._xmlNode&&(this._scene._xmlNode["on"+eventType]||this._scene._xmlNode.hasAttribute("on"+eventType)||this._scene._listeners[eventType])){var event={target:this._scene._xmlNode,type:eventType,button:prevButton,layerX:x,layerY:y,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;},preventDefault:function(){this.cancelBubble=true;}};this._scene.callEvtHandler(("on"+eventType),event);}}
+catch(e){x3dom.debug.logException("backgroundClicked: "+e);}}}
+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));}}
+this._pickingInfo.firstObj=null;if(this._currentInputType==x3dom.InputTypes.NAVIGATION&&(this._pickingInfo.pickObj||this._pickingInfo.shadowObjectId>=0)&&navType==="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 newAt=from.addScaled(dir,len);var s=dir.cross(up).normalize();dir=s.cross(up).normalize();if(step<0){dist=(0.5+len+dist)*2;}
+var newFrom=newAt.addScaled(dir,dist);laMat=x3dom.fields.SFMatrix4f.lookAt(newFrom,newAt,up);laMat=laMat.inverse();dist=newFrom.subtract(from).length();var dur=Math.max(0.5,Math.log((1+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;this._isMoving=false;};x3dom.Viewarea.prototype.onMouseOver=function(x,y,buttonState)
+{this._dx=0;this._dy=0;this._lastButton=0;this._isMoving=false;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._isMoving=false;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.getType()=="none"){return;}
+var pickMode=this._scene._vf.pickMode.toLowerCase();if((pickMode=="color"||pickMode=="texcoord")){return;}
+var viewpoint=this._scene.getViewpoint();viewpoint.setCenterOfRotation(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)
+{if(buttonState==0)
+{this._doc._nodeBag.affectedPointingSensors=[];}
+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)
+{if(this._currentInputType==x3dom.InputTypes.NAVIGATION)
+{var navi=this._scene.getNavigationInfo();var viewpoint=this._scene.getViewpoint();if(navi.getType()==="examine")
+{if(translation)
+{var distance=(this._scene._lastMax.subtract(this._scene._lastMin)).length();distance=((distance<x3dom.fields.Eps)?1:distance)*navi._vf.speed;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)
+{var center=viewpoint.getCenterOfRotation();var mat=this.getViewMatrix();mat.setTranslate(new x3dom.fields.SFVec3f(0,0,0));this._rotMat=this._rotMat.mult(x3dom.fields.SFMatrix4f.translation(center)).mult(mat.inverse()).mult(rotation).mult(mat).mult(x3dom.fields.SFMatrix4f.translation(center.negate()));}
+this._isMoving=true;}}};x3dom.Viewarea.prototype.onDrag=function(x,y,buttonState)
+{this.handleMoveEvt(x,y,buttonState);if(this._currentInputType==x3dom.InputTypes.NAVIGATION)
+{var navi=this._scene.getNavigationInfo();var navType=navi.getType();var navRestrict=navi.getExplorationMode();if(navType==="none"||navRestrict==0){return;}
+var viewpoint=this._scene.getViewpoint();var dx=x-this._lastX;var dy=y-this._lastY;var d,vec,cor,mat=null;var alpha,beta;buttonState=((navRestrict&buttonState)!=buttonState)?navRestrict:buttonState;if(navType==="examine")
+{if(buttonState&1)
+{alpha=(dy*2*Math.PI)/this._width;beta=(dx*2*Math.PI)/this._height;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)
+{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=((d<x3dom.fields.Eps)?1:d)*navi._vf.speed;vec=new x3dom.fields.SFVec3f(d*dx/this._width,d*(-dy)/this._height,0);this._movement=this._movement.add(vec);mat=this.getViewpointMatrix().mult(this._transMat);this._transMat=mat.inverse().mult(x3dom.fields.SFMatrix4f.translation(this._movement)).mult(mat);}
+if(buttonState&2)
+{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=((d<x3dom.fields.Eps)?1:d)*navi._vf.speed;vec=new x3dom.fields.SFVec3f(0,0,d*(dx+dy)/this._height);if(x3dom.isa(viewpoint,x3dom.nodeTypes.OrthoViewpoint))
+{viewpoint._vf.fieldOfView[0]+=vec.z;viewpoint._vf.fieldOfView[1]+=vec.z;viewpoint._vf.fieldOfView[2]-=vec.z;viewpoint._vf.fieldOfView[3]-=vec.z;viewpoint._projMatrix=null;}
+else
+{this._movement=this._movement.add(vec);mat=this.getViewpointMatrix().mult(this._transMat);this._transMat=mat.inverse().mult(x3dom.fields.SFMatrix4f.translation(this._movement)).mult(mat);}}
+this._isMoving=true;}
+else if(navType==="turntable")
+{if(buttonState&1)
+{alpha=(dy*2*Math.PI)/this._height;beta=(dx*2*Math.PI)/this._width;this._flyMat=this.calcOrbit(alpha,beta,navi);viewpoint.setView(this._flyMat.inverse());}
+else if(buttonState&2)
+{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=((d<x3dom.fields.Eps)?1:d)*navi._vf.speed;this._up=this._flyMat.e1();this._from=this._flyMat.e3();cor=viewpoint.getCenterOfRotation();var lastDir=cor.subtract(this._from);var lastDirL=lastDir.length();lastDir=lastDir.normalize();var zoomAmount=d*(dx+dy)/this._height;if(navi._vf.typeParams.length>=5&&navi._vf.typeParams[4]!=0)
+{var newDist=Math.min(zoomAmount,lastDirL-0.01);this._from=this._from.addScaled(lastDir,newDist);}
+else
+{var diff=zoomAmount-lastDirL+0.01;if(diff>=0){cor=cor.addScaled(lastDir,diff);viewpoint.setCenterOfRotation(cor);}
+this._from=this._from.addScaled(lastDir,zoomAmount);}
+this._from=this._from.addScaled(lastDir,zoomAmount);this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,cor,this._up);viewpoint.setView(this._flyMat.inverse());}
+else if(buttonState&4)
+{d=(this._scene._lastMax.subtract(this._scene._lastMin)).length();d=((d<x3dom.fields.Eps)?1:d)*navi._vf.speed*0.75;var tx=-d*dx/this._width;var ty=d*dy/this._height;this._up=this._flyMat.e1();this._from=this._flyMat.e3();var s=this._flyMat.e0();this._from=this._from.addScaled(this._up,ty);this._from=this._from.addScaled(s,tx);cor=viewpoint.getCenterOfRotation();cor=cor.addScaled(this._up,ty);cor=cor.addScaled(s,tx);viewpoint.setCenterOfRotation(cor);this._flyMat=x3dom.fields.SFMatrix4f.lookAt(this._from,cor,this._up);viewpoint.setView(this._flyMat.inverse());}
+this._isMoving=true;}}
+this._dx=dx;this._dy=dy;this._lastX=x;this._lastY=y;};x3dom.Viewarea.prototype.calcOrbit=function(alpha,beta,navi)
+{this._up=this._flyMat.e1();this._from=this._flyMat.e3();var offset=this._from.subtract(this._at);var phi=Math.atan2(offset.x,offset.z);var theta=Math.atan2(Math.sqrt(offset.x*offset.x+offset.z*offset.z),offset.y);phi-=Math.min(beta,0.1);theta-=Math.min(alpha,0.1);var typeParams=navi.getTypeParams();theta=Math.max(typeParams[2],Math.min(typeParams[3],theta));var radius=offset.length();var rSinPhi=radius*Math.sin(theta);offset.x=rSinPhi*Math.sin(phi);offset.y=radius*Math.cos(theta);offset.z=rSinPhi*Math.cos(phi);offset=this._at.add(offset);theta-=Math.PI/2;var sinPhi=Math.sin(theta);var cosPhi=Math.cos(theta);var up=new x3dom.fields.SFVec3f(sinPhi*Math.sin(phi),cosPhi,sinPhi*Math.cos(phi));if(up.y<0)
+up=up.negate();return x3dom.fields.SFMatrix4f.lookAt(offset,this._at,up);};x3dom.Viewarea.prototype.prepareEvents=function(x,y,buttonState,eventType)
+{var affectedPointingSensorsList=this._doc._nodeBag.affectedPointingSensors;var pickMode=this._scene._vf.pickMode.toLowerCase();var avoidTraversal=(pickMode.indexOf("idbuf")==0||pickMode=="color"||pickMode=="texcoord");var obj=null;if(avoidTraversal){obj=this._pickingInfo.pickObj;if(obj){this._pick.setValues(this._pickingInfo.pickPos);this._pickNorm.setValues(this._pickingInfo.pickNorm);this.checkEvents(obj,x,y,buttonState,eventType);if(eventType==="onclick"){if(obj._xmlNode)
+x3dom.debug.logInfo("Hit \""+obj._xmlNode.localName+"/ "+obj._DEF+"\"");x3dom.debug.logInfo("Ray hit at position "+this._pick);}}}
+var event={viewarea:this,target:{},type:eventType.substr(2,eventType.length-2),button:buttonState,layerX:x,layerY:y,worldX:this._pick.x,worldY:this._pick.y,worldZ:this._pick.z,normalX:this._pickNorm.x,normalY:this._pickNorm.y,normalZ:this._pickNorm.z,hitPnt:this._pick.toGL(),hitObject:(obj&&obj._xmlNode)?obj._xmlNode:null,shadowObjectId:this._pickingInfo.shadowObjectId,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;},preventDefault:function(){this.cancelBubble=true;}};this._notifyAffectedPointingSensors(event);if(affectedPointingSensorsList.length>0)
+{this._currentInputType=x3dom.InputTypes.INTERACTION;}
+else
+{this._currentInputType=x3dom.InputTypes.NAVIGATION;}};x3dom.Viewarea.prototype.getRenderMode=function()
+{return this._points;};x3dom.Viewarea.prototype.getShadowedLights=function()
+{var shadowedLights=[];var shadowIndex=0;var slights=this.getLights();for(var i=0;i<slights.length;i++){if(slights[i]._vf.shadowIntensity>0.0){shadowedLights[shadowIndex]=slights[i];shadowIndex++;}}
+return shadowedLights;};x3dom.Viewarea.prototype.getShadowSplitDepths=function(numCascades,splitFactor,splitOffset,postProject,mat_proj)
+{var logSplit;var practSplit=[];var viewPoint=this._scene.getViewpoint();var zNear=viewPoint.getNear();var zFar=viewPoint.getFar();practSplit[0]=zNear;zNear=zNear+splitOffset*(zFar-zNear)/10;for(var i=1;i<numCascades;i++){logSplit=zNear*Math.pow((zFar/zNear),i/numCascades);practSplit[i]=splitFactor*logSplit+(1-splitFactor)*(zNear+i/(numCascades*(zNear-zFar)));}
+practSplit[numCascades]=zFar;if(!postProject)
+return practSplit;var postProj=[];for(var j=0;j<=numCascades;j++){postProj[j]=mat_proj.multFullMatrixPnt(new x3dom.fields.SFVec3f(0,0,-practSplit[j])).z;}
+return postProj;};x3dom.Viewarea.prototype.getLightCropMatrix=function(WCToLCMatrix)
+{var sceneMin=x3dom.fields.SFVec3f.copy(this._scene._lastMin);var sceneMax=x3dom.fields.SFVec3f.copy(this._scene._lastMax);var sceneCorners=[];sceneCorners[0]=new x3dom.fields.SFVec3f(sceneMin.x,sceneMin.y,sceneMin.z);sceneCorners[1]=new x3dom.fields.SFVec3f(sceneMin.x,sceneMin.y,sceneMax.z);sceneCorners[2]=new x3dom.fields.SFVec3f(sceneMin.x,sceneMax.y,sceneMin.z);sceneCorners[3]=new x3dom.fields.SFVec3f(sceneMin.x,sceneMax.y,sceneMax.z);sceneCorners[4]=new x3dom.fields.SFVec3f(sceneMax.x,sceneMin.y,sceneMin.z);sceneCorners[5]=new x3dom.fields.SFVec3f(sceneMax.x,sceneMin.y,sceneMax.z);sceneCorners[6]=new x3dom.fields.SFVec3f(sceneMax.x,sceneMax.y,sceneMin.z);sceneCorners[7]=new x3dom.fields.SFVec3f(sceneMax.x,sceneMax.y,sceneMax.z);var i;for(i=0;i<8;i++){sceneCorners[i]=WCToLCMatrix.multFullMatrixPnt(sceneCorners[i]);}
+var minScene=x3dom.fields.SFVec3f.copy(sceneCorners[0]);var maxScene=x3dom.fields.SFVec3f.copy(sceneCorners[0]);for(i=1;i<8;i++){minScene.z=Math.min(sceneCorners[i].z,minScene.z);maxScene.z=Math.max(sceneCorners[i].z,maxScene.z);}
+var scaleZ=2.0/(maxScene.z-minScene.z);var offsetZ=-(scaleZ*(maxScene.z+minScene.z))/2.0;var cropMatrix=x3dom.fields.SFMatrix4f.identity();cropMatrix._22=scaleZ;cropMatrix._23=offsetZ;return cropMatrix;};x3dom.Viewarea.prototype.getLightFittingMatrix=function(WCToLCMatrix,zNear,zFar,mat_proj)
+{var mat_view=this.getViewMatrix();var mat_view_proj=mat_proj.mult(mat_view);var mat_view_proj_inverse=mat_view_proj.inverse();var frustumCorners=[];frustumCorners[0]=new x3dom.fields.SFVec3f(-1,-1,zFar);frustumCorners[1]=new x3dom.fields.SFVec3f(-1,-1,zNear);frustumCorners[2]=new x3dom.fields.SFVec3f(-1,1,zFar);frustumCorners[3]=new x3dom.fields.SFVec3f(-1,1,zNear);frustumCorners[4]=new x3dom.fields.SFVec3f(1,-1,zFar);frustumCorners[5]=new x3dom.fields.SFVec3f(1,-1,zNear);frustumCorners[6]=new x3dom.fields.SFVec3f(1,1,zFar);frustumCorners[7]=new x3dom.fields.SFVec3f(1,1,zNear);var i;for(i=0;i<8;i++){frustumCorners[i]=mat_view_proj_inverse.multFullMatrixPnt(frustumCorners[i]);frustumCorners[i]=WCToLCMatrix.multFullMatrixPnt(frustumCorners[i]);}
+var minFrustum=x3dom.fields.SFVec3f.copy(frustumCorners[0]);var maxFrustum=x3dom.fields.SFVec3f.copy(frustumCorners[0]);for(i=1;i<8;i++){minFrustum.x=Math.min(frustumCorners[i].x,minFrustum.x);minFrustum.y=Math.min(frustumCorners[i].y,minFrustum.y);minFrustum.z=Math.min(frustumCorners[i].z,minFrustum.z);maxFrustum.x=Math.max(frustumCorners[i].x,maxFrustum.x);maxFrustum.y=Math.max(frustumCorners[i].y,maxFrustum.y);maxFrustum.z=Math.max(frustumCorners[i].z,maxFrustum.z);}
+function clip(min,max)
+{var xMin=min.x;var yMin=min.y;var zMin=min.z;var xMax=max.x;var yMax=max.y;var zMax=max.z;if(xMin>1.0||xMax<-1.0){xMin=-1.0;xMax=1.0;}else{xMin=Math.max(xMin,-1.0);xMax=Math.min(xMax,1.0);}
+if(yMin>1.0||yMax<-1.0){yMin=-1.0;yMax=1.0;}else{yMin=Math.max(yMin,-1.0);yMax=Math.min(yMax,1.0);}
+if(zMin>1.0||zMax<-1.0){zMin=-1.0;zMax=1.0;}else{zMin=Math.max(zMin,-1.0);zMax=Math.min(zMax,1.0);}
+var minValues=new x3dom.fields.SFVec3f(xMin,yMin,zMin);var maxValues=new x3dom.fields.SFVec3f(xMax,yMax,zMax);return new x3dom.fields.BoxVolume(minValues,maxValues);}
+var frustumBB=clip(minFrustum,maxFrustum);var scaleX=2.0/(frustumBB.max.x-frustumBB.min.x);var scaleY=2.0/(frustumBB.max.y-frustumBB.min.y);var offsetX=-(scaleX*(frustumBB.max.x+frustumBB.min.x))/2.0;var offsetY=-(scaleY*(frustumBB.max.y+frustumBB.min.y))/2.0;var fittingMatrix=x3dom.fields.SFMatrix4f.identity();fittingMatrix._00=scaleX;fittingMatrix._11=scaleY;fittingMatrix._03=offsetX;fittingMatrix._13=offsetY;return fittingMatrix;};x3dom.Mesh=function(parent)
+{this._parent=parent;this._vol=new x3dom.fields.BoxVolume();this._invalidate=true;this._numFaces=0;this._numCoords=0;this._primType='TRIANGLES';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._numPosComponents=3;x3dom.Mesh.prototype._numTexComponents=2;x3dom.Mesh.prototype._numColComponents=3;x3dom.Mesh.prototype._numNormComponents=3;x3dom.Mesh.prototype._lit=true;x3dom.Mesh.prototype._vol=null;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.getVolume=function()
+{if(this._invalidate==true&&!this._vol.isValid())
+{var coords=this._positions[0];var n=coords.length;if(n>3)
+{var initVal=new x3dom.fields.SFVec3f(coords[0],coords[1],coords[2]);this._vol.setBounds(initVal,initVal);for(var i=3;i<n;i+=3)
+{if(this._vol.min.x>coords[i]){this._vol.min.x=coords[i];}
+if(this._vol.min.y>coords[i+1]){this._vol.min.y=coords[i+1];}
+if(this._vol.min.z>coords[i+2]){this._vol.min.z=coords[i+2];}
+if(this._vol.max.x<coords[i]){this._vol.max.x=coords[i];}
+if(this._vol.max.y<coords[i+1]){this._vol.max.y=coords[i+1];}
+if(this._vol.max.z<coords[i+2]){this._vol.max.z=coords[i+2];}}
+this._invalidate=false;}}
+return this._vol;};x3dom.Mesh.prototype.invalidate=function()
+{this._invalidate=true;this._vol.invalidate();};x3dom.Mesh.prototype.isValid=function()
+{return this._vol.isValid();};x3dom.Mesh.prototype.getCenter=function()
+{return this.getVolume().getCenter();};x3dom.Mesh.prototype.getDiameter=function()
+{return this.getVolume().getDiameter();};x3dom.Mesh.prototype.doIntersect=function(line)
+{var vol=this.getVolume();var isect=line.intersect(vol.min,vol.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,ccw)
+{if(ccw===undefined)
+ccw=true;var multInd=this._multiIndIndices&&this._multiIndIndices.length;var idxs=multInd?this._multiIndIndices:this._indices[0];var coords=this._positions[0];var vertNormals=[];var vertFaceNormals=[];var i,j,m=coords.length;var a,b,n=null;var num=(this._posSize!==undefined&&this._posSize>m)?this._posSize/3:m/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){var ind_i0,ind_i1,ind_i2;var t;if(!multInd){ind_i0=idxs[i]*3;ind_i1=idxs[i+1]*3;ind_i2=idxs[i+2]*3;t=new x3dom.fields.SFVec3f(coords[ind_i1],coords[ind_i1+1],coords[ind_i1+2]);a=new x3dom.fields.SFVec3f(coords[ind_i0],coords[ind_i0+1],coords[ind_i0+2]).subtract(t);b=t.subtract(new x3dom.fields.SFVec3f(coords[ind_i2],coords[ind_i2+1],coords[ind_i2+2]));ind_i0=i*3;ind_i1=(i+1)*3;ind_i2=(i+2)*3;}
+else{ind_i0=i*3;ind_i1=(i+1)*3;ind_i2=(i+2)*3;t=new x3dom.fields.SFVec3f(coords[ind_i1],coords[ind_i1+1],coords[ind_i1+2]);a=new x3dom.fields.SFVec3f(coords[ind_i0],coords[ind_i0+1],coords[ind_i0+2]).subtract(t);b=t.subtract(new x3dom.fields.SFVec3f(coords[ind_i2],coords[ind_i2+1],coords[ind_i2+2]));}
+n=a.cross(b).normalize();if(!ccw)
+n=n.negate();if(creaseAngle<=x3dom.fields.Eps){vertNormals[ind_i0]=vertNormals[ind_i1]=vertNormals[ind_i2]=n.x;vertNormals[ind_i0+1]=vertNormals[ind_i1+1]=vertNormals[ind_i2+1]=n.y;vertNormals[ind_i0+2]=vertNormals[ind_i1+2]=vertNormals[ind_i2+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<m;i+=3){var iThird=i/3;var arr;if(!multInd){arr=vertFaceNormals[iThird];}
+else{arr=vertFaceNormals[idxs[iThird]];}
+num=arr.length;n=new x3dom.fields.SFVec3f(0,0,0);for(j=0;j<num;++j){n=n.add(arr[j]);}
+n=n.normalize();vertNormals[i]=n.x;vertNormals[i+1]=n.y;vertNormals[i+2]=n.z;}}
+this._normals[0]=vertNormals;};x3dom.Mesh.prototype.splitMesh=function(primStride,checkMultiIndIndices)
+{var pStride;var isMultiInd;if(typeof primStride===undefined){pStride=3;}else{pStride=primStride;}
+if(typeof checkMultiIndIndices===undefined){checkMultiIndIndices=false;}
+var MAX=x3dom.Utils.maxIndexableCoords;MAX=Math.floor(MAX/pStride)*pStride;if(this._positions[0].length/3<=MAX&&!checkMultiIndIndices){return;}
+if(checkMultiIndIndices){isMultiInd=this._multiIndIndices&&this._multiIndIndices.length;}else{isMultiInd=false;}
+var positions=this._positions[0];var normals=this._normals[0];var texCoords=this._texCoords[0];var colors=this._colors[0];var indices=isMultiInd?this._multiIndIndices: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);if(k){this._indices[i]=indices.slice(i*MAX,(i+1)*MAX);}else{this._indices[i]=indices.slice(i*MAX);}
+if(!isMultiInd){if(i){var m=i*MAX;for(var j=0,l=this._indices[i].length;j<l;j++){this._indices[i][j]-=m;}}}else{for(var j=0,l=this._indices[i].length;j<l;j++){this._indices[i][j]=j;}}
+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);var vol=this.getVolume();vol.getBounds(min,max);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;}}};if(typeof x3dom==="undefined")
+{x3dom={extend:function(f){function G(){}
+G.prototype=f.prototype||f;return new G();},debug:{logInfo:function(msg){console.log(msg);},logWarning:function(msg){console.warn(msg);},logError:function(msg){console.error(msg);}}};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;};}
+console.log("Using x3dom fields.js as standalone math and/or base types library.");}
+x3dom.fields={};var VecMath=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.copy=function(that){return new x3dom.fields.SFMatrix4f(that._00,that._01,that._02,that._03,that._10,that._11,that._12,that._13,that._20,that._21,that._22,that._23,that._30,that._31,that._32,that._33);};x3dom.fields.SFMatrix4f.prototype.copy=function(){return x3dom.fields.SFMatrix4f.copy(this);};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).normalize();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();var tmp=x3dom.fields.SFMatrix4f.identity();tmp.setValue(right,newUp,view,from);return tmp;};x3dom.fields.SFMatrix4f.perspectiveFrustum=function(left,right,bottom,top,near,far)
+{return new x3dom.fields.SFMatrix4f(2*near/(right-left),0,(right+left)/(right-left),0,0,2*near/(top-bottom),(top+bottom)/(top-bottom),0,0,0,-(far+near)/(far-near),-2*far*near/(far-near),0,0,-1,0);};x3dom.fields.SFMatrix4f.perspective=function(fov,aspect,near,far)
+{var f=1/Math.tan(fov/2);return new x3dom.fields.SFMatrix4f(f/aspect,0,0,0,0,f,0,0,0,0,(near+far)/(near-far),2*near*far/(near-far),0,0,-1,0);};x3dom.fields.SFMatrix4f.ortho=function(left,right,bottom,top,near,far,aspect)
+{var rl=(right-left)/2;var tb=(top-bottom)/2;var fn=far-near;if(aspect===undefined)
+aspect=1.0;if(aspect<(rl/tb))
+tb=rl/aspect;else
+rl=tb*aspect;left=-rl;right=rl;bottom=-tb;top=tb;rl*=2;tb*=2;return new x3dom.fields.SFMatrix4f(2/rl,0,0,-(right+left)/rl,0,2/tb,0,-(top+bottom)/tb,0,0,-2/fn,-(far+near)/fn,0,0,0,1);};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.prototype.setRotate=function(quat){var xx=quat.x*quat.x;var xy=quat.x*quat.y;var xz=quat.x*quat.z;var yy=quat.y*quat.y;var yz=quat.y*quat.z;var zz=quat.z*quat.z;var wx=quat.w*quat.x;var wy=quat.w*quat.y;var wz=quat.w*quat.z;this._00=1-2*(yy+zz);this._01=2*(xy-wz);this._02=2*(xz+wy);this._10=2*(xy+wz);this._11=1-2*(xx+zz);this._12=2*(yz-wx);this._20=2*(xz-wy);this._21=2*(yz+wx);this._22=1-2*(xx+yy);};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.setFromArray=function(a){this._00=a[0];this._01=a[4];this._02=a[8];this._03=a[12];this._10=a[1];this._11=a[5];this._12=a[9];this._13=a[13];this._20=a[2];this._21=a[6];this._22=a[10];this._23=a[14];this._30=a[3];this._31=a[7];this._32=a[11];this._33=a[15];};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 Y=x3dom.fields.SFMatrix4f.identity();var result=x3dom.fields.SFMatrix4f.copy(this);for(var i=0;i<6;i++)
+{var iX=result.inverse();var iY=(i==0)?x3dom.fields.SFMatrix4f.identity():Y.inverse();var rd=result.det(),yd=Y.det();var g=Math.abs(Math.pow(rd*yd,-0.125));var 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=Math.abs(this._00)+
+Math.abs(this._10)+
+Math.abs(this._20);var t=0;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=Math.abs(this._00)+
+Math.abs(this._01)+
+Math.abs(this._02);var t=0;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=null;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=x3dom.fields.SFMatrix4f.copy(this);}
+var flip=m.decompose(translation,rotation,scaleFactor,scaleOrientation);scaleFactor.setValues(scaleFactor.multiply(flip));};x3dom.fields.SFMatrix4f.prototype.decompose=function(t,r,s,so)
+{var A=x3dom.fields.SFMatrix4f.copy(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;}
+r.setValue(Q);S.spectralDecompose(SO,s);so.setValue(SO);return f;};x3dom.fields.SFMatrix4f.prototype.polarDecompose=function(Q,S)
+{var TOL=0.000000000001;var Mk=this.transpose();var Ek=x3dom.fields.SFMatrix4f.identity();var Mk_one=Mk.norm1_3x3();var Mk_inf=Mk.normInf_3x3();var MkAdjT;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.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));Q.setValues(Mk.transpose());S.setValues(Mk.mult(this));for(var i=0;i<3;++i)
+{for(var 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 diag=[this._00,this._11,this._22];var offDiag=[this._12,this._20,this._01];for(var iter=0;iter<maxIterations;++iter)
+{var sm=Math.abs(offDiag[0])+Math.abs(offDiag[1])+Math.abs(offDiag[2]);if(sm==0){break;}
+for(var 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=0,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(var 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 eps=1e-12;var A=x3dom.fields.SFMatrix4f.copy(this),Z=x3dom.fields.SFMatrix4f.copy(this);Z._00-=1;Z._11-=1;Z._22-=1;Z._33-=1;var k=0;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();Z.setValues(A);var result=x3dom.fields.SFMatrix4f.copy(A);var i=1;while(Z.normInfinity()>eps&&i<maxiter)
+{Z=Z.mult(A);i++;result=result.addScaled(Z,1.0/i);}
+return result.multiply(-(1<<k));};x3dom.fields.SFMatrix4f.prototype.exp=function(){var q=6;var A=x3dom.fields.SFMatrix4f.copy(this),D=x3dom.fields.SFMatrix4f.identity(),N=x3dom.fields.SFMatrix4f.identity(),result=x3dom.fields.SFMatrix4f.identity();var k=0,c=1.0;var j=1.0+parseInt(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){return((a1*b2*c3)+(a2*b3*c1)+(a3*b1*c2)-
+(a1*b3*c2)-(a2*b1*c3)-(a3*b2*c1));};x3dom.fields.SFMatrix4f.prototype.det=function(){var a1=this._00;var b1=this._10;var c1=this._20;var d1=this._30;var a2=this._01;var b2=this._11;var c2=this._21;var d2=this._31;var a3=this._02;var b3=this._12;var c3=this._22;var d3=this._32;var a4=this._03;var b4=this._13;var c4=this._23;var d4=this._33;return(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));};x3dom.fields.SFMatrix4f.prototype.inverse=function(){var a1=this._00;var b1=this._10;var c1=this._20;var d1=this._30;var a2=this._01;var b2=this._11;var c2=this._21;var d2=this._31;var a3=this._02;var b3=this._12;var c3=this._22;var d3=this._32;var a4=this._03;var b4=this._13;var c4=this._23;var d4=this._33;var rDet=this.det();if(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.getEulerAngles=function(){var theta_1,theta_2,theta;var phi_1,phi_2,phi;var psi_1,psi_2,psi;var cos_theta_1,cos_theta_2;if(Math.abs(this._20)!=1.0){theta_1=-Math.asin(this._20);theta_2=Math.PI-theta_1;cos_theta_1=Math.cos(theta_1);cos_theta_2=Math.cos(theta_2);psi_1=Math.atan2(this._21/cos_theta_1,this._22/cos_theta_1);psi_2=Math.atan2(this._21/cos_theta_2,this._22/cos_theta_2);phi_1=Math.atan2(this._10/cos_theta_1,this._00/cos_theta_1);phi_2=Math.atan2(this._10/cos_theta_2,this._00/cos_theta_2);return[psi_1,theta_1,phi_1,psi_2,theta_2,phi_2];}
+else{phi=0;if(this._20==-1.0){theta=Math.PI/2.0;psi=phi+Math.atan2(this._01,this._02);}
+else{theta=-(Math.PI/2.0);psi=-phi+Math.atan2(-this._01,-this._02);}
+return[psi,theta,phi,psi,theta,phi];}};x3dom.fields.SFMatrix4f.prototype.toString=function(){return'\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=0;this.y=0;}
+else{this.x=x;this.y=y;}};x3dom.fields.SFVec2f.copy=function(v){return new x3dom.fields.SFVec2f(v.x,v.y);};x3dom.fields.SFVec2f.parse=function(str){var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.exec(str);return new x3dom.fields.SFVec2f(+m[1],+m[2]);};x3dom.fields.SFVec2f.prototype.copy=function(){return x3dom.fields.SFVec2f.copy(this);};x3dom.fields.SFVec2f.prototype.setValues=function(that){this.x=that.x;this.y=that.y;};x3dom.fields.SFVec2f.prototype.at=function(i){switch(i){case 0:return this.x;case 1:return this.y;default:return this.x;}};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(){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 this.x+" "+this.y;};x3dom.fields.SFVec2f.prototype.setValueByStr=function(str){var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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=0;this.y=0;this.z=0;}
+else{this.x=x;this.y=y;this.z=z;}};x3dom.fields.SFVec3f.NullVector=new x3dom.fields.SFVec3f(0,0,0);x3dom.fields.SFVec3f.OneVector=new x3dom.fields.SFVec3f(1,1,1);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=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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.copy=function(){return x3dom.fields.SFVec3f.copy(this);};x3dom.fields.SFVec3f.prototype.setValues=function(that){this.x=that.x;this.y=that.y;this.z=that.z;};x3dom.fields.SFVec3f.prototype.at=function(i){switch(i){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:return this.x;}};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(){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 this.x+" "+this.y+" "+this.z;};x3dom.fields.SFVec3f.prototype.setValueByStr=function(str){try{var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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.SFVec4f=function(x,y,z,w){if(arguments.length===0){this.x=0;this.y=0;this.z=0;this.w=0;}
+else{this.x=x;this.y=y;this.z=z;this.w=w;}};x3dom.fields.SFVec4f.copy=function(v){return new x3dom.fields.SFVec4f(v.x,v.y,v.z,v.w);};x3dom.fields.SFVec4f.prototype.copy=function(){return x3dom.fields.SFVec4f(this);};x3dom.fields.SFVec4f.parse=function(str){var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.exec(str);return new x3dom.fields.SFVec4f(+m[1],+m[2],+m[3],+m[4]);};x3dom.fields.SFVec4f.prototype.setValueByStr=function(str){var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.exec(str);this.x=+m[1];this.y=+m[2];this.z=+m[3];this.w=+m[4];return this;};x3dom.fields.SFVec4f.prototype.toGL=function(){return[this.x,this.y,this.z,this.w];};x3dom.fields.SFVec4f.prototype.toString=function(){return this.x+" "+this.y+" "+this.z+" "+this.w;};x3dom.fields.Quaternion=function(x,y,z,w){if(arguments.length===0){this.x=0;this.y=0;this.z=1;this.w=0;}
+else{this.x=x;this.y=y;this.z=z;this.w=w;}};x3dom.fields.Quaternion.copy=function(v){return new x3dom.fields.Quaternion(v.x,v.y,v.z,v.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=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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.copy=function(){return x3dom.fields.Quaternion(this);};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.setFromEuler=function(alpha,beta,gamma){var sx=Math.sin(alpha*0.5);var cx=Math.cos(alpha*0.5);var sy=Math.sin(beta*0.5);var cy=Math.cos(beta*0.5);var sz=Math.sin(gamma*0.5);var cz=Math.cos(gamma*0.5);this.x=(sx*cy*cz)-(cx*sy*sz);this.y=(cx*sy*cz)+(sx*cy*sz);this.z=(cx*cy*sz)-(sx*sy*cz);this.w=(cx*cy*cz)+(sx*sy*sz);};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(this.dot(that)>=1.0-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.toGL=function(){var val=this.toAxisAngle();return[val[0].x,val[0].y,val[0].z,val[1]];};x3dom.fields.Quaternion.prototype.toString=function(){return this.x+" "+this.y+" "+this.z+", "+this.w;};x3dom.fields.Quaternion.prototype.setValueByStr=function(str){var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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=0;this.g=0;this.b=0;}
+else{this.r=r;this.g=g;this.b=b;}};x3dom.fields.SFColor.parse=function(str){try{var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.exec(str);return new x3dom.fields.SFColor(+m[1],+m[2],+m[3]);}
+catch(e){return x3dom.fields.SFColor.colorParse(str);}};x3dom.fields.SFColor.copy=function(that){return new x3dom.fields.SFColor(that.r,that.g,that.b);};x3dom.fields.SFColor.prototype.copy=function(){return x3dom.fields.SFColor.copy(this);};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 this.r+" "+this.g+" "+this.b;};x3dom.fields.SFColor.prototype.setValueByStr=function(str){try{var m=/^\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*,?\s*([+\-]?\d*\.*\d*[eE]?[+\-]?\d*?)\s*$/.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.SFColorRGBA=function(r,g,b,a){if(arguments.length===0){this.r=0;this.g=0;this.b=0;this.a=1;}
+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.copy=function(that){return new x3dom.fields.SFColorRGBA(that.r,that.g,that.b,that.a);};x3dom.fields.SFColorRGBA.prototype.copy=function(){return x3dom.fields.SFColorRGBA.copy(this);};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 this.r+" "+this.g+" "+this.b+" "+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.SFColorRGBA.prototype.toUint=function(){return((Math.round(this.r*255)<<24)|(Math.round(this.g*255)<<16)|(Math.round(this.b*255)<<8)|Math.round(this.a*255))>>>0;};x3dom.fields.SFColorRGBA.colorParse=function(color){var red=0,green=0,blue=0,alpha=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]+"ff";}
+if(color.substr&&color.substr(0,1)==="#"){color=color.substr(1);var len=color.length;if(len===8){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;alpha=parseInt("0x"+color.substr(6,2),16)/255.0;}
+else 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;alpha=1.0;}
+else if(len===4){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;alpha=parseInt("0x"+color.substr(3,1),16)/15.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;alpha=1.0;}}
+return new x3dom.fields.SFColorRGBA(red,green,blue,alpha);};x3dom.fields.SFImage=function(w,h,c,arr){if(arguments.length===0||!(arr&&arr.map)){this.width=0;this.height=0;this.comp=0;this.array=[];}
+else{this.width=w;this.height=h;this.comp=c;var that=this.array;arr.map(function(v){that.push(v);},this.array);}};x3dom.fields.SFImage.parse=function(str){var img=new x3dom.fields.SFImage();img.setValueByStr(str);return img;};x3dom.fields.SFImage.copy=function(that){var destination=new x3dom.fields.SFImage();destination.width=that.width;destination.height=that.height;destination.comp=that.comp;destination.setPixels(that.array);return destination;};x3dom.fields.SFImage.prototype.copy=function(){return x3dom.fields.SFImage.copy(this);};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++){var r,g,b,a;if(!mc[i].substr){continue;}
+if(mc[i].substr(1,1).toLowerCase()!=="x"){var inp=parseInt(mc[i],10);if(this.comp===1){r=inp;this.array.push(r);}
+else if(this.comp===2){r=inp>>8&255;g=inp&255;this.array.push(r,g);}
+else if(this.comp===3){r=inp>>16&255;g=inp>>8&255;b=inp&255;this.array.push(r,g,b);}
+else if(this.comp===4){r=inp>>24&255;g=inp>>16&255;b=inp>>8&255;a=inp&255;this.array.push(r,g,b,a);}}
+else if(mc[i].substr(1,1).toLowerCase()==="x"){mc[i]=mc[i].substr(2);len=mc[i].length;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.setPixel=function(x,y,color){var startIdx=(y*this.width+x)*this.comp;if(this.comp===1&&startIdx<this.array.length){this.array[startIdx]=color.r*255;}
+else if(this.comp===2&&(startIdx+1)<this.array.length){this.array[startIdx]=color.r*255;this.array[startIdx+1]=color.g*255;}
+else if(this.comp===3&&(startIdx+2)<this.array.length){this.array[startIdx]=color.r*255;this.array[startIdx+1]=color.g*255;this.array[startIdx+2]=color.b*255;}
+else if(this.comp===4&&(startIdx+3)<this.array.length){this.array[startIdx]=color.r*255;this.array[startIdx+1]=color.g*255;this.array[startIdx+2]=color.b*255;this.array[startIdx+3]=color.a*255;}};x3dom.fields.SFImage.prototype.getPixel=function(x,y){var startIdx=(y*this.width+x)*this.comp;if(this.comp===1&&startIdx<this.array.length){return new x3dom.fields.SFColorRGBA(this.array[startIdx]/255,0,0,1);}
+else if(this.comp===2&&(startIdx+1)<this.array.length){return new x3dom.fields.SFColorRGBA(this.array[startIdx]/255,this.array[startIdx+1]/255,0,1);}
+else if(this.comp===3&&(startIdx+2)<this.array.length){return new x3dom.fields.SFColorRGBA(this.array[startIdx]/255,this.array[startIdx+1]/255,this.array[startIdx+2]/255,1);}
+else if(this.comp===4&&(startIdx+3)<this.array.length){return new x3dom.fields.SFColorRGBA(this.array[startIdx]/255,this.array[startIdx+1]/255,this.array[startIdx+2]/255,this.array[startIdx+3]/255);}};x3dom.fields.SFImage.prototype.setPixels=function(pixels){var i,idx=0;if(this.comp===1){for(i=0;i<pixels.length;i++){this.array[idx++]=pixels[i].r*255;}}
+else if(this.comp===2){for(i=0;i<pixels.length;i++){this.array[idx++]=pixels[i].r*255;this.array[idx++]=pixels[i].g*255;}}
+else if(this.comp===3){for(i=0;i<pixels.length;i++){this.array[idx++]=pixels[i].r*255;this.array[idx++]=pixels[i].g*255;this.array[idx++]=pixels[i].b*255;}}
+else if(this.comp===4){for(i=0;i<pixels.length;i++){this.array[idx++]=pixels[i].r*255;this.array[idx++]=pixels[i].g*255;this.array[idx++]=pixels[i].b*255;this.array[idx++]=pixels[i].a*255;}}};x3dom.fields.SFImage.prototype.getPixels=function(){var i;var pixels=[];if(this.comp===1){for(i=0;i<this.array.length;i+=this.comp){pixels.push(new x3dom.fields.SFColorRGBA(this.array[i]/255,0,0,1));}}
+else if(this.comp===2){for(i=0;i<this.array.length;i+=this.comp){pixels.push(new x3dom.fields.SFColorRGBA(this.array[i]/255,this.array[i+1]/255,0,1));}}
+else if(this.comp===3){for(i=0;i<this.array.length;i+=this.comp){pixels.push(new x3dom.fields.SFColorRGBA(this.array[i]/255,this.array[i+1]/255,this.array[i+2]/255,1));}}
+else if(this.comp===4){for(i=0;i<this.array.length;i+=this.comp){pixels.push(new x3dom.fields.SFColorRGBA(this.array[i]/255,this.array[i+1]/255,this.array[i+2]/255,this.array[i+3]/255));}}
+return pixels;};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(colorArray){var that=this;colorArray.map(function(c){that.push(c);},this);}};x3dom.fields.MFColor.copy=function(colorArray){var destination=new x3dom.fields.MFColor();colorArray.map(function(v){destination.push(v.copy());},this);return destination;};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?mc.length:0;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.copy=function(){return x3dom.fields.MFColor.copy(this);};x3dom.fields.MFColor.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;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.MFColorRGBA=function(colorArray){if(colorArray){var that=this;colorArray.map(function(c){that.push(c);},this);}};x3dom.fields.MFColorRGBA.copy=function(colorArray){var destination=new x3dom.fields.MFColorRGBA();colorArray.map(function(v){destination.push(v.copy());},this);return destination;};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?mc.length:0;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.copy=function(){return x3dom.fields.MFColorRGBA.copy(this);};x3dom.fields.MFColorRGBA.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;i<n;i+=4){this.push(new x3dom.fields.SFColorRGBA(+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(rotArray){var that=this;rotArray.map(function(v){that.push(v);},this);}};x3dom.fields.MFRotation.prototype=x3dom.extend([]);x3dom.fields.MFRotation.copy=function(rotationArray){var destination=new x3dom.fields.MFRotation();rotationArray.map(function(v){destination.push(v.copy());},this);return destination;};x3dom.fields.MFRotation.prototype.copy=function(){return x3dom.fields.MFRotation.copy(this);};x3dom.fields.MFRotation.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc?mc.length:0;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){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;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=[];Array.map(this,function(c){var val=c.toAxisAngle();a.push(val[0].x);a.push(val[0].y);a.push(val[0].z);a.push(val[1]);});return a;};x3dom.fields.MFVec3f=function(vec3Array){if(vec3Array){var that=this;vec3Array.map(function(v){that.push(v);},this);}};x3dom.fields.MFVec3f.prototype=x3dom.extend([]);x3dom.fields.MFVec3f.copy=function(vec3Array){var destination=new x3dom.fields.MFVec3f();vec3Array.map(function(v){destination.push(v.copy());},this);return destination;};x3dom.fields.MFVec3f.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc?mc.length:0;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.copy=function()
+{x3dom.fields.MFVec3f.copy(this);};x3dom.fields.MFVec3f.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;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(vec2Array){var that=this;vec2Array.map(function(v){that.push(v);},this);}};x3dom.fields.MFVec2f.prototype=x3dom.extend([]);x3dom.fields.MFVec2f.copy=function(vec2Array){var destination=new x3dom.fields.MFVec2f();vec2Array.map(function(v){destination.push(v.copy());},this);return destination;};x3dom.fields.MFVec2f.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vecs=[];for(var i=0,n=mc?mc.length:0;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.copy=function(){return x3dom.fields.MFVec2f.copy(this);};x3dom.fields.MFVec2f.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;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(array){var that=this;array.map(function(v){that.push(v);},this);}};x3dom.fields.MFInt32.prototype=x3dom.extend([]);x3dom.fields.MFInt32.copy=function(intArray){var destination=new x3dom.fields.MFInt32();intArray.map(function(v){destination.push(v);},this);return destination;};x3dom.fields.MFInt32.parse=function(str){var mc=str.match(/([+\-]?\d+\s*){1},?\s*/g);var vals=[];for(var i=0,n=mc?mc.length:0;i<n;++i){vals.push(parseInt(mc[i],10));}
+return new x3dom.fields.MFInt32(vals);};x3dom.fields.MFInt32.prototype.copy=function(){return x3dom.fields.MFInt32.copy(this);};x3dom.fields.MFInt32.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-]?\d+\s*){1},?\s*/g);for(var i=0,n=mc?mc.length:0;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(array){var that=this;array.map(function(v){that.push(v);},this);}};x3dom.fields.MFFloat.prototype=x3dom.extend([]);x3dom.fields.MFFloat.copy=function(floatArray){var destination=new x3dom.fields.MFFloat();floatArray.map(function(v){destination.push(v);},this);return destination;};x3dom.fields.MFFloat.parse=function(str){var mc=str.match(/([+\-0-9eE\.]+)/g);var vals=[];for(var i=0,n=mc?mc.length:0;i<n;i++){vals.push(+mc[i]);}
+return new x3dom.fields.MFFloat(vals);};x3dom.fields.MFFloat.prototype.copy=function(){return x3dom.fields.MFFloat.copy(this);};x3dom.fields.MFFloat.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/([+\-0-9eE\.]+)/g);for(var i=0,n=mc?mc.length:0;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.MFBoolean=function(array){if(array){var that=this;array.map(function(v){that.push(v);},this);}};x3dom.fields.MFBoolean.prototype=x3dom.extend([]);x3dom.fields.MFBoolean.copy=function(boolArray){var destination=new x3dom.fields.MFBoolean();boolArray.map(function(v){destination.push(v);},this);return destination;};x3dom.fields.MFBoolean.parse=function(str){var mc=str.match(/(true|false|1|0)/ig);var vals=[];for(var i=0,n=mc?mc.length:0;i<n;i++){vals.push((mc[i]=='1'||mc[i].toLowerCase()=='true'));}
+return new x3dom.fields.MFBoolean(vals);};x3dom.fields.MFBoolean.prototype.copy=function(){return x3dom.fields.MFBoolean.copy(this);};x3dom.fields.MFBoolean.prototype.setValueByStr=function(str){this.length=0;var mc=str.match(/(true|false|1|0)/ig);for(var i=0,n=mc?mc.length:0;i<n;i++){this.push((mc[i]=='1'||mc[i].toLowerCase()=='true'));}};x3dom.fields.MFBoolean.prototype.toGL=function(){var a=[];Array.map(this,function(v){a.push(v?1:0);});return a;};x3dom.fields.MFString=function(strArray){if(strArray&&strArray.map){var that=this;strArray.map(function(v){that.push(v);},this);}};x3dom.fields.MFString.prototype=x3dom.extend([]);x3dom.fields.MFString.copy=function(stringArray){var destination=new x3dom.fields.MFString();stringArray.map(function(v){destination.push(v);},this);return destination;};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.copy=function(){return x3dom.fields.MFString.copy(this);};x3dom.fields.MFString.prototype.setValueByStr=function(str){this.length=0;if(str.length&&str[0]=='"'){var m,re=/"((?:[^\\"]|\\\\|\\")*)"/g;while((m=re.exec(str))){var s=m[1].replace(/\\([\\"])/,"$1");if(s!==undefined){this.push(s);}}}
+else{this.push(str);}
+return this;};x3dom.fields.MFString.prototype.toString=function(){var str="";for(var i=0,n=this.length;i<n;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);}
+this.pos=x3dom.fields.SFVec3f.copy(pos);this.dir=x3dom.fields.SFVec3f.copy(dir);};x3dom.fields.Line.prototype.closestPoint=function(p)
+{var distVec=p.subtract(this.pos);var projDist=distVec.dot(this.dir);return this.pos.add(this.dir.multiply(projDist));};x3dom.fields.Line.prototype.shortestDistance=function(p)
+{var distVec=p.subtract(this.pos);var projDist=distVec.dot(this.dir);return distVec.subtract(this.dir.multiply(projDist)).length();};x3dom.fields.Ray=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.Ray.prototype.toString=function(){return'Ray: ['+this.pos.toString()+'; '+this.dir.toString()+']';};x3dom.fields.Ray.prototype.intersectPlane=function(p,n)
+{var result=null;var alpha;var nDotDir=n.dot(this.dir);if(nDotDir<0.0)
+{alpha=(p.dot(n)-this.pos.dot(n))/nDotDir;result=this.pos.addScaled(this.dir,alpha);}
+return result;};x3dom.fields.Ray.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.fields.BoxVolume=function(min,max)
+{if(arguments.length<2){this.min=new x3dom.fields.SFVec3f(0,0,0);this.max=new x3dom.fields.SFVec3f(0,0,0);this.valid=false;}
+else{this.min=x3dom.fields.SFVec3f.copy(min);this.max=x3dom.fields.SFVec3f.copy(max);this.valid=true;}
+this.updateInternals();};x3dom.fields.BoxVolume.prototype.getScalarValue=function()
+{var extent=this.max.subtract(this.min);return(extent.x*extent.y*extent.z);};x3dom.fields.BoxVolume.copy=function(other)
+{return new x3dom.fields.BoxVolume(other.min,other.max);};x3dom.fields.BoxVolume.prototype.updateInternals=function()
+{this.radialVec=this.max.subtract(this.min).multiply(0.5);this.center=this.min.add(this.radialVec);this.diameter=2*this.radialVec.length();};x3dom.fields.BoxVolume.prototype.setBounds=function(min,max)
+{this.min.setValues(min);this.max.setValues(max);this.updateInternals();this.valid=true;};x3dom.fields.BoxVolume.prototype.setBoundsByCenterSize=function(center,size)
+{var halfSize=size.multiply(0.5);this.min=center.subtract(halfSize);this.max=center.add(halfSize);this.updateInternals();this.valid=true;};x3dom.fields.BoxVolume.prototype.extendBounds=function(min,max)
+{if(this.valid)
+{if(this.min.x>min.x){this.min.x=min.x;}
+if(this.min.y>min.y){this.min.y=min.y;}
+if(this.min.z>min.z){this.min.z=min.z;}
+if(this.max.x<max.x){this.max.x=max.x;}
+if(this.max.y<max.y){this.max.y=max.y;}
+if(this.max.z<max.z){this.max.z=max.z;}
+this.updateInternals();}
+else
+{this.setBounds(min,max);}};x3dom.fields.BoxVolume.prototype.getBounds=function(min,max)
+{min.setValues(this.min);max.setValues(this.max);};x3dom.fields.BoxVolume.prototype.getRadialVec=function()
+{return this.radialVec;};x3dom.fields.BoxVolume.prototype.invalidate=function()
+{this.valid=false;};x3dom.fields.BoxVolume.prototype.isValid=function()
+{return this.valid;};x3dom.fields.BoxVolume.prototype.getCenter=function()
+{return this.center;};x3dom.fields.BoxVolume.prototype.getDiameter=function()
+{return this.diameter;};x3dom.fields.BoxVolume.prototype.transform=function(m)
+{var xmin,ymin,zmin;var xmax,ymax,zmax;xmin=xmax=m._03;ymin=ymax=m._13;zmin=zmax=m._23;var a=this.max.x*m._00;var b=this.min.x*m._00;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=this.max.y*m._01;b=this.min.y*m._01;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=this.max.z*m._02;b=this.min.z*m._02;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=this.max.x*m._10;b=this.min.x*m._10;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=this.max.y*m._11;b=this.min.y*m._11;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=this.max.z*m._12;b=this.min.z*m._12;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=this.max.x*m._20;b=this.min.x*m._20;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+a=this.max.y*m._21;b=this.min.y*m._21;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+a=this.max.z*m._22;b=this.min.z*m._22;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+this.min.x=xmin;this.min.y=ymin;this.min.z=zmin;this.max.x=xmax;this.max.y=ymax;this.max.z=zmax;this.updateInternals();};x3dom.fields.BoxVolume.prototype.transformFrom=function(m,other)
+{var xmin,ymin,zmin;var xmax,ymax,zmax;xmin=xmax=m._03;ymin=ymax=m._13;zmin=zmax=m._23;var a=other.max.x*m._00;var b=other.min.x*m._00;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=other.max.y*m._01;b=other.min.y*m._01;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=other.max.z*m._02;b=other.min.z*m._02;if(a>=b){xmax+=a;xmin+=b;}
+else{xmax+=b;xmin+=a;}
+a=other.max.x*m._10;b=other.min.x*m._10;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=other.max.y*m._11;b=other.min.y*m._11;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=other.max.z*m._12;b=other.min.z*m._12;if(a>=b){ymax+=a;ymin+=b;}
+else{ymax+=b;ymin+=a;}
+a=other.max.x*m._20;b=other.min.x*m._20;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+a=other.max.y*m._21;b=other.min.y*m._21;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+a=other.max.z*m._22;b=other.min.z*m._22;if(a>=b){zmax+=a;zmin+=b;}
+else{zmax+=b;zmin+=a;}
+this.min.x=xmin;this.min.y=ymin;this.min.z=zmin;this.max.x=xmax;this.max.y=ymax;this.max.z=zmax;this.updateInternals();this.valid=true;};x3dom.fields.FrustumVolume=function(clipMat)
+{this.planeNormals=[];this.planeDistances=[];this.directionIndex=[];if(arguments.length===0){return;}
+var planeEquation=[];for(var i=0;i<6;i++){this.planeNormals[i]=new x3dom.fields.SFVec3f(0,0,0);this.planeDistances[i]=0;this.directionIndex[i]=0;planeEquation[i]=new x3dom.fields.SFVec4f(0,0,0,0);}
+planeEquation[0].x=clipMat._30-clipMat._00;planeEquation[0].y=clipMat._31-clipMat._01;planeEquation[0].z=clipMat._32-clipMat._02;planeEquation[0].w=clipMat._33-clipMat._03;planeEquation[1].x=clipMat._30+clipMat._00;planeEquation[1].y=clipMat._31+clipMat._01;planeEquation[1].z=clipMat._32+clipMat._02;planeEquation[1].w=clipMat._33+clipMat._03;planeEquation[2].x=clipMat._30+clipMat._10;planeEquation[2].y=clipMat._31+clipMat._11;planeEquation[2].z=clipMat._32+clipMat._12;planeEquation[2].w=clipMat._33+clipMat._13;planeEquation[3].x=clipMat._30-clipMat._10;planeEquation[3].y=clipMat._31-clipMat._11;planeEquation[3].z=clipMat._32-clipMat._12;planeEquation[3].w=clipMat._33-clipMat._13;planeEquation[4].x=clipMat._30+clipMat._20;planeEquation[4].y=clipMat._31+clipMat._21;planeEquation[4].z=clipMat._32+clipMat._22;planeEquation[4].w=clipMat._33+clipMat._23;planeEquation[5].x=clipMat._30-clipMat._20;planeEquation[5].y=clipMat._31-clipMat._21;planeEquation[5].z=clipMat._32-clipMat._22;planeEquation[5].w=clipMat._33-clipMat._23;for(i=0;i<6;i++){var vectorLength=Math.sqrt(planeEquation[i].x*planeEquation[i].x+
+planeEquation[i].y*planeEquation[i].y+
+planeEquation[i].z*planeEquation[i].z);planeEquation[i].x/=vectorLength;planeEquation[i].y/=vectorLength;planeEquation[i].z/=vectorLength;planeEquation[i].w/=-vectorLength;}
+var updateDirectionIndex=function(normalVec){var ind=0;if(normalVec.x>0)ind|=1;if(normalVec.y>0)ind|=2;if(normalVec.z>0)ind|=4;return ind;};this.planeNormals[3].setValues(planeEquation[0]);this.planeDistances[3]=planeEquation[0].w;this.directionIndex[3]=updateDirectionIndex(this.planeNormals[3]);this.planeNormals[2].setValues(planeEquation[1]);this.planeDistances[2]=planeEquation[1].w;this.directionIndex[2]=updateDirectionIndex(this.planeNormals[2]);this.planeNormals[5].setValues(planeEquation[2]);this.planeDistances[5]=planeEquation[2].w;this.directionIndex[5]=updateDirectionIndex(this.planeNormals[5]);this.planeNormals[4].setValues(planeEquation[3]);this.planeDistances[4]=planeEquation[3].w;this.directionIndex[4]=updateDirectionIndex(this.planeNormals[4]);this.planeNormals[0].setValues(planeEquation[4]);this.planeDistances[0]=planeEquation[4].w;this.directionIndex[0]=updateDirectionIndex(this.planeNormals[0]);this.planeNormals[1].setValues(planeEquation[5]);this.planeDistances[1]=planeEquation[5].w;this.directionIndex[1]=updateDirectionIndex(this.planeNormals[1]);};x3dom.fields.FrustumVolume.prototype.intersect=function(vol,planeMask)
+{if(this.planeNormals.length<6){x3dom.debug.logWarning("FrustumVolume not initialized!");return false;}
+var that=this;var min=vol.min,max=vol.max;var setDirectionIndexPoint=function(index){var pnt=new x3dom.fields.SFVec3f(0,0,0);if(index&1){pnt.x=min.x;}
+else{pnt.x=max.x;}
+if(index&2){pnt.y=min.y;}
+else{pnt.y=max.y;}
+if(index&4){pnt.z=min.z;}
+else{pnt.z=max.z;}
+return pnt;};var pntIsInHalfSpace=function(i,pnt){var s=that.planeNormals[i].dot(pnt)-that.planeDistances[i];return(s>=0);};var isInHalfSpace=function(i){var p=setDirectionIndexPoint(that.directionIndex[i]);return pntIsInHalfSpace(i,p);};var isOutHalfSpace=function(i){var p=setDirectionIndexPoint(that.directionIndex[i]^7);return!pntIsInHalfSpace(i,p);};var mask=1;if(planeMask<0)planeMask=0;for(var i=0;i<6;i++,mask<<=1){if((planeMask&mask)!=0)
+continue;if(isOutHalfSpace(i))
+return-1;if(isInHalfSpace(i))
+planeMask|=mask;}
+return planeMask;};x3dom.docs={};x3dom.docs.specURLMap={CADGeometry:"CADGeometry.html",Core:"core.html",DIS:"dis.html",CubeMapTexturing:"env_texture.html",EnvironmentalEffects:"enveffects.html",EnvironmentalSensor:"envsensor.html",Followers:"followers.html",Geospatial:"geodata.html",Geometry2D:"geometry2D.html",Geometry3D:"geometry3D.html",Grouping:"group.html","H-Anim":"hanim.html",Interpolation:"interp.html",KeyDeviceSensor:"keyboard.html",Layering:"layering.html",Layout:"layout.html",Lighting:"lighting.html",Navigation:"navigation.html",Networking:"networking.html",NURBS:"nurbs.html",ParticleSystems:"particle_systems.html",Picking:"picking.html",PointingDeviceSensor:"pointingsensor.html",Rendering:"rendering.html",RigidBodyPhysics:"rigid_physics.html",Scripting:"scripting.html",Shaders:"shaders.html",Shape:"shape.html",Sound:"sound.html",Text:"text.html",Texturing3D:"texture3D.html",Texturing:"texturing.html",Time:"time.html",EventUtilities:"utils.html",VolumeRendering:"volume.html"};x3dom.docs.specBaseURL="http://www.web3d.org/x3d/specifications/ISO-IEC-19775-1.2-X3D-AbstractSpecification/Part01/components/";x3dom.docs.getNodeTreeInfo=function(){var tn,t;var types="";var objInArray=function(array,obj){for(var i=0;i<array.length;i++){if(array[i]===obj){return true;}}
+return false;};var dump=function(t,indent){for(var i=0;i<indent;i++){types+="&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";}
+types+="<a href='"+
+x3dom.docs.specBaseURL+x3dom.docs.specURLMap[x3dom.nodeTypes[t]._compName]+"#"+t+"' style='color:black; text-decoration:none; font-weight:bold;'>"+
+t+"</a> &nbsp; <a href='"+
+x3dom.docs.specBaseURL+x3dom.docs.specURLMap[x3dom.nodeTypes[t]._compName]+"' style='color:black; text-decoration:none; font-style:italic;'>"+
+x3dom.nodeTypes[t]._compName+"</a><br/>";for(var i in x3dom.nodeTypes[t].childTypes[t]){dump(x3dom.nodeTypes[t].childTypes[t][i],indent+1);}};for(tn in x3dom.nodeTypes){var t=x3dom.nodeTypes[tn];if(t.childTypes===undefined){t.childTypes={};}
+while(t.superClass){if(t.superClass.childTypes[t.superClass._typeName]===undefined){t.superClass.childTypes[t.superClass._typeName]=[];}
+if(!objInArray(t.superClass.childTypes[t.superClass._typeName],t._typeName)){t.superClass.childTypes[t.superClass._typeName].push(t._typeName);}
+t=t.superClass;}}
+dump("X3DNode",0);return"<div class='x3dom-doc-nodes-tree'>"+types+"</div>";};x3dom.docs.getComponentInfo=function(){var components=[];var component;var result="";var c,cn;for(c in x3dom.components){components.push(c);}
+components.sort();for(cn in components){c=components[cn];component=x3dom.components[c];result+="<h2><a href='"+
+x3dom.docs.specBaseURL+x3dom.docs.specURLMap[c]+"' style='color:black; text-decoration:none; font-style:italic;'>"+
+c+"</a></h2>";result+="<ul style='list-style-type:circle;'>";for(var t in component){result+="<li><a href='"+
+x3dom.docs.specBaseURL+x3dom.docs.specURLMap[c]+"#"+t+"' style='color:black; text-decoration:none; font-weight:bold;'>"+
+t+"</a></li>";}
+result+="</ul>";}
+return result;};x3dom.shader={};x3dom.shader.PICKING="picking";x3dom.shader.PICKING_24="picking24";x3dom.shader.PICKING_ID="pickingId";x3dom.shader.PICKING_COLOR="pickingColor";x3dom.shader.PICKING_TEXCOORD="pickingTexCoord";x3dom.shader.FRONTGROUND_TEXTURE="frontgroundTexture";x3dom.shader.BACKGROUND_TEXTURE="backgroundTexture";x3dom.shader.BACKGROUND_SKYTEXTURE="backgroundSkyTexture";x3dom.shader.BACKGROUND_CUBETEXTURE="backgroundCubeTexture";x3dom.shader.SHADOW="shadow";x3dom.shader.BLUR="blur";x3dom.shader.DEPTH="depth";x3dom.shader.NORMAL="normal";x3dom.shader.TEXTURE_REFINEMENT="textureRefinement";x3dom.shader.material=function(){var shaderPart="uniform vec3  diffuseColor;\n"+"uniform vec3  specularColor;\n"+"uniform vec3  emissiveColor;\n"+"uniform float shininess;\n"+"uniform float transparency;\n"+"uniform float ambientIntensity;\n";return shaderPart;};x3dom.shader.fog=function(){var shaderPart="uniform vec3  fogColor;\n"+"uniform float fogType;\n"+"uniform float fogRange;\n"+"varying vec3 fragEyePosition;\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"+"}\n";return shaderPart;};x3dom.shader.gammaCorrectionDecl=function(properties){var shaderPart="";if(properties.GAMMACORRECTION==="none"){}else if(properties.GAMMACORRECTION==="fastlinear"){shaderPart+="vec4 gammaEncode(vec4 color){\n"+"  vec4 tmp = sqrt(color);\n"+"  return vec4(tmp.rgb, color.a);\n"+"}\n";shaderPart+="vec4 gammaDecode(vec4 color){\n"+"  vec4 tmp = color * color;\n"+"  return vec4(tmp.rgb, color.a);\n"+"}\n";shaderPart+="vec3 gammaEncode(vec3 color){\n"+"  return sqrt(color);\n"+"}\n";shaderPart+="vec3 gammaDecode(vec3 color){\n"+"  return (color * color);\n"+"}\n";}else{shaderPart+="const vec4 gammaEncode4Vector = vec4(0.4545454545454545, 0.4545454545454545, 0.4545454545454545, 1.0);\n";shaderPart+="const vec4 gammaDecode4Vector = vec4(2.2, 2.2, 2.2, 1.0);\n";shaderPart+="vec4 gammaEncode(vec4 color){\n"+"    return pow(color, gammaEncode4Vector);\n"+"}\n";shaderPart+="vec4 gammaDecode(vec4 color){\n"+"    return pow(color, gammaDecode4Vector);\n"+"}\n";shaderPart+="const vec3 gammaEncode3Vector = vec3(0.4545454545454545, 0.4545454545454545, 0.4545454545454545);\n";shaderPart+="const vec3 gammaDecode3Vector = vec3(2.2, 2.2, 2.2);\n";shaderPart+="vec3 gammaEncode(vec3 color){\n"+"    return pow(color, gammaEncode3Vector);\n"+"}\n";shaderPart+="vec3 gammaDecode(vec3 color){\n"+"    return pow(color, gammaDecode3Vector);\n"+"}\n";}
+return shaderPart;};x3dom.shader.encodeGamma=function(properties,expr){if(properties.GAMMACORRECTION==="none"){return expr;}else{return"gammaEncode ("+expr+")";}};x3dom.shader.decodeGamma=function(properties,expr){if(properties.GAMMACORRECTION==="none"){return expr;}else{return"gammaDecode ("+expr+")";}};x3dom.shader.rgbaPacking=function(){var shaderPart="";shaderPart+="vec4 packDepth(float depth){\n"+" depth = (depth + 1.0)*0.5;\n"+" vec4 outVal = vec4(1.0, 255.0, 65025.0, 160581375.0) * depth;\n"+" outVal = fract(outVal);\n"+"   outVal -= outVal.yzww * vec4(1.0/255.0, 1.0/255.0, 1.0/255.0, 0.0);\n"+"   return outVal;\n"+"}\n";shaderPart+="float unpackDepth(vec4 color){\n"+" float depth = dot(color, vec4(1.0, 1.0/255.0, 1.0/65025.0, 1.0/160581375.0));\n"+" return (2.0*depth - 1.0);\n"+"}\n";return shaderPart;};x3dom.shader.shadowRendering=function(){var shaderPart="";shaderPart+="float getLightInfluence(float lType, float lShadowIntensity, float lOn, vec3 lLocation, vec3 lDirection, "+"float lCutOffAngle, float lBeamWidth, vec3 lAttenuation, float lRadius, vec3 eyeCoords) {\n"+" if (lOn == 0.0 || lShadowIntensity == 0.0){ return 0.0;\n"+" } else if (lType == 0.0) {\n"+"  return 1.0;\n"+" } else {\n"+"    float attenuation = 0.0;\n"+"    vec3 lightVec = (lLocation - (eyeCoords));\n"+"    float distance = length(lightVec);\n"+"  lightVec = normalize(lightVec);\n"+"  eyeCoords = normalize(-eyeCoords);\n"+"    if(lRadius == 0.0 || distance <= lRadius) {\n"+"        attenuation = 1.0 / max(lAttenuation.x + lAttenuation.y * distance + lAttenuation.z * (distance * distance), 1.0);\n"+"  }\n"+"   if (lType == 1.0) return attenuation;\n"+"    float spotAngle = acos(max(0.0, dot(-lightVec, normalize(lDirection))));\n"+"    if(spotAngle >= lCutOffAngle) return 0.0;\n"+"    else if(spotAngle <= lBeamWidth) return attenuation;\n"+"    else return attenuation * (spotAngle - lCutOffAngle) / (lBeamWidth - lCutOffAngle);\n"+" }\n"+"}\n";shaderPart+="void getShadowValues(inout vec4 shadowMapValues, inout float viewSampleDepth, in mat4 lightMatrix, in vec4 worldCoords, in sampler2D shadowMap){\n"+" vec4 lightSpaceCoords = lightMatrix*worldCoords;\n"+" vec3 lightSpaceCoordsCart = lightSpaceCoords.xyz / lightSpaceCoords.w;\n"+" vec2 textureCoords = (lightSpaceCoordsCart.xy + 1.0)*0.5;\n"+" viewSampleDepth = lightSpaceCoordsCart.z;\n"+" shadowMapValues = texture2D(shadowMap, textureCoords);\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE)
+shaderPart+=" shadowMapValues = vec4(1.0,1.0,unpackDepth(shadowMapValues),1.0);\n";shaderPart+="}\n";shaderPart+="void getShadowValuesPointLight(inout vec4 shadowMapValues, inout float viewSampleDepth, in vec3 lLocation, in vec4 worldCoords, in mat4 lightViewMatrix,"+"in mat4 lMatrix_0, in mat4 lMatrix_1, in mat4 lMatrix_2, in mat4 lMatrix_3, in mat4 lMatrix_4, in mat4 lMatrix_5,"+"in sampler2D shadowMap_0, in sampler2D shadowMap_1, in sampler2D shadowMap_2, in sampler2D shadowMap_3,"+"in sampler2D shadowMap_4, in sampler2D shadowMap_5){\n"+" vec4 transformed = lightViewMatrix * worldCoords;\n"+" vec3 lightVec = normalize(transformed.xyz/transformed.w);\n"+" vec3 lightVecAbs = abs(lightVec);\n"+" float maximum = max(max(lightVecAbs.x, lightVecAbs.y),lightVecAbs.z);\n"+" if (lightVecAbs.x == maximum) {\n"+"  if (lightVec.x < 0.0) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_3,worldCoords,shadowMap_3);\n"+"  else getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_1,worldCoords,shadowMap_1);\n"+" }\n"+" else if (lightVecAbs.y == maximum) {\n"+"  if (lightVec.y < 0.0) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_4,worldCoords,shadowMap_4);\n"+"  else getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_5,worldCoords,shadowMap_5);\n"+" }\n"+" else if (lightVec.z < 0.0) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_0,worldCoords,shadowMap_0);\n"+" else getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_2,worldCoords,shadowMap_2);\n"+"}\n";shaderPart+="void getShadowValuesCascaded(inout vec4 shadowMapValues, inout float viewSampleDepth, in vec4 worldCoords, in float eyeDepth, in mat4 lMatrix_0, in mat4 lMatrix_1, in mat4 lMatrix_2,"+"in mat4 lMatrix_3, in mat4 lMatrix_4, in mat4 lMatrix_5, in sampler2D shadowMap_0, in sampler2D shadowMap_1, in sampler2D shadowMap_2,"+"in sampler2D shadowMap_3, in sampler2D shadowMap_4, in sampler2D shadowMap_5, in float split_0, in float split_1, in float split_2, in float split_3, in float split_4){\n"+" if (eyeDepth < split_0) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_0, worldCoords, shadowMap_0);\n"+" else if (eyeDepth < split_1) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_1, worldCoords, shadowMap_1);\n"+" else if (eyeDepth < split_2) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_2, worldCoords, shadowMap_2);\n"+" else if (eyeDepth < split_3) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_3, worldCoords, shadowMap_3);\n"+" else if (eyeDepth < split_4) getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_4, worldCoords, shadowMap_4);\n"+" else getShadowValues(shadowMapValues, viewSampleDepth, lMatrix_5, worldCoords, shadowMap_5);\n"+"}\n";shaderPart+="float ESM(float shadowMapDepth, float viewSampleDepth, float offset){\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE)
+shaderPart+=" return exp(-80.0*(1.0-offset)*(viewSampleDepth - shadowMapDepth));\n";else shaderPart+=" return shadowMapDepth * exp(-80.0*(1.0-offset)*viewSampleDepth);\n";shaderPart+="}\n";shaderPart+="float VSM(vec2 moments, float viewSampleDepth, float offset){\n"+" viewSampleDepth = (viewSampleDepth + 1.0) * 0.5;\n"+" if (viewSampleDepth <= moments.x) return 1.0;\n"+" float variance = moments.y - moments.x * moments.x;\n"+" variance = max(variance, 0.00002 + offset*0.01);\n"+" float d = viewSampleDepth - moments.x;\n"+" return variance/(variance + d*d);\n"+"}\n";return shaderPart;};x3dom.shader.light=function(numLights){var shaderPart="";for(var l=0;l<numLights;l++){shaderPart+="uniform float light"+l+"_On;\n"+"uniform float light"+l+"_Type;\n"+"uniform vec3  light"+l+"_Location;\n"+"uniform vec3  light"+l+"_Direction;\n"+"uniform vec3  light"+l+"_Color;\n"+"uniform vec3  light"+l+"_Attenuation;\n"+"uniform float light"+l+"_Radius;\n"+"uniform float light"+l+"_Intensity;\n"+"uniform float light"+l+"_AmbientIntensity;\n"+"uniform float light"+l+"_BeamWidth;\n"+"uniform float light"+l+"_CutOffAngle;\n"+"uniform float light"+l+"_ShadowIntensity;\n";}
+shaderPart+="vec3 lighting(in float lType, in vec3 lLocation, in vec3 lDirection, in vec3 lColor, in vec3 lAttenuation, "+"in float lRadius, in float lIntensity, in float lAmbientIntensity, in float lBeamWidth, "+"in float lCutOffAngle, in vec3 N, in vec3 V, float shin)\n"+"{\n"+"   vec3 L;\n"+"   float spot = 1.0, attentuation = 0.0;\n"+"   if(lType == 0.0) {\n"+"       L = -normalize(lDirection);\n"+"  V = normalize(V);\n"+"  attentuation = 1.0;\n"+"   } else{\n"+"       L = (lLocation - (-V));\n"+"       float d = length(L);\n"+"  L = normalize(L);\n"+"  V = normalize(V);\n"+"       if(lRadius == 0.0 || d <= lRadius) {\n"+"        attentuation = 1.0 / max(lAttenuation.x + lAttenuation.y * d + lAttenuation.z * (d * d), 1.0);\n"+"  }\n"+"       if(lType == 2.0) {\n"+"           float spotAngle = acos(max(0.0, dot(-L, normalize(lDirection))));\n"+"           if(spotAngle >= lCutOffAngle) spot = 0.0;\n"+"           else if(spotAngle <= lBeamWidth) spot = 1.0;\n"+"           else spot = (spotAngle - lCutOffAngle ) / (lBeamWidth - lCutOffAngle);\n"+"       }\n"+"   }\n"+"   vec3  H = normalize( L + V );\n"+"   float NdotL = clamp(dot(L, N), 0.0, 1.0);\n"+"   float NdotH = clamp(dot(H, N), 0.0, 1.0);\n"+"   float ambientFactor  = lAmbientIntensity * ambientIntensity;\n"+"   float diffuseFactor  = lIntensity * NdotL;\n"+"   float specularFactor = lIntensity * pow(NdotH, shin*128.0);\n"+"   return vec3(ambientFactor, diffuseFactor, specularFactor) * attentuation * spot;\n"+"}\n";return shaderPart;};x3dom.shader.TBNCalculation=function(){var shaderPart="";shaderPart+="mat3 cotangent_frame(vec3 N, vec3 p, vec2 uv)\n"+"{\n"+"    // get edge vectors of the pixel triangle\n"+"    vec3 dp1 = dFdx( p );\n"+"    vec3 dp2 = dFdy( p );\n"+"    vec2 duv1 = dFdx( uv );\n"+"    vec2 duv2 = dFdy( uv );\n"+"\n"+"    // solve the linear system\n"+"    vec3 dp2perp = cross( dp2, N );\n"+"    vec3 dp1perp = cross( N, dp1 );\n"+"    vec3 T = dp2perp * duv1.x + dp1perp * duv2.x;\n"+"    vec3 B = dp2perp * duv1.y + dp1perp * duv2.y;\n"+"\n"+"    // construct a scale-invariant frame\n"+"    float invmax = inversesqrt( max( dot(T,T), dot(B,B) ) );\n"+"    return mat3( T * invmax, B * invmax, N );\n"+"}\n\n";shaderPart+="vec3 perturb_normal( vec3 N, vec3 V, vec2 texcoord )\n"+"{\n"+"    // assume N, the interpolated vertex normal and\n"+"    // V, the view vector (vertex to eye)\n"+"    vec3 map = texture2D(normalMap, texcoord ).xyz;\n"+"    map = map * 255./127. - 128./127.;\n"+"    mat3 TBN = cotangent_frame(N, -V, texcoord);\n"+"    return normalize(TBN * map);\n"+"}\n\n";return shaderPart;};x3dom.shader.DynamicShader=function(gl,properties)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl,properties);var fragmentShader=this.generateFragmentShader(gl,properties);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.DynamicShader.prototype.generateVertexShader=function(gl,properties)
+{var shader="";shader+="uniform mat4 modelViewMatrix;\n";shader+="uniform mat4 modelViewProjectionMatrix;\n";if(properties.POSCOMPONENTS==3){shader+="attribute vec3 position;\n";}else if(properties.POSCOMPONENTS==4){shader+="attribute vec4 position;\n";}
+if(properties.IMAGEGEOMETRY){shader+="uniform vec3 IG_bboxMin;\n";shader+="uniform vec3 IG_bboxMax;\n";shader+="uniform float IG_coordTextureWidth;\n";shader+="uniform float IG_coordTextureHeight;\n";shader+="uniform vec2 IG_implicitMeshSize;\n";for(var i=0;i<properties.IG_PRECISION;i++){shader+="uniform sampler2D IG_coords"+i+"\n;";}
+if(properties.IG_INDEXED){shader+="uniform sampler2D IG_index;\n";shader+="uniform float IG_indexTextureWidth;\n";shader+="uniform float IG_indexTextureHeight;\n";}}
+if(properties.POPGEOMETRY){shader+="uniform float PG_precisionLevel;\n";shader+="uniform float PG_powPrecision;\n";shader+="uniform vec3 PG_maxBBSize;\n";shader+="uniform vec3 PG_bbMin;\n";shader+="uniform vec3 PG_bbMaxModF;\n";shader+="uniform vec3 PG_bboxShiftVec;\n";shader+="uniform float PG_numAnchorVertices;\n";shader+="attribute float PG_vertexID;\n";}
+if(properties.LIGHTS){shader+="varying vec3 fragNormal;\n";shader+="uniform mat4 normalMatrix;\n";if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_normals;\n";}else{if(properties.NORCOMPONENTS==2){if(properties.POSCOMPONENTS!=4){shader+="attribute vec2 normal;\n";}}else if(properties.NORCOMPONENTS==3){shader+="attribute vec3 normal;\n";}}}
+if(properties.VERTEXCOLOR){if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_colors;\n";if(properties.COLCOMPONENTS==3){shader+="varying vec3 fragColor;\n";}else if(properties.COLCOMPONENTS==4){shader+="varying vec4 fragColor;\n";}}else{if(properties.COLCOMPONENTS==3){shader+="attribute vec3 color;\n";shader+="varying vec3 fragColor;\n";}else if(properties.COLCOMPONENTS==4){shader+="attribute vec4 color;\n";shader+="varying vec4 fragColor;\n";}}}
+if(properties.TEXTURED||properties.CSSHADER){shader+="varying vec2 fragTexcoord;\n";if(!properties.SPHEREMAPPING){if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_texCoords;\n";}else{shader+="attribute vec2 texcoord;\n";}}
+if(properties.TEXTRAFO){shader+="uniform mat4 texTrafoMatrix;\n";}
+if(properties.NORMALMAP&&!x3dom.caps.STD_DERIVATIVES){x3dom.debug.logWarning("Your System doesn't support the 'OES_STANDARD_DERIVATIVES' Extension. "+"You must set tangents and binormals manually via the FloatVertexAttribute-Node "+"to use normal maps");shader+="attribute vec3 tangent;\n";shader+="attribute vec3 binormal;\n";shader+="varying vec3 fragTangent;\n";shader+="varying vec3 fragBinormal;\n";}
+if(properties.CUBEMAP){shader+="varying vec3 fragViewDir;\n";shader+="uniform mat4 viewMatrix;\n";}
+if(properties.DISPLACEMENTMAP){shader+="uniform sampler2D displacementMap;\n";shader+="uniform float displacementFactor;\n";shader+="uniform float displacementWidth;\n";shader+="uniform float displacementHeight;\n";shader+="uniform float displacementAxis;\n";}
+if(properties.DIFFPLACEMENTMAP){shader+="uniform sampler2D diffuseDisplacementMap;\n";shader+="uniform float displacementFactor;\n";shader+="uniform float displacementWidth;\n";shader+="uniform float displacementHeight;\n";shader+="uniform float displacementAxis;\n";}
+if(properties.MULTIDIFFALPMAP||properties.MULTIVISMAP){shader+="attribute float id;\n";shader+="varying float fragID;\n";}}
+if(properties.LIGHTS||properties.FOG){shader+="uniform vec3 eyePosition;\n";shader+="varying vec3 fragPosition;\n";if(properties.FOG){shader+="varying vec3 fragEyePosition;\n";}}
+if(properties.REQUIREBBOX){shader+="uniform vec3 bgCenter;\n";shader+="uniform vec3 bgSize;\n";shader+="uniform float bgPrecisionMax;\n";}
+if(properties.REQUIREBBOXNOR){shader+="uniform float bgPrecisionNorMax;\n";}
+if(properties.REQUIREBBOXCOL){shader+="uniform float bgPrecisionColMax;\n";}
+if(properties.REQUIREBBOXTEX){shader+="uniform float bgPrecisionTexMax;\n";}
+shader+="void main(void) {\n";shader+="gl_PointSize = 2.0;\n";if(properties.IMAGEGEOMETRY){if(properties.IG_INDEXED){shader+="vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);\n";shader+="vec2 IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_indexTextureWidth), position.y*(IG_implicitMeshSize.y/IG_indexTextureHeight)) + halfPixel;\n";shader+="vec2 IG_indices = texture2D( IG_index, IG_texCoord ).rg;\n";shader+="halfPixel = vec2(0.5/IG_coordTextureWidth,0.5/IG_coordTextureHeight);\n";shader+="IG_texCoord = (IG_indices * 0.996108948) + halfPixel;\n";}else{shader+="vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);\n";shader+="vec2 IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_coordTextureWidth), position.y*(IG_implicitMeshSize.y/IG_coordTextureHeight)) + halfPixel;\n";}
+shader+="vec3 temp = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 vertPosition = vec3(0.0, 0.0, 0.0);\n";for(var i=0;i<properties.IG_PRECISION;i++){shader+="temp = 255.0 * texture2D( IG_coords"+i+", IG_texCoord ).rgb;\n";shader+="vertPosition *= 256.0;\n";shader+="vertPosition += temp;\n";}
+shader+="vertPosition /= (pow(2.0, 8.0 * "+properties.IG_PRECISION+".0) - 1.0);\n";shader+="vertPosition = vertPosition * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;\n";if(properties.LIGHTS){shader+="vec3 vertNormal = texture2D( IG_normals, IG_texCoord ).rgb;\n";shader+="vertNormal = vertNormal * 2.0 - 1.0;\n";}
+if(properties.VERTEXCOLOR){if(properties.COLCOMPONENTS==3){shader+="fragColor = texture2D( IG_colors, IG_texCoord ).rgb;\n";}else if(properties.COLCOMPONENTS==4){shader+="fragColor = texture2D( IG_colors, IG_texCoord ).rgba;\n";}}
+if(properties.TEXTURED||properties.CSSHADER){shader+="vec4 IG_doubleTexCoords = texture2D( IG_texCoords, IG_texCoord );\n";shader+="vec2 vertTexCoord;";shader+="vertTexCoord.r = (IG_doubleTexCoords.r * 0.996108948) + (IG_doubleTexCoords.b * 0.003891051);\n";shader+="vertTexCoord.g = (IG_doubleTexCoords.g * 0.996108948) + (IG_doubleTexCoords.a * 0.003891051);\n";}}else{shader+="vec3 vertPosition = position.xyz;\n";if(properties.POPGEOMETRY){shader+="vec3 offsetVec = step(vertPosition / bgPrecisionMax, PG_bbMaxModF) * PG_bboxShiftVec;\n";shader+="if ((PG_precisionLevel <= 2.0) || PG_vertexID >= PG_numAnchorVertices) {\n";shader+="   vertPosition = floor(vertPosition / PG_powPrecision) * PG_powPrecision;\n";shader+="   vertPosition /= (65536.0 - PG_powPrecision);\n";shader+="}\n";shader+="else {\n";shader+="   vertPosition /= bgPrecisionMax;\n";shader+="}\n";shader+="vertPosition = (vertPosition + offsetVec + PG_bbMin) * PG_maxBBSize;\n";}
+else if(properties.REQUIREBBOX){shader+="vertPosition = bgCenter + bgSize * vertPosition / bgPrecisionMax;\n";}
+if(properties.LIGHTS){if(properties.NORCOMPONENTS==2){if(properties.POSCOMPONENTS==4){shader+="vec3 vertNormal = vec3(position.w / 256.0); \n";shader+="vertNormal.x = floor(vertNormal.x) / 255.0; \n";shader+="vertNormal.y = fract(vertNormal.y) * 1.00392156862745; \n";}
+else if(properties.REQUIREBBOXNOR){shader+="vec3 vertNormal = vec3(normal.xy, 0.0) / bgPrecisionNorMax;\n";}
+shader+="vec2 thetaPhi = 3.14159265358979 * vec2(vertNormal.x, vertNormal.y*2.0-1.0); \n";shader+="vec4 sinCosThetaPhi = sin( vec4(thetaPhi, thetaPhi + 1.5707963267949) ); \n";shader+="vertNormal.x = sinCosThetaPhi.x * sinCosThetaPhi.w; \n";shader+="vertNormal.y = sinCosThetaPhi.x * sinCosThetaPhi.y; \n";shader+="vertNormal.z = sinCosThetaPhi.z; \n";}else{shader+="vec3 vertNormal = normal;\n";if(properties.REQUIREBBOXNOR){shader+="vertNormal = vertNormal / bgPrecisionNorMax;\n";}
+if(properties.POPGEOMETRY){shader+="vertNormal = 2.0*vertNormal - 1.0;\n";}}}
+if(properties.VERTEXCOLOR){shader+="fragColor = color;\n";if(properties.REQUIREBBOXCOL){shader+="fragColor = fragColor / bgPrecisionColMax;\n";}}
+if((properties.TEXTURED||properties.CSSHADER)&&!properties.SPHEREMAPPING){shader+="vec2 vertTexCoord = texcoord;\n";if(properties.REQUIREBBOXTEX){shader+="vertTexCoord = vertTexCoord / bgPrecisionTexMax;\n";}}}
+if(properties.LIGHTS){if(properties.DISPLACEMENTMAP||properties.DIFFPLACEMENTMAP&&!properties.NORMALMAP){shader+="float dx = 1.0 / displacementWidth;\n";shader+="float dy = 1.0 / displacementHeight;\n";if(properties.DISPLACEMENTMAP)
+{shader+="float s1 = texture2D(displacementMap, vec2(vertTexCoord.x - dx, 1.0 - vertTexCoord.y)).r;\n";shader+="float s2 = texture2D(displacementMap, vec2(vertTexCoord.x, 1.0 - vertTexCoord.y - dy)).r;\n";shader+="float s3 = texture2D(displacementMap, vec2(vertTexCoord.x + dx, 1.0 - vertTexCoord.y)).r;\n";shader+="float s4 = texture2D(displacementMap, vec2(vertTexCoord.x, 1.0 - vertTexCoord.y + dy)).r;\n";}
+else if(properties.DIFFPLACEMENTMAP)
+{shader+="float s1 = texture2D(diffuseDisplacementMap, vec2(vertTexCoord.x - dx, 1.0 - vertTexCoord.y)).a;\n";shader+="float s2 = texture2D(diffuseDisplacementMap, vec2(vertTexCoord.x, 1.0 - vertTexCoord.y - dy)).a;\n";shader+="float s3 = texture2D(diffuseDisplacementMap, vec2(vertTexCoord.x + dx, 1.0 - vertTexCoord.y)).a;\n";shader+="float s4 = texture2D(diffuseDisplacementMap, vec2(vertTexCoord.x, 1.0 - vertTexCoord.y + dy)).a;\n";}
+shader+="float coef = displacementFactor;\n";shader+="vec3 calcNormal;\n";shader+="if (displacementAxis == 0.0) {\n";shader+="calcNormal = vec3((s1 - s3) * coef, -5.0, (s2 - s4) * coef);\n";shader+="} else if(displacementAxis == 1.0) {\n";shader+="calcNormal = vec3((s1 - s3) * coef, -5.0, (s2 - s4) * coef);\n";shader+="} else {\n";shader+="calcNormal = vec3((s1 - s3) * coef, -(s2 - s4) * coef, 5.0);\n";shader+="}\n";shader+="calcNormal = normalize(calcNormal);\n";shader+="fragNormal = (normalMatrix * vec4(calcNormal, 0.0)).xyz;\n";}
+else
+{shader+="fragNormal = (normalMatrix * vec4(vertNormal, 0.0)).xyz;\n";}}
+if(properties.TEXTURED||properties.CSSHADER){if(properties.CUBEMAP){shader+="fragViewDir = (viewMatrix[3].xyz);\n";}else if(properties.SPHEREMAPPING){shader+=" fragTexcoord = 0.5 + fragNormal.xy / 2.0;\n";}else if(properties.TEXTRAFO){shader+=" fragTexcoord = (texTrafoMatrix * vec4(vertTexCoord, 1.0, 1.0)).xy;\n";}else{shader+=" fragTexcoord = vertTexCoord;\n";if(properties.POPGEOMETRY&&x3dom.debug.usePrecisionLevelAsTexCoord===true)
+shader+="fragTexcoord = vec2(0.03125 + 0.9375 * (PG_precisionLevel / 16.0), 1.0);";}
+if(properties.NORMALMAP&&!x3dom.caps.STD_DERIVATIVES){shader+="fragTangent  = (normalMatrix * vec4(tangent, 0.0)).xyz;\n";shader+="fragBinormal = (normalMatrix * vec4(binormal, 0.0)).xyz;\n";}}
+if(properties.LIGHTS||properties.FOG){shader+="fragPosition = (modelViewMatrix * vec4(vertPosition, 1.0)).xyz;\n";if(properties.FOG){shader+="fragEyePosition = eyePosition - fragPosition;\n";}}
+if(properties.MULTIDIFFALPMAP){shader+="fragID = id;\n";}
+if(properties.DISPLACEMENTMAP){shader+="vertPosition += normalize(vertNormal) * texture2D(displacementMap, vec2(fragTexcoord.x, 1.0-fragTexcoord.y)).r * displacementFactor;\n";}
+else if(properties.DIFFPLACEMENTMAP)
+{shader+="vertPosition += normalize(vertNormal) * texture2D(diffuseDisplacementMap, vec2(fragTexcoord.x, 1.0-fragTexcoord.y)).a * displacementFactor;\n";}
+shader+="gl_Position = modelViewProjectionMatrix * vec4(vertPosition, 1.0);\n";shader+="}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logInfo("VERTEX:\n"+shader);x3dom.debug.logError("VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.DynamicShader.prototype.generateFragmentShader=function(gl,properties)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+=" precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform mat4 modelMatrix;\n";shader+="uniform mat4 modelViewMatrix;\n";shader+=x3dom.shader.material();if(properties.VERTEXCOLOR){if(properties.COLCOMPONENTS==3){shader+="varying vec3 fragColor;  \n";}else if(properties.COLCOMPONENTS==4){shader+="varying vec4 fragColor;  \n";}}
+if(properties.TEXTURED||properties.CSSHADER){shader+="varying vec2 fragTexcoord;\n";if((properties.TEXTURED||properties.DIFFUSEMAP)&&!properties.CUBEMAP){shader+="uniform sampler2D diffuseMap;\n";}else if(properties.CUBEMAP){shader+="uniform samplerCube cubeMap;\n";shader+="varying vec3 fragViewDir;\n";shader+="uniform mat4 modelViewMatrixInverse;\n";}
+if(properties.SPECMAP){shader+="uniform sampler2D specularMap;\n";}
+if(properties.SHINMAP){shader+="uniform sampler2D shininessMap;\n";}
+if(properties.DISPLACEMENTMAP){shader+="uniform sampler2D displacementMap;\n";shader+="uniform float displacementWidth;\n";shader+="uniform float displacementHeight;\n";}
+if(properties.DIFFPLACEMENTMAP){shader+="uniform sampler2D diffuseDisplacementMap;\n";shader+="uniform float displacementWidth;\n";shader+="uniform float displacementHeight;\n";}
+if(properties.MULTIDIFFALPMAP||properties.MULTIVISMAP){shader+="varying float fragID;\n";}
+if(properties.MULTIDIFFALPMAP){shader+="uniform sampler2D multiDiffuseAlphaMap;\n";shader+="uniform float multiDiffuseAlphaWidth;\n";shader+="uniform float multiDiffuseAlphaHeight;\n";}
+if(properties.MULTIVISMAP){shader+="uniform sampler2D multiVisibilityMap;\n";shader+="uniform float multiVisibilityWidth;\n";shader+="uniform float multiVisibilityHeight;\n";}
+if(properties.NORMALMAP){shader+="uniform sampler2D normalMap;\n";if(x3dom.caps.STD_DERIVATIVES){shader+="#extension GL_OES_standard_derivatives:enable\n";shader+=x3dom.shader.TBNCalculation();}else{shader+="varying vec3 fragTangent;\n";shader+="varying vec3 fragBinormal;\n";}}}
+if(properties.FOG){shader+=x3dom.shader.fog();}
+if(properties.LIGHTS){shader+="varying vec3 fragNormal;\n";shader+="varying vec3 fragPosition;\n";shader+=x3dom.shader.light(properties.LIGHTS);}
+shader+=x3dom.shader.gammaCorrectionDecl(properties);shader+="void main(void) {\n";shader+="vec4 color;\n";shader+="color.rgb = "+x3dom.shader.decodeGamma(properties,"diffuseColor")+";\n";shader+="color.a = 1.0 - transparency;\n";if(properties.MULTIVISMAP||properties.MULTIDIFFALPMAP){shader+="vec2 idCoord;\n";shader+="float roundedID = floor(fragID+0.5);\n";}
+if(properties.MULTIVISMAP){shader+="idCoord.x = (mod(roundedID, multiVisibilityWidth)) * (1.0 / multiVisibilityWidth) + (0.5 / multiVisibilityWidth);\n";shader+="idCoord.y = (floor(roundedID / multiVisibilityHeight)) * (1.0 / multiVisibilityHeight) + (0.5 / multiVisibilityHeight);\n";shader+="vec4 visibility = texture2D( multiVisibilityMap, idCoord );\n";shader+="if (visibility.r < 1.0) discard; \n";}
+if(properties.MULTIDIFFALPMAP){shader+="idCoord.x = (mod(roundedID, multiDiffuseAlphaWidth)) * (1.0 / multiDiffuseAlphaWidth) + (0.5 / multiDiffuseAlphaWidth);\n";shader+="idCoord.y = (floor(roundedID / multiDiffuseAlphaHeight)) * (1.0 / multiDiffuseAlphaHeight) + (0.5 / multiDiffuseAlphaHeight);\n";shader+="vec4 diffAlpha = texture2D( multiDiffuseAlphaMap, idCoord );\n";shader+="color.rgb = "+x3dom.shader.decodeGamma(properties,"diffAlpha.rgb")+";\n";shader+="color.a = diffAlpha.a;\n";}
+if(properties.VERTEXCOLOR){if(properties.COLCOMPONENTS===3){shader+="color.rgb = "+x3dom.shader.decodeGamma(properties,"fragColor")+";\n";}else if(properties.COLCOMPONENTS===4){shader+="color = "+x3dom.shader.decodeGamma(properties,"fragColor")+";\n";}}
+if(properties.LIGHTS){shader+="vec3 ambient   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 diffuse   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 specular  = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 normal    = normalize(fragNormal);\n";shader+="vec3 eye    = -fragPosition;\n";shader+="float shin     = shininess;\n";if(properties.NORMALMAP){shader+="vec3 n = normalize( fragNormal );\n";if(x3dom.caps.STD_DERIVATIVES){shader+="normal = perturb_normal( n, fragPosition, vec2(fragTexcoord.x, 1.0-fragTexcoord.y) );\n";}else{shader+="vec3 t = normalize( fragTangent );\n";shader+="vec3 b = normalize( fragBinormal );\n";shader+="mat3 tangentToWorld = mat3(t, b, n);\n";shader+="normal = texture2D( normalMap, 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;\n";shader+="normal.x = -normal.x;\n";}}
+if(properties.SHINMAP){shader+="shin = texture2D( shininessMap, vec2(fragTexcoord.x, 1.0-fragTexcoord.y) ).r;\n";}
+if(!properties.SOLID){shader+="if (dot(normal, eye) < 0.0) {\n";shader+="  normal *= -1.0;\n";shader+="}\n";}
+if(properties.LIGHTS){shader+="vec3 ads;\n";for(var l=0;l<properties.LIGHTS;l++){var lightCol="light"+l+"_Color";shader+="ads = lighting(light"+l+"_Type, "+"light"+l+"_Location, "+"light"+l+"_Direction, "+
+lightCol+", "+"light"+l+"_Attenuation, "+"light"+l+"_Radius, "+"light"+l+"_Intensity, "+"light"+l+"_AmbientIntensity, "+"light"+l+"_BeamWidth, "+"light"+l+"_CutOffAngle, "+"normal, eye, shin);\n";shader+="   ambient  += "+lightCol+" * ads.r;\n"+"   diffuse  += "+lightCol+" * ads.g;\n"+"   specular += "+lightCol+" * ads.b;\n";}
+shader+="ambient = max(ambient, 0.0);\n";shader+="diffuse = max(diffuse, 0.0);\n";shader+="specular = max(specular, 0.0);\n";}
+if(properties.SPECMAP){shader+="specular *= "+x3dom.shader.decodeGamma(properties,"texture2D(specularMap, vec2(fragTexcoord.x, 1.0-fragTexcoord.y)).rgb")+";\n";}
+if(properties.TEXTURED||properties.DIFFUSEMAP||properties.DIFFPLACEMENTMAP){if(properties.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 = "+x3dom.shader.decodeGamma(properties,"textureCube(cubeMap, reflected)")+";\n";shader+="color.a *= texColor.a;\n";}
+else if(properties.DIFFPLACEMENTMAP)
+{shader+="vec2 texCoord = vec2(fragTexcoord.x, 1.0-fragTexcoord.y);\n";shader+="vec4 texColor = texture2D(diffuseDisplacementMap, texCoord);\n";}
+else
+{shader+="vec2 texCoord = vec2(fragTexcoord.x, 1.0-fragTexcoord.y);\n";shader+="vec4 texColor = "+x3dom.shader.decodeGamma(properties,"texture2D(diffuseMap, texCoord)")+";\n";shader+="color.a *= texColor.a;\n";}
+if(properties.BLENDING){shader+="color.rgb = (emissiveColor + max(ambient + diffuse, 0.0) * color.rgb + specular*specularColor);\n";if(properties.CUBEMAP){shader+="color.rgb = mix(color.rgb, texColor.rgb, vec3(0.75));\n";}else{shader+="color.rgb *= texColor.rgb;\n";}}else{shader+="color.rgb = (emissiveColor + max(ambient + diffuse, 0.0) * texColor.rgb + specular*specularColor);\n";}}else{shader+="color.rgb = (emissiveColor + max(ambient + diffuse, 0.0) * color.rgb + specular*specularColor);\n";}}else{if(properties.APPMAT&&!properties.VERTEXCOLOR){shader+="color = vec4(0.0, 0.0, 0.0, 1.0 - transparency);\n";}
+if(properties.TEXTURED||properties.DIFFUSEMAP){shader+="vec2 texCoord = vec2(fragTexcoord.x, 1.0-fragTexcoord.y);\n";shader+="vec4 texColor = "+x3dom.shader.decodeGamma(properties,"texture2D(diffuseMap, texCoord)")+";\n";shader+="color.a = texColor.a;\n";if(properties.BLENDING){shader+="color.rgb += emissiveColor.rgb;\n";shader+="color.rgb *= texColor.rgb;\n";}else{shader+="color = texColor;\n";}}else if(!properties.VERTEXCOLOR&&!properties.POINTLINE2D){shader+="color.rgb += emissiveColor;\n";}else if(!properties.VERTEXCOLOR&&properties.POINTLINE2D){shader+="color.rgb = emissiveColor;\n";}}
+if(properties.FOG){shader+="float f0 = calcFog(fragEyePosition);\n";shader+="color.rgb = fogColor * (1.0-f0) + f0 * (color.rgb);\n";}
+if(properties.TEXT){shader+="if (color.a <= 0.5) discard;\n";}else{shader+="if (color.a <= 0.1) discard;\n";}
+shader+="color = clamp(color, 0.0, 1.0);\n";shader+="gl_FragColor = "+x3dom.shader.encodeGamma(properties,"color")+";\n";shader+="}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logInfo("FRAGMENT:\n"+shader);x3dom.debug.logError("FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.DynamicMobileShader=function(gl,properties)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl,properties);var fragmentShader=this.generateFragmentShader(gl,properties);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.DynamicMobileShader.prototype.generateVertexShader=function(gl,properties)
+{var shader="";shader+=x3dom.shader.material();shader+="uniform mat4 normalMatrix;\n";shader+="uniform mat4 modelViewMatrix;\n";shader+="uniform mat4 modelViewProjectionMatrix;\n";if(properties.POSCOMPONENTS==3){shader+="attribute vec3 position;\n";}else if(properties.POSCOMPONENTS==4){shader+="attribute vec4 position;\n";}
+if(properties.IMAGEGEOMETRY){shader+="uniform vec3 IG_bboxMin;\n";shader+="uniform vec3 IG_bboxMax;\n";shader+="uniform float IG_coordTextureWidth;\n";shader+="uniform float IG_coordTextureHeight;\n";shader+="uniform vec2 IG_implicitMeshSize;\n";for(var i=0;i<properties.IG_PRECISION;i++){shader+="uniform sampler2D IG_coords"+i+"\n;";}
+if(properties.IG_INDEXED){shader+="uniform sampler2D IG_index;\n";shader+="uniform float IG_indexTextureWidth;\n";shader+="uniform float IG_indexTextureHeight;\n";}}
+if(properties.POPGEOMETRY){shader+="uniform float PG_precisionLevel;\n";shader+="uniform float PG_powPrecision;\n";shader+="uniform vec3 PG_maxBBSize;\n";shader+="uniform vec3 PG_bbMin;\n";shader+="uniform vec3 PG_bbMaxModF;\n";shader+="uniform vec3 PG_bboxShiftVec;\n";shader+="uniform float PG_numAnchorVertices;\n";shader+="attribute float PG_vertexID;\n";}
+if(!properties.POINTLINE2D){if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_normals;\n";}else{if(properties.NORCOMPONENTS==2){if(properties.POSCOMPONENTS!=4){shader+="attribute vec2 normal;\n";}}else if(properties.NORCOMPONENTS==3){shader+="attribute vec3 normal;\n";}}}
+shader+="varying vec4 fragColor;\n";if(properties.VERTEXCOLOR){if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_colors;";}else{if(properties.COLCOMPONENTS==3){shader+="attribute vec3 color;";}else if(properties.COLCOMPONENTS==4){shader+="attribute vec4 color;";}}}
+if(properties.TEXTURED){shader+="varying vec2 fragTexcoord;\n";if(properties.IMAGEGEOMETRY){shader+="uniform sampler2D IG_texCoords;";}else{shader+="attribute vec2 texcoord;\n";}
+if(properties.TEXTRAFO){shader+="uniform mat4 texTrafoMatrix;\n";}
+if(!properties.BLENDING){shader+="varying vec3 fragAmbient;\n";shader+="varying vec3 fragDiffuse;\n";}
+if(properties.CUBEMAP){shader+="varying vec3 fragViewDir;\n";shader+="varying vec3 fragNormal;\n";shader+="uniform mat4 viewMatrix;\n";}}
+if(properties.FOG){shader+=x3dom.shader.fog();}
+if(properties.LIGHTS){shader+=x3dom.shader.light(properties.LIGHTS);}
+if(properties.REQUIREBBOX){shader+="uniform vec3 bgCenter;\n";shader+="uniform vec3 bgSize;\n";shader+="uniform float bgPrecisionMax;\n";}
+if(properties.REQUIREBBOXNOR){shader+="uniform float bgPrecisionNorMax;\n";}
+if(properties.REQUIREBBOXCOL){shader+="uniform float bgPrecisionColMax;\n";}
+if(properties.REQUIREBBOXTEX){shader+="uniform float bgPrecisionTexMax;\n";}
+shader+="void main(void) {\n";shader+="gl_PointSize = 2.0;\n";if(properties.IMAGEGEOMETRY){if(properties.IG_INDEXED){shader+="vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);\n";shader+="vec2 IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_indexTextureWidth), position.y*(IG_implicitMeshSize.y/IG_indexTextureHeight)) + halfPixel;\n";shader+="vec2 IG_indices = texture2D( IG_index, IG_texCoord ).rg;\n";shader+="halfPixel = vec2(0.5/IG_coordTextureWidth,0.5/IG_coordTextureHeight);\n";shader+="IG_texCoord = (IG_indices * 0.996108948) + halfPixel;\n";}else{shader+="vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);\n";shader+="vec2 IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_coordTextureWidth), position.y*(IG_implicitMeshSize.y/IG_coordTextureHeight)) + halfPixel;\n";}
+shader+="vec3 temp = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 vertPosition = vec3(0.0, 0.0, 0.0);\n";for(var i=0;i<properties.IG_PRECISION;i++){shader+="temp = 255.0 * texture2D( IG_coords"+i+", IG_texCoord ).rgb;\n";shader+="vertPosition *= 256.0;\n";shader+="vertPosition += temp;\n";}
+shader+="vertPosition /= (pow(2.0, 8.0 * "+properties.IG_PRECISION+".0) - 1.0);\n";shader+="vertPosition = vertPosition * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;\n";if(!properties.POINTLINE2D){shader+="vec3 vertNormal = texture2D( IG_normals, IG_texCoord ).rgb;\n";shader+="vertNormal = vertNormal * 2.0 - 1.0;\n";}
+if(properties.VERTEXCOLOR){if(properties.COLCOMPONENTS==3){shader+="vec3 vertColor = texture2D( IG_colors, IG_texCoord ).rgb;";}else if(properties.COLCOMPONENTS==4){shader+="vec4 vertColor = texture2D( IG_colors, IG_texCoord ).rgba;";}}
+if(properties.TEXTURED){shader+="vec4 IG_doubleTexCoords = texture2D( IG_texCoords, IG_texCoord );\n";shader+="vec2 vertTexCoord;";shader+="vertTexCoord.r = (IG_doubleTexCoords.r * 0.996108948) + (IG_doubleTexCoords.b * 0.003891051);\n";shader+="vertTexCoord.g = (IG_doubleTexCoords.g * 0.996108948) + (IG_doubleTexCoords.a * 0.003891051);\n";}}else{shader+="vec3 vertPosition = position.xyz;\n";if(properties.POPGEOMETRY){shader+="vec3 offsetVec = step(vertPosition / bgPrecisionMax, PG_bbMaxModF) * PG_bboxShiftVec;\n";shader+="if ((PG_precisionLevel <= 2.0) || PG_vertexID >= PG_numAnchorVertices) {\n";shader+="   vertPosition = floor(vertPosition / PG_powPrecision) * PG_powPrecision;\n";shader+="   vertPosition /= (65536.0 - PG_powPrecision);\n";shader+="}\n";shader+="else {\n";shader+="   vertPosition /= bgPrecisionMax;\n";shader+="}\n";shader+="vertPosition = (vertPosition + offsetVec + PG_bbMin) * PG_maxBBSize;\n";}
+else if(properties.REQUIREBBOX){shader+="vertPosition = bgCenter + bgSize * vertPosition / bgPrecisionMax;\n";}
+if(!properties.POINTLINE2D){if(properties.NORCOMPONENTS==2){if(properties.POSCOMPONENTS==4){shader+="vec3 vertNormal = vec3(position.w / 256.0); \n";shader+="vertNormal.x = floor(vertNormal.x) / 255.0; \n";shader+="vertNormal.y = fract(vertNormal.y) * 1.00392156862745; \n";}else if(properties.REQUIREBBOXNOR){shader+="vec3 vertNormal = vec3(normal.xy, 0.0) / bgPrecisionNorMax;\n";}else{shader+="vec3 vertNormal = vec3(normal.xy, 0.0);\n";}
+shader+="vec2 thetaPhi = 3.14159265358979 * vec2(vertNormal.x, vertNormal.y*2.0-1.0); \n";shader+="vec4 sinCosThetaPhi = vec4(thetaPhi, thetaPhi + 1.5707963267949); \n";shader+="vec4 thetaPhiPow2 = sinCosThetaPhi * sinCosThetaPhi; \n";shader+="vec4 thetaPhiPow3 =  thetaPhiPow2  * sinCosThetaPhi; \n";shader+="vec4 thetaPhiPow5 =  thetaPhiPow3  * thetaPhiPow2; \n";shader+="vec4 thetaPhiPow7 =  thetaPhiPow5  * thetaPhiPow2; \n";shader+="vec4 thetaPhiPow9 =  thetaPhiPow7  * thetaPhiPow2; \n";shader+="sinCosThetaPhi +=  -0.16666666667   * thetaPhiPow3; \n";shader+="sinCosThetaPhi +=   0.00833333333   * thetaPhiPow5; \n";shader+="sinCosThetaPhi +=  -0.000198412698  * thetaPhiPow7; \n";shader+="sinCosThetaPhi +=   0.0000027557319 * thetaPhiPow9; \n";shader+="vertNormal.x = sinCosThetaPhi.x * sinCosThetaPhi.w; \n";shader+="vertNormal.y = sinCosThetaPhi.x * sinCosThetaPhi.y; \n";shader+="vertNormal.z = sinCosThetaPhi.z; \n";}else{shader+="vec3 vertNormal = normal;\n";if(properties.REQUIREBBOXNOR){shader+="vertNormal = vertNormal / bgPrecisionNorMax;\n";}
+if(properties.POPGEOMETRY){shader+="vertNormal = 2.0*vertNormal - 1.0;\n";}}}
+if(properties.VERTEXCOLOR){if(properties.COLCOMPONENTS==3){shader+="vec3 vertColor = color;";}else if(properties.COLCOMPONENTS==4){shader+="vec4 vertColor = color;";}
+if(properties.REQUIREBBOXNOR){shader+="vertColor = vertColor / bgPrecisionColMax;\n";}}
+if(properties.TEXTURED){shader+="vec2 vertTexCoord = texcoord;\n";if(properties.REQUIREBBOXTEX){shader+="vertTexCoord = vertTexCoord / bgPrecisionTexMax;\n";}}}
+shader+="vec3 positionMV = (modelViewMatrix * vec4(vertPosition, 1.0)).xyz;\n";if(!properties.POINTLINE2D){shader+="vec3 normalMV = normalize( (normalMatrix * vec4(vertNormal, 0.0)).xyz );\n";}
+shader+="vec3 eye = -positionMV;\n";if(properties.VERTEXCOLOR){shader+="vec3 rgb = vertColor.rgb;\n";if(properties.COLCOMPONENTS==4){shader+="float alpha = vertColor.a;\n";}else if(properties.COLCOMPONENTS==3){shader+="float alpha = 1.0 - transparency;\n";}}else{shader+="vec3 rgb = diffuseColor;\n";shader+="float alpha = 1.0 - transparency;\n";}
+if(properties.TEXTURED){if(properties.CUBEMAP){shader+="fragViewDir = viewMatrix[3].xyz;\n";shader+="fragNormal = normalMV;\n";}else if(properties.SPHEREMAPPING){shader+=" fragTexcoord = 0.5 + normalMV.xy / 2.0;\n";}else if(properties.TEXTRAFO){shader+=" fragTexcoord = (texTrafoMatrix * vec4(vertTexCoord, 1.0, 1.0)).xy;\n";}else{shader+=" fragTexcoord = vertTexCoord;\n";if(properties.POPGEOMETRY&&x3dom.debug.usePrecisionLevelAsTexCoord===true)
+shader+="fragTexcoord = vec2(0.03125 + 0.9375 * (PG_precisionLevel / 16.0), 1.0);";}}
+if(properties.LIGHTS){shader+="vec3 ambient   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 diffuse   = vec3(0.0, 0.0, 0.0);\n";shader+="vec3 specular  = vec3(0.0, 0.0, 0.0);\n";if(!properties.SOLID){shader+="if (dot(normalMV, eye) < 0.0) {\n";shader+="  normalMV *= -1.0;\n";shader+="}\n";}
+if(properties.LIGHTS){shader+="vec3 ads;\n";for(var l=0;l<properties.LIGHTS;l++){var lightCol="light"+l+"_Color";shader+="ads = lighting(light"+l+"_Type, "+"light"+l+"_Location, "+"light"+l+"_Direction, "+
+lightCol+", "+"light"+l+"_Attenuation, "+"light"+l+"_Radius, "+"light"+l+"_Intensity, "+"light"+l+"_AmbientIntensity, "+"light"+l+"_BeamWidth, "+"light"+l+"_CutOffAngle, "+"normalMV, eye, shininess);\n";shader+="   ambient  += "+lightCol+" * ads.r;\n"+"   diffuse  += "+lightCol+" * ads.g;\n"+"   specular += "+lightCol+" * ads.b;\n";}
+shader+="ambient = max(ambient, 0.0);\n";shader+="diffuse = max(diffuse, 0.0);\n";shader+="specular = max(specular, 0.0);\n";}
+if(properties.TEXTURED&&!properties.BLENDING){shader+="fragAmbient = ambient;\n";shader+="fragDiffuse = diffuse;\n";shader+="fragColor.rgb = (emissiveColor + specular*specularColor);\n";shader+="fragColor.a = alpha;\n";}else{shader+="fragColor.rgb = (emissiveColor + max(ambient + diffuse, 0.0) * rgb + specular*specularColor);\n";shader+="fragColor.a = alpha;\n";}}else{if(properties.APPMAT&&!properties.VERTEXCOLOR){shader+="rgb = vec3(0.0, 0.0, 0.0);\n";}
+if(properties.TEXTURED&&!properties.BLENDING){shader+="fragAmbient = vec3(0.0);\n";shader+="fragDiffuse = vec3(1.0);\n";shader+="fragColor.rgb = vec3(0.0);\n";shader+="fragColor.a = alpha;\n";}else if(!properties.VERTEXCOLOR&&properties.POINTLINE2D){shader+="fragColor.rgb = emissiveColor;\n";shader+="fragColor.a = alpha;\n";}else{shader+="fragColor.rgb = rgb + emissiveColor;\n";shader+="fragColor.a = alpha;\n";}}
+if(properties.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";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[DynamicMobileShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.DynamicMobileShader.prototype.generateFragmentShader=function(gl,properties)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="varying vec4 fragColor;\n";if(properties.TEXTURED){if(properties.CUBEMAP){shader+="uniform samplerCube cubeMap;\n";shader+="varying vec3 fragViewDir;\n";shader+="varying vec3 fragNormal;\n";shader+="uniform mat4 modelViewMatrixInverse;\n";}else{shader+="uniform sampler2D diffuseMap;           \n";shader+="varying vec2 fragTexcoord;       \n";}
+if(!properties.BLENDING){shader+="varying vec3 fragAmbient;\n";shader+="varying vec3 fragDiffuse;\n";}}
+shader+="void main(void) {\n";shader+="vec4 color = fragColor;\n";if(properties.TEXTURED){if(properties.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(cubeMap, reflected);\n";}else{shader+="vec4 texColor = texture2D(diffuseMap, vec2(fragTexcoord.s, 1.0-fragTexcoord.t));\n";}
+if(properties.BLENDING){if(properties.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 += max(fragAmbient + fragDiffuse, 0.0) * texColor.rgb;\n";shader+="color.a *= texColor.a;\n";}}
+if(properties.TEXT){shader+="if (color.a <= 0.5) discard;\n";}else{shader+="if (color.a <= 0.1) discard;\n";}
+shader+="gl_FragColor = clamp(color, 0.0, 1.0);\n";shader+="}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[DynamicMobileShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.ComposedShader=function(gl,shape)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl,shape);var fragmentShader=this.generateFragmentShader(gl,shape);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.ComposedShader.prototype.generateVertexShader=function(gl,shape)
+{var shader=shape._cf.appearance.node._shader._vertex._vf.url[0];var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ComposedShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.ComposedShader.prototype.generateFragmentShader=function(gl,shape)
+{var shader=shape._cf.appearance.node._shader._fragment._vf.url[0];var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ComposedShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.NormalShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.NormalShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"attribute vec3 normal;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform float bgPrecisionNorMax;\n"+"uniform mat4 normalMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec3 fragNormal;\n"+"void main(void) {\n"+"    vec3 pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+"    fragNormal = (normalMatrix * vec4(normal / bgPrecisionNorMax, 0.0)).xyz;\n"+"    gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[NormalShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.NormalShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="varying vec3 fragNormal;\n"+"void main(void) {\n"+"    gl_FragColor = vec4(normalize(fragNormal) / 2.0 + 0.5, 1.0);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[NormalShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.PickingShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.PickingShader.prototype.generateVertexShader=function(gl)
+{var shader="";var popUniforms="";var popDecoder="";{popUniforms+="uniform float popGeometry;\n"+"uniform float PG_precisionLevel;\n"+"uniform float PG_powPrecision;\n"+"uniform vec3 PG_maxBBSize;\n"+"uniform vec3 PG_bbMin;\n"+"uniform vec3 PG_bbMaxModF;\n"+"uniform vec3 PG_bboxShiftVec;\n";popDecoder+="   else if (popGeometry != 0.0) {\n"+"  vec3 offsetVec = step(pos / bgPrecisionMax, PG_bbMaxModF) * PG_bboxShiftVec;\n"+"  if (PG_precisionLevel <= 2.0) {\n"+"     pos = floor(pos / PG_powPrecision) * PG_powPrecision;\n"+"     pos /= (65536.0 - PG_powPrecision);\n"+"  }\n"+"  else {\n"+"     pos /= bgPrecisionMax;\n"+"  }\n"+"  pos = (pos + offsetVec + PG_bbMin) * PG_maxBBSize;\n"+" }\n"+"   else\n";}
+if(!x3dom.caps.MOBILE){shader="attribute vec3 position;\n"+"attribute float id;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform mat4 modelMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"uniform vec3 from;\n"+"varying vec3 worldCoord;\n"+"varying vec2 idCoord;\n"+"varying float fragID;\n"+"uniform float writeShadowIDs;\n"+"uniform float imageGeometry;\n"+"uniform vec3 IG_bboxMin;\n"+"uniform vec3 IG_bboxMax;\n"+"uniform float IG_coordTextureWidth;\n"+"uniform float IG_coordTextureHeight;\n"+"uniform float IG_indexTextureWidth;\n"+"uniform float IG_indexTextureHeight;\n"+"uniform sampler2D IG_indexTexture;\n"+"uniform sampler2D IG_coordinateTexture;\n"+"uniform vec2 IG_implicitMeshSize;\n"+
+popUniforms+"void main(void) {\n"+"   gl_PointSize = 2.0;\n"+"   vec3 pos = position;\n"+"   if (writeShadowIDs > 0.0) {\n"+"     idCoord = vec2((id + writeShadowIDs) / 256.0);\n"+"       idCoord.x = floor(idCoord.x) / 255.0;\n"+"       idCoord.y = fract(idCoord.y) * 1.00392156862745;\n"+"       fragID = id;\n"+" }\n"+" if (imageGeometry != 0.0) {\n"+"  vec2 IG_texCoord;\n"+"  if(imageGeometry == 1.0) {\n"+"   vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_indexTextureWidth), position.y*(IG_implicitMeshSize.y/IG_indexTextureHeight)) + halfPixel;\n"+"   vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;\n"+"   IG_texCoord = IG_index * 0.996108948;\n"+"  } else {\n"+"   vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_coordTextureWidth), position.y*(IG_implicitMeshSize.y/IG_coordTextureHeight)) + halfPixel;\n"+"  }\n"+"  pos = texture2D( IG_coordinateTexture, IG_texCoord ).rgb;\n"+"   pos = pos * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;\n"+" } \n"+
+popDecoder+"   {\n"+"  pos = bgCenter + bgSize * pos / bgPrecisionMax;\n"+" }\n"+" worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz - from;\n"+" gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"}\n";}
+else{shader="attribute vec3 position;\n"+"attribute float id;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform float writeShadowIDs;\n"+"uniform mat4 modelMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"uniform vec3 from;\n"+"varying vec3 worldCoord;\n"+"varying vec2 idCoord;\n"+"varying float fragID;\n"+
+popUniforms+"void main(void) {\n"+"    gl_PointSize = 2.0;\n"+"    vec3 pos = position;\n"+"    if (writeShadowIDs > 0.0) {\n"+"     idCoord = vec2((id + writeShadowIDs) / 256.0);\n"+"       idCoord.x = floor(idCoord.x) / 255.0;\n"+"       idCoord.y = fract(idCoord.y) * 1.00392156862745;\n"+"       fragID = id;\n"+"  }\n"+
+popDecoder+"  {\n"+"       pos = bgCenter + bgSize * pos / bgPrecisionMax;\n"+"  }\n"+"    worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz - from;\n"+"    gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"}\n";}
+var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.PickingShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+=" precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform float writeShadowIDs;\n"+"uniform float highBit;\n"+"uniform float lowBit;\n"+"uniform float sceneSize;\n"+"uniform float visibilityMap;\n"+"uniform float multiVisibilityWidth;\n"+"uniform float multiVisibilityHeight;\n"+"varying vec3 worldCoord;\n"+"varying vec2 idCoord;\n"+"varying float fragID;\n"+"uniform sampler2D multiVisibilityMap;\n"+"void main(void) {\n"+"    vec4 col = vec4(0.0, 0.0, highBit, lowBit);\n"+"    if (writeShadowIDs > 0.0) {\n"+"       col.ba = idCoord;\n"+"       if (visibilityMap > 0.1) {\n"+"           vec2 idTexCoord;\n"+"           float roundedID = floor(fragID+0.5);\n"+"           idTexCoord.x = (mod(roundedID, multiVisibilityWidth)) * (1.0 / multiVisibilityWidth) + (0.5 / multiVisibilityWidth);\n"+"           idTexCoord.y = (floor(roundedID / multiVisibilityHeight)) * (1.0 / multiVisibilityHeight) + (0.5 / multiVisibilityHeight);\n"+"           vec4 visibility = texture2D( multiVisibilityMap, idTexCoord );\n"+"           if (visibility.r < 1.0) discard; \n"+"       }\n"+"  }\n"+"    float d = length(worldCoord) / sceneSize;\n"+"    vec2 comp = fract(d * vec2(256.0, 1.0));\n"+"    col.rg = comp - (comp.rr * vec2(0.0, 1.0/256.0));\n"+"    gl_FragColor = col;\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.Picking24Shader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.Picking24Shader.prototype.generateVertexShader=function(gl)
+{var shader="";if(!x3dom.caps.MOBILE){shader="attribute vec3 position;\n"+"attribute float id;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform mat4 modelMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"uniform vec3 from;\n"+"varying vec3 worldCoord;\n"+"varying vec3 idCoord;\n"+"varying float fragID;\n"+"uniform float writeShadowIDs;\n"+"uniform float imageGeometry;\n"+"uniform vec3 IG_bboxMin;\n"+"uniform vec3 IG_bboxMax;\n"+"uniform float IG_coordTextureWidth;\n"+"uniform float IG_coordTextureHeight;\n"+"uniform float IG_indexTextureWidth;\n"+"uniform float IG_indexTextureHeight;\n"+"uniform sampler2D IG_indexTexture;\n"+"uniform sampler2D IG_coordinateTexture;\n"+"uniform vec2 IG_implicitMeshSize;\n"+"void main(void) {\n"+"   gl_PointSize = 2.0;\n"+"   if (writeShadowIDs > 0.0) {\n"+"       float ID = id + writeShadowIDs;\n"+"       float h = floor(ID / 256.0);\n"+"       idCoord.x = ID - (h * 256.0);\n"+"       idCoord.z = floor(h / 256.0);\n"+"       idCoord.y = h - (idCoord.z * 256.0);\n"+"       idCoord = idCoord.zyx / 255.0;\n"+"       fragID = id;\n"+" }\n"+" if (imageGeometry != 0.0) {\n"+"  vec2 IG_texCoord;\n"+"  if(imageGeometry == 1.0) {\n"+"   vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_indexTextureWidth), position.y*(IG_implicitMeshSize.y/IG_indexTextureHeight)) + halfPixel;\n"+"   vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;\n"+"   IG_texCoord = IG_index * 0.996108948;\n"+"  } else {\n"+"   vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_coordTextureWidth), position.y*(IG_implicitMeshSize.y/IG_coordTextureHeight)) + halfPixel;\n"+"  }\n"+"  vec3 pos = texture2D( IG_coordinateTexture, IG_texCoord ).rgb;\n"+"   pos = pos * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;\n"+"     worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz - from;\n"+"  gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+" } else {\n"+"  vec3 pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+"  worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz - from;\n"+"  gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+" }\n"+"}\n";}
+else{shader="attribute vec3 position;\n"+"attribute float id;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform float writeShadowIDs;\n"+"varying float fragID;\n"+"uniform mat4 modelMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"uniform vec3 from;\n"+"varying vec3 worldCoord;\n"+"varying vec3 idCoord;\n"+"void main(void) {\n"+"    gl_PointSize = 2.0;\n"+"    if (writeShadowIDs > 0.0) {\n"+"       float ID = id + writeShadowIDs;\n"+"       float h = floor(ID / 256.0);\n"+"       idCoord.x = ID - (h * 256.0);\n"+"       idCoord.z = floor(h / 256.0);\n"+"       idCoord.y = h - (idCoord.z * 256.0);\n"+"       idCoord = idCoord.zyx / 255.0;\n"+"       fragID = id;\n"+"  }\n"+"    vec3 pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+"    worldCoord = (modelMatrix * vec4(pos, 1.0)).xyz - from;\n"+"    gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"}\n";}
+var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[Picking24Shader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.Picking24Shader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform float writeShadowIDs;\n"+"uniform float highBit;\n"+"uniform float lowBit;\n"+"uniform float sceneSize;\n"+"uniform float visibilityMap;\n"+"uniform float multiVisibilityWidth;\n"+"uniform float multiVisibilityHeight;\n"+"varying vec3 worldCoord;\n"+"varying vec3 idCoord;\n"+"varying float fragID;\n"+"uniform sampler2D multiVisibilityMap;\n"+"void main(void) {\n"+"    vec4 col = vec4(0.0, 0.0, highBit, lowBit);\n"+"    if (writeShadowIDs > 0.0) {\n"+"       col.gba = idCoord;\n"+"       if (visibilityMap > 0.0) {\n"+"           vec2 idTexCoord;\n"+"           float roundedID = floor(fragID+0.5);\n"+"           idTexCoord.x = (mod(roundedID, multiVisibilityWidth)) * (1.0 / multiVisibilityWidth) + (0.5 / multiVisibilityWidth);\n"+"           idTexCoord.y = (floor(roundedID / multiVisibilityHeight)) * (1.0 / multiVisibilityHeight) + (0.5 / multiVisibilityHeight);\n"+"           vec4 visibility = texture2D( multiVisibilityMap, idTexCoord );\n"+"           if (visibility.a < 1.0) discard; \n"+"       }\n"+"  }\n"+"    col.r = length(worldCoord) / sceneSize;\n"+"    gl_FragColor = col;\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[Picking24Shader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.PickingIdShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.PickingIdShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"attribute float id;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform float writeShadowIDs;\n"+"uniform mat4 modelMatrix;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec2 idCoord;\n"+"void main(void) {\n"+"    if (writeShadowIDs > 0.0) {\n"+"     idCoord = vec2((id + writeShadowIDs) / 256.0);\n"+"       idCoord.x = floor(idCoord.x) / 255.0;\n"+"       idCoord.y = fract(idCoord.y) * 1.00392156862745;\n"+"  }\n"+"    vec3 pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+"    gl_Position = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingIdShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.PickingIdShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+=" precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform float writeShadowIDs;\n"+"uniform float highBit;\n"+"uniform float lowBit;\n"+"varying vec2 idCoord;\n"+"void main(void) {\n"+"    vec4 col = vec4(highBit, lowBit, 0.0, 0.0);\n"+"    if (writeShadowIDs > 0.0) {\n"+"       col.ba = idCoord;\n"+"  }\n"+"    gl_FragColor = col;\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingIdShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.PickingColorShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.PickingColorShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"attribute vec3 color;\n"+"varying vec3 fragColor;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"\n"+"void main(void) {\n"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);\n"+"    gl_PointSize = 2.0;\n"+"    fragColor = color;\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingColorShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.PickingColorShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform float lowBit;\n"+"varying vec3 fragColor;\n"+"\n"+"void main(void) {\n"+"    gl_FragColor = vec4(fragColor, lowBit);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingColorShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.PickingTexcoordShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.PickingTexcoordShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"attribute vec2 texcoord;\n"+"varying vec3 fragColor;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+""+"void main(void) {\n"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);\n"+"    fragColor = vec3(abs(texcoord.x), abs(texcoord.y), 0.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingTexcoordShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.PickingTexcoordShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform float lowBit;\n"+"varying vec3 fragColor;\n"+"\n"+"void main(void) {\n"+"    gl_FragColor = vec4(fragColor, lowBit);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[PickingTexcoordShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.FrontgroundTextureShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.FrontgroundTextureShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    vec2 texCoord = (position.xy + 1.0) * 0.5;\n"+"    fragTexCoord = texCoord;\n"+"    gl_Position = vec4(position.xy, 0.0, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[FrontgroundTextureShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.FrontgroundTextureShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform sampler2D tex;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    vec4 col = texture2D(tex, fragTexCoord);\n"+"    gl_FragColor = vec4(col.rgb, 1.0);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[FrontgroundTextureShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.BackgroundTextureShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.BackgroundTextureShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    vec2 texCoord = (position.xy + 1.0) * 0.5;\n"+"    fragTexCoord = texCoord;\n"+"    gl_Position = vec4(position.xy, 0.0, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundTextureShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.BackgroundTextureShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform sampler2D tex;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    gl_FragColor = texture2D(tex, fragTexCoord);\n"+"}";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundTextureShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.BackgroundSkyTextureShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.BackgroundSkyTextureShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"attribute vec2 texcoord;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    fragTexCoord = texcoord;\n"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundSkyTextureShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.BackgroundSkyTextureShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform sampler2D tex;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    gl_FragColor = texture2D(tex, fragTexCoord);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundSkyTextureShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.BackgroundCubeTextureShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.BackgroundCubeTextureShader.prototype.generateVertexShader=function(gl)
+{var shader="attribute vec3 position;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec3 fragNormal;\n"+"\n"+"void main(void) {\n"+"    fragNormal = normalize(position);\n"+"    gl_Position = modelViewProjectionMatrix * vec4(position, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundCubeTextureShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.BackgroundCubeTextureShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform samplerCube tex;\n"+"varying vec3 fragNormal;\n"+"\n"+"float magn(float val) {\n"+"    return ((val >= 0.0) ? val : -1.0 * val);\n"+"}"+"\n"+"void main(void) {\n"+"    vec3 normal = -reflect(normalize(fragNormal), vec3(0.0,0.0,1.0));\n"+"    if (magn(normal.y) >= magn(normal.x) && magn(normal.y) >= magn(normal.z))\n"+"        normal.xz = -normal.xz;\n"+"    gl_FragColor = textureCube(tex, normal);\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BackgroundCubeTextureShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.ShadowShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.ShadowShader.prototype.generateVertexShader=function(gl)
+{var shader="";if(!x3dom.caps.MOBILE){shader+="attribute vec3 position;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec4 projCoords;\n"+"uniform float imageGeometry;\n"+"uniform vec3 IG_bboxMin;\n"+"uniform vec3 IG_bboxMax;\n"+"uniform float IG_coordTextureWidth;\n"+"uniform float IG_coordTextureHeight;\n"+"uniform float IG_indexTextureWidth;\n"+"uniform float IG_indexTextureHeight;\n"+"uniform sampler2D IG_indexTexture;\n"+"uniform sampler2D IG_coordinateTexture;\n"+"uniform vec2 IG_implicitMeshSize;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform float popGeometry;\n"+"uniform float PG_precisionLevel;\n"+"uniform float PG_powPrecision;\n"+"uniform vec3 PG_maxBBSize;\n"+"uniform vec3 PG_bbMin;\n"+"uniform vec3 PG_bbMaxModF;\n"+"uniform vec3 PG_bboxShiftVec;\n"+"void main(void) {\n"+" vec3 pos;\n"+" if (imageGeometry != 0.0) {\n"+"  vec2 IG_texCoord;\n"+"  if(imageGeometry == 1.0) {\n"+"   vec2 halfPixel = vec2(0.5/IG_indexTextureWidth,0.5/IG_indexTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_indexTextureWidth), position.y*(IG_implicitMeshSize.y/IG_indexTextureHeight)) + halfPixel;\n"+"   vec2 IG_index = texture2D( IG_indexTexture, IG_texCoord ).rg;\n"+"   IG_texCoord = IG_index * 0.996108948;\n"+"  } else {\n"+"   vec2 halfPixel = vec2(0.5/IG_coordTextureWidth, 0.5/IG_coordTextureHeight);\n"+"   IG_texCoord = vec2(position.x*(IG_implicitMeshSize.x/IG_coordTextureWidth), position.y*(IG_implicitMeshSize.y/IG_coordTextureHeight)) + halfPixel;\n"+"  }\n"+"  pos = texture2D( IG_coordinateTexture, IG_texCoord ).rgb;\n"+"   pos = pos * (IG_bboxMax - IG_bboxMin) + IG_bboxMin;\n"+" } else if (popGeometry != 0.0){\n"+"  pos = position;\n"+"  vec3 offsetVec = step(pos / bgPrecisionMax, PG_bbMaxModF) * PG_bboxShiftVec;\n"+"  if (PG_precisionLevel <= 2.0) {\n"+"     pos = floor(pos / PG_powPrecision) * PG_powPrecision;\n"+"     pos /= (65536.0 - PG_powPrecision);\n"+"  }\n"+"  else {\n"+"     pos /= bgPrecisionMax;\n"+"  }\n"+"  pos = (pos + offsetVec + PG_bbMin) * PG_maxBBSize;\n"+" } else {\n"+"  pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+" }\n"+"   projCoords = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+"   gl_Position = projCoords;\n"+"}\n";}else{shader="attribute vec3 position;\n"+"uniform vec3 bgCenter;\n"+"uniform vec3 bgSize;\n"+"uniform float bgPrecisionMax;\n"+"uniform mat4 modelViewProjectionMatrix;\n"+"varying vec4 projCoords;\n"+"void main(void) {\n"+" vec3 pos = bgCenter + bgSize * position / bgPrecisionMax;\n"+" projCoords = modelViewProjectionMatrix * vec4(pos, 1.0);\n"+" gl_Position = projCoords;\n"+"}\n";}
+var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ShadowShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.ShadowShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="varying vec4 projCoords;\n"+"uniform float offset;\n"+"uniform bool cameraView;\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE)
+shader+=x3dom.shader.rgbaPacking();shader+="void main(void) {\n"+"    vec3 proj = (projCoords.xyz / projCoords.w);\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE){shader+="gl_FragColor = packDepth(proj.z);\n";}else{shader+=" if (!cameraView){\n"+"  proj.z = (proj.z + 1.0)*0.5;\n"+"  proj.y = proj.z * proj.z;\n"+" }\n";shader+=" gl_FragColor = vec4(proj, 1.0);\n";}
+shader+="}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ShadowShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.ShadowRenderingShader=function(gl,shadowedLights)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl,shadowedLights);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.ShadowRenderingShader.prototype.generateVertexShader=function(gl)
+{var shader="";shader+="attribute vec2 position;\n";shader+="varying vec2 vPosition;\n";shader+="void main(void) {\n";shader+=" vPosition = position;\n";shader+=" gl_Position = vec4(position, -1.0, 1.0);\n";shader+="}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ShadowRendering] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.ShadowRenderingShader.prototype.generateFragmentShader=function(gl,shadowedLights)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="uniform mat4 inverseViewProj;\n";shader+="uniform mat4 inverseProj;\n";shader+="varying vec2 vPosition;\n";shader+="uniform sampler2D sceneMap;\n";for(var i=0;i<5;i++)
+shader+="uniform float cascade"+i+"_Depth;\n";for(var l=0;l<shadowedLights.length;l++){shader+="uniform float light"+l+"_On;\n"+"uniform float light"+l+"_Type;\n"+"uniform vec3  light"+l+"_Location;\n"+"uniform vec3  light"+l+"_Direction;\n"+"uniform vec3  light"+l+"_Attenuation;\n"+"uniform float light"+l+"_Radius;\n"+"uniform float light"+l+"_BeamWidth;\n"+"uniform float light"+l+"_CutOffAngle;\n"+"uniform float light"+l+"_ShadowIntensity;\n"+"uniform float light"+l+"_ShadowOffset;\n"+"uniform mat4 light"+l+"_ViewMatrix;\n";for(var j=0;j<6;j++){shader+="uniform mat4 light"+l+"_"+j+"_Matrix;\n";shader+="uniform sampler2D light"+l+"_"+j+"_ShadowMap;\n";}
+for(var j=0;j<5;j++)
+shader+="uniform float light"+l+"_"+j+"_Split;\n";}
+if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE)
+shader+=x3dom.shader.rgbaPacking();shader+=x3dom.shader.shadowRendering();shader+=x3dom.shader.gammaCorrectionDecl({});shader+="void main(void) {\n"+" float shadowValue = 1.0;\n"+" vec2 texCoordsSceneMap = (vPosition + 1.0)*0.5;\n"+" vec4 projCoords = texture2D(sceneMap, texCoordsSceneMap);\n"+" if (projCoords != vec4(1.0,1.0,1.0,0.0)){\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE){shader+=" projCoords.z = unpackDepth(projCoords);\n"+" projCoords.w = 1.0;\n";}
+shader+=" projCoords = projCoords / projCoords.w;\n"+" projCoords.xy = vPosition;\n"+" vec4 eyeCoords = inverseProj*projCoords;\n"+" vec4 worldCoords = inverseViewProj*projCoords;\n"+" float lightInfluence = 0.0;\n";for(var l=0;l<shadowedLights.length;l++){shader+=" lightInfluence = getLightInfluence(light"+l+"_Type, light"+l+"_ShadowIntensity, light"+l+"_On, light"+l+"_Location, light"+l+"_Direction, "+"light"+l+"_CutOffAngle, light"+l+"_BeamWidth, light"+l+"_Attenuation, light"+l+"_Radius, eyeCoords.xyz/eyeCoords.w);\n"+" if (lightInfluence != 0.0){\n"+"  vec4 shadowMapValues;\n"+"  float viewSampleDepth;\n";if(!x3dom.isa(shadowedLights[l],x3dom.nodeTypes.PointLight)){shader+="  getShadowValuesCascaded(shadowMapValues, viewSampleDepth, worldCoords, -eyeCoords.z/eyeCoords.w,"+"light"+l+"_0_Matrix,light"+l+"_1_Matrix,light"+l+"_2_Matrix,light"+l+"_3_Matrix,light"+l+"_4_Matrix,light"+l+"_5_Matrix,"+"light"+l+"_0_ShadowMap,light"+l+"_1_ShadowMap,light"+l+"_2_ShadowMap,light"+l+"_3_ShadowMap,"+"light"+l+"_4_ShadowMap,light"+l+"_5_ShadowMap, light"+l+"_0_Split, light"+l+"_1_Split, light"+l+"_2_Split, light"+l+"_3_Split, \n"+"light"+l+"_4_Split);\n";}else{shader+="  getShadowValuesPointLight(shadowMapValues, viewSampleDepth, light"+l+"_Location, worldCoords, light"+l+"_ViewMatrix, "+"light"+l+"_0_Matrix,light"+l+"_1_Matrix,light"+l+"_2_Matrix,light"+l+"_3_Matrix,light"+l+"_4_Matrix,light"+l+"_5_Matrix,"+"light"+l+"_0_ShadowMap,light"+l+"_1_ShadowMap,light"+l+"_2_ShadowMap,light"+l+"_3_ShadowMap,"+"light"+l+"_4_ShadowMap,light"+l+"_5_ShadowMap);\n";}
+if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE)
+shader+=" shadowValue *= clamp(ESM(shadowMapValues.z, viewSampleDepth, light"+l+"_ShadowOffset), "+"    1.0 - light"+l+"_ShadowIntensity*lightInfluence, 1.0);\n";else
+shader+="  shadowValue *= clamp(VSM(shadowMapValues.zy, viewSampleDepth, light"+l+"_ShadowOffset), "+"    1.0 - light"+l+"_ShadowIntensity*lightInfluence, 1.0);\n";shader+=" }\n";}
+shader+="}\n"+" gl_FragColor = "+x3dom.shader.encodeGamma({},"vec4(shadowValue, shadowValue, shadowValue, 1.0)")+";\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[ShadowRendering] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.TextureRefinementShader=function(gl){this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.TextureRefinementShader.prototype.generateVertexShader=function(gl){var shader="attribute vec2 position;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void main(void) {\n"+"    fragTexCoord = (position.xy + 1.0) / 2.0;\n"+"    gl_Position = vec4(position, -1.0, 1.0);\n"+"}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[TextureRefinementShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.TextureRefinementShader.prototype.generateFragmentShader=function(gl){var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n"+" precision highp float;\n"+"#else\n"+" precision mediump float;\n"+"#endif\n\n";shader+="uniform sampler2D stamp;\n"+"uniform sampler2D lastTex;\n"+"uniform sampler2D curTex;\n"+"uniform int mode;\n"+"uniform vec2 repeat;\n"+"varying vec2 fragTexCoord;\n"+"\n"+"void init(void);\n"+"void refine(void);\n"+"\n"+"void main(void) {\n"+"    if (mode == 0) { init(); }\n"+"    else { refine(); }\n"+"}\n"+"\n"+"void init(void) {\n"+"    gl_FragColor = texture2D(curTex, fragTexCoord);\n"+"}\n"+"\n"+"void refine(void) {\n"+"    vec3 red = texture2D(stamp, repeat * fragTexCoord).rgb;\n"+"    vec3 v1  = texture2D(lastTex, fragTexCoord).rgb;\n"+"    vec3 v2  = texture2D(curTex, fragTexCoord).rgb;\n"+"    if (red.r <= 0.5) {\n"+"        gl_FragColor = vec4(v1, 1.0);\n"+"    }\n"+"    else {\n"+"        gl_FragColor = vec4(v2, 1.0);\n"+"    }\n"+"}\n";var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[TextureRefinementShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.shader.BlurShader=function(gl)
+{this.program=gl.createProgram();var vertexShader=this.generateVertexShader(gl);var fragmentShader=this.generateFragmentShader(gl);gl.attachShader(this.program,vertexShader);gl.attachShader(this.program,fragmentShader);gl.bindAttribLocation(this.program,0,"position");gl.linkProgram(this.program);return this.program;};x3dom.shader.BlurShader.prototype.generateVertexShader=function(gl)
+{var shader="";shader+="attribute vec2 position;\n";shader+="varying vec2 vPosition;\n";shader+="void main(void) {\n";shader+=" vPosition = position;\n";shader+=" gl_Position = vec4(position, -1.0, 1.0);\n";shader+="}\n";var vertexShader=gl.createShader(gl.VERTEX_SHADER);gl.shaderSource(vertexShader,shader);gl.compileShader(vertexShader);if(!gl.getShaderParameter(vertexShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BlurShader] VertexShader "+gl.getShaderInfoLog(vertexShader));}
+return vertexShader;};x3dom.shader.BlurShader.prototype.generateFragmentShader=function(gl)
+{var shader="#ifdef GL_FRAGMENT_PRECISION_HIGH\n";shader+="precision highp float;\n";shader+="#else\n";shader+=" precision mediump float;\n";shader+="#endif\n\n";shader+="varying vec2 vPosition;\n"+"uniform sampler2D texture;\n"+"uniform bool horizontal;\n"+"uniform float pixelSizeHor;\n"+"uniform float pixelSizeVert;\n"+"uniform int filterSize;\n";if(!x3dom.caps.FP_TEXTURES||x3dom.caps.MOBILE){shader+=x3dom.shader.rgbaPacking()+"void main(void) {\n"+" vec2 texCoords = (vPosition + 1.0)*0.5;\n"+" vec2 offset;\n"+" if (horizontal) offset = vec2(pixelSizeHor, 0.0);\n"+" else offset = vec2(0.0, pixelSizeVert);\n"+" float depth = unpackDepth(texture2D(texture, texCoords));\n"+" if (filterSize == 3){\n"+"  depth = depth * 0.3844;\n"+"  depth += 0.3078*unpackDepth(texture2D(texture, texCoords-offset));\n"+"  depth += 0.3078*unpackDepth(texture2D(texture, texCoords+offset));\n"+" } else if (filterSize == 5){\n"+"  depth = depth * 0.2921;\n"+"  depth += 0.2339*unpackDepth(texture2D(texture, texCoords-offset));\n"+"  depth += 0.2339*unpackDepth(texture2D(texture, texCoords+offset));\n"+"  depth += 0.1201*unpackDepth(texture2D(texture, texCoords-2.0*offset));\n"+"  depth += 0.1201*unpackDepth(texture2D(texture, texCoords+2.0*offset));\n"+" } else if (filterSize == 7){\n"+"  depth = depth * 0.2161;\n"+"  depth += 0.1907*unpackDepth(texture2D(texture, texCoords-offset));\n"+"  depth += 0.1907*unpackDepth(texture2D(texture, texCoords+offset));\n"+"  depth += 0.1311*unpackDepth(texture2D(texture, texCoords-2.0*offset));\n"+"  depth += 0.1311*unpackDepth(texture2D(texture, texCoords+2.0*offset));\n"+"  depth += 0.0702*unpackDepth(texture2D(texture, texCoords-3.0*offset));\n"+"  depth += 0.0702*unpackDepth(texture2D(texture, texCoords+3.0*offset));\n"+" }\n"+" gl_FragColor = packDepth(depth);\n"+"}\n";}else{shader+="void main(void) {\n"+" vec2 texCoords = (vPosition + 1.0)*0.5;\n"+" vec2 offset;\n"+" if (horizontal) offset = vec2(pixelSizeHor, 0.0);\n"+" else offset = vec2(0.0, pixelSizeVert);\n"+" vec4 color = texture2D(texture, texCoords);\n"+" if (filterSize == 3){\n"+"  color = color * 0.3844;\n"+"  color += 0.3078*texture2D(texture, texCoords-offset);\n"+"  color += 0.3078*texture2D(texture, texCoords+offset);\n"+" } else if (filterSize == 5){\n"+"  color = color * 0.2921;\n"+"  color += 0.2339*texture2D(texture, texCoords-offset);\n"+"  color += 0.2339*texture2D(texture, texCoords+offset);\n"+"  color += 0.1201*texture2D(texture, texCoords-2.0*offset);\n"+"  color += 0.1201*texture2D(texture, texCoords+2.0*offset);\n"+" } else if (filterSize == 7){\n"+"  color = color * 0.2161;\n"+"  color += 0.1907*texture2D(texture, texCoords-offset);\n"+"  color += 0.1907*texture2D(texture, texCoords+offset);\n"+"  color += 0.1311*texture2D(texture, texCoords-2.0*offset);\n"+"  color += 0.1311*texture2D(texture, texCoords+2.0*offset);\n"+"  color += 0.0702*texture2D(texture, texCoords-3.0*offset);\n"+"  color += 0.0702*texture2D(texture, texCoords+3.0*offset);\n"+" }\n"+" gl_FragColor = color;\n"+"}\n";}
+var fragmentShader=gl.createShader(gl.FRAGMENT_SHADER);gl.shaderSource(fragmentShader,shader);gl.compileShader(fragmentShader);if(!gl.getShaderParameter(fragmentShader,gl.COMPILE_STATUS)){x3dom.debug.logError("[BlurShader] FragmentShader "+gl.getShaderInfoLog(fragmentShader));}
+return fragmentShader;};x3dom.gfx_webgl=(function(){"use strict";function Context(ctx3d,canvas,name,x3dElem){this.ctx3d=ctx3d;this.canvas=canvas;this.name=name;this.x3dElem=x3dElem;this.IG_PositionBuffer=null;this.cache=new x3dom.Cache();this.stateManager=new x3dom.StateManager(ctx3d);}
+Context.prototype.getName=function(){return this.name;};function setupContext(canvas,forbidMobileShaders,forceMobileShaders,tryWebGL2,x3dElem){var validContextNames=['webgl','experimental-webgl','moz-webgl','webkit-3d'];if(tryWebGL2){validContextNames=['experimental-webgl2'].concat(validContextNames);}
+var ctx=null;var ctxAttribs={alpha:true,depth:true,stencil:true,antialias:true,premultipliedAlpha:false,preserveDrawingBuffer:true};for(var i=0;i<validContextNames.length;i++){try{ctx=canvas.getContext(validContextNames[i],ctxAttribs);if(ctx){var newCtx=new Context(ctx,canvas,'webgl',x3dElem);try{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.DEPTH_BITS=ctx.getParameter(ctx.DEPTH_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_TEXTURE_IMAGE_UNITS=ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);x3dom.caps.MAX_CUBE_MAP_TEXTURE_SIZE=ctx.getParameter(ctx.MAX_CUBE_MAP_TEXTURE_SIZE);x3dom.caps.COMPRESSED_TEXTURE_FORMATS=ctx.getParameter(ctx.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.SAMPLES=ctx.getParameter(ctx.SAMPLES);x3dom.caps.INDEX_UINT=ctx.getExtension("OES_element_index_uint");x3dom.caps.FP_TEXTURES=ctx.getExtension("OES_texture_float");x3dom.caps.FPL_TEXTURES=ctx.getExtension("OES_texture_float_linear");x3dom.caps.STD_DERIVATIVES=ctx.getExtension("OES_standard_derivatives");x3dom.caps.DRAW_BUFFERS=ctx.getExtension("WEBGL_draw_buffers");x3dom.caps.EXTENSIONS=ctx.getSupportedExtensions();var extString=x3dom.caps.EXTENSIONS.toString().replace(/,/g,", ");x3dom.debug.logInfo(validContextNames[i]+" context found\nVendor: "+x3dom.caps.VENDOR+", Renderer: "+x3dom.caps.RENDERER+", "+"Version: "+x3dom.caps.VERSION+", "+"ShadingLangV.: "+x3dom.caps.SHADING_LANGUAGE_VERSION
++", MSAA samples: "+x3dom.caps.SAMPLES+"\nExtensions: "+extString);if(x3dom.caps.INDEX_UINT){x3dom.Utils.maxIndexableCoords=4294967295;}
+x3dom.caps.MOBILE=(function(a){return(/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)))})(navigator.userAgent||navigator.vendor||window.opera);if(x3dom.caps.RENDERER.indexOf("PowerVR")>=0||navigator.appVersion.indexOf("Mobile")>-1||x3dom.caps.MAX_VARYING_VECTORS<=8||x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS<2){x3dom.caps.MOBILE=true;}
+if(x3dom.caps.MOBILE){if(forbidMobileShaders){x3dom.caps.MOBILE=false;x3dom.debug.logWarning("Detected mobile graphics card! "+"But being forced to desktop shaders which might not work!");}
+else{x3dom.debug.logWarning("Detected mobile graphics card! "+"Using low quality shaders without ImageGeometry support!");}}
+else{if(forceMobileShaders){x3dom.caps.MOBILE=true;x3dom.debug.logWarning("Detected desktop graphics card! "+"But being forced to mobile shaders with lower quality!");}}}
+catch(ex){x3dom.debug.logWarning("Your browser probably supports an older WebGL version. "+"Please try the old mobile runtime instead:\n"+"http://www.x3dom.org/x3dom/src_mobile/x3dom.js");newCtx=null;}
+return newCtx;}}
+catch(e){x3dom.debug.logWarning(e);}}
+return null;}
+Context.prototype.setupShape=function(gl,drawable,viewarea){var q=0,q6;var textures,t;var vertices,positionBuffer;var texCoordBuffer,normalBuffer,colorBuffer;var indicesBuffer,indexArray;var shape=drawable.shape;var geoNode=shape._cf.geometry.node;if(shape._webgl!==undefined){var needFullReInit=false;if(shape._dirty.colors===true&&shape._webgl.shader.color===undefined&&geoNode._mesh._colors[0].length){needFullReInit=true;}
+if(needFullReInit&&shape._cleanupGLObjects){shape._cleanupGLObjects(true,false);}
+if(shape._dirty.texture===true){if(shape._webgl.texture.length!=shape.getTextures().length){for(t=0;t<shape._webgl.texture.length;++t){shape._webgl.texture.pop();}
+textures=shape.getTextures();for(t=0;t<textures.length;++t){shape._webgl.texture.push(new x3dom.Texture(gl,shape._nameSpace.doc,this.cache,textures[t]));}
+shape._dirty.shader=true;if(shape._webgl.shader.texcoord===undefined)
+shape._dirty.texcoords=true;}
+else{textures=shape.getTextures();for(t=0;t<textures.length;++t){if(textures[t]===shape._webgl.texture[t].node){shape._webgl.texture[t].update();}
+else{shape._webgl.texture[t].texture=null;shape._webgl.texture[t].node=textures[t];shape._webgl.texture[t].update();}}}
+shape._dirty.texture=false;}
+shape._webgl.shader=this.cache.getShaderByProperties(gl,shape,shape.getShaderProperties(viewarea));if(!needFullReInit&&shape._webgl.binaryGeometry==0)
+{for(q=0;q<shape._webgl.positions.length;q++)
+{q6=6*q;if(shape._dirty.positions==true||shape._dirty.indexes==true){if(shape._webgl.shader.position!==undefined){shape._webgl.indexes[q]=geoNode._mesh._indices[q];gl.deleteBuffer(shape._webgl.buffers[q6]);indicesBuffer=gl.createBuffer();shape._webgl.buffers[q6]=indicesBuffer;if(x3dom.caps.INDEX_UINT&&(geoNode._mesh._positions[0].length/3>65535)){indexArray=new Uint32Array(shape._webgl.indexes[q]);shape._webgl.indexType=gl.UNSIGNED_INT;}
+else{indexArray=new Uint16Array(shape._webgl.indexes[q]);shape._webgl.indexType=gl.UNSIGNED_SHORT;}
+gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,indicesBuffer);gl.bufferData(gl.ELEMENT_ARRAY_BUFFER,indexArray,gl.STATIC_DRAW);indexArray=null;shape._webgl.positions[q]=geoNode._mesh._positions[q];gl.deleteBuffer(shape._webgl.buffers[q6+1]);positionBuffer=gl.createBuffer();shape._webgl.buffers[q6+1]=positionBuffer;gl.bindBuffer(gl.ARRAY_BUFFER,positionBuffer);gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,shape._webgl.buffers[q6]);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,geoNode._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);vertices=null;}
+shape._dirty.positions=false;shape._dirty.indexes=false;}
+if(shape._dirty.colors==true){if(shape._webgl.shader.color!==undefined){shape._webgl.colors[q]=geoNode._mesh._colors[q];gl.deleteBuffer(shape._webgl.buffers[q6+4]);colorBuffer=gl.createBuffer();shape._webgl.buffers[q6+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,geoNode._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);colors=null;}
+shape._dirty.colors=false;}
+if(shape._dirty.normals==true){if(shape._webgl.shader.normal!==undefined){shape._webgl.normals[q]=geoNode._mesh._normals[q];gl.deleteBuffer(shape._webgl.buffers[q6+2]);normalBuffer=gl.createBuffer();shape._webgl.buffers[q6+2]=normalBuffer;normals=new Float32Array(shape._webgl.normals[q]);gl.bindBuffer(gl.ARRAY_BUFFER,normalBuffer);gl.bufferData(gl.ARRAY_BUFFER,normals,gl.STATIC_DRAW);gl.vertexAttribPointer(shape._webgl.shader.normal,geoNode._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);normals=null;}
+shape._dirty.normals=false;}
+if(shape._dirty.texcoords==true){if(shape._webgl.shader.texcoord!==undefined){shape._webgl.texcoords[q]=geoNode._mesh._texCoords[q];gl.deleteBuffer(shape._webgl.buffers[q6+3]);texCoordBuffer=gl.createBuffer();shape._webgl.buffers[q6+3]=texCoordBuffer;texCoords=new Float32Array(shape._webgl.texcoords[q]);gl.bindBuffer(gl.ARRAY_BUFFER,texCoordBuffer);gl.bufferData(gl.ARRAY_BUFFER,texCoords,gl.STATIC_DRAW);gl.vertexAttribPointer(shape._webgl.shader.texCoord,geoNode._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);texCoords=null;}
+shape._dirty.texcoords=false;}
+if(shape._dirty.ids==true){if(shape._webgl.shader.texcoord!==undefined){shape._webgl.texcoords[q]=geoNode._mesh._texCoords[q];gl.deleteBuffer(shape._webgl.buffers[q6+3]);texCoordBuffer=gl.createBuffer();shape._webgl.buffers[q6+3]=texCoordBuffer;texCoords=new Float32Array(shape._webgl.texcoords[q]);gl.bindBuffer(gl.ARRAY_BUFFER,texCoordBuffer);gl.bufferData(gl.ARRAY_BUFFER,texCoords,gl.STATIC_DRAW);gl.vertexAttribPointer(shape._webgl.shader.texCoord,geoNode._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);texCoords=null;}
+shape._dirty.texcoords=false;}}}
+else
+{}
+if(shape._webgl.imageGeometry!=0){for(t=0;t<shape._webgl.texture.length;++t){shape._webgl.texture[t].updateTexture();}
+geoNode.unsetGeoDirty();shape.unsetGeoDirty();}
+if(!needFullReInit){return;}}
+else if(!(x3dom.isa(geoNode,x3dom.nodeTypes.Text)||x3dom.isa(geoNode,x3dom.nodeTypes.BinaryGeometry)||x3dom.isa(geoNode,x3dom.nodeTypes.PopGeometry)||x3dom.isa(geoNode,x3dom.nodeTypes.ExternalGeometry))&&(!geoNode||geoNode._mesh._positions[0].length<1))
+{if(x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS<2&&x3dom.isa(geoNode,x3dom.nodeTypes.ImageGeometry)){x3dom.debug.logError("Can't render ImageGeometry nodes with only "+
+x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS+" vertex texture units. Please upgrade your GPU!");}
+else{x3dom.debug.logError("NO VALID MESH OR NO VERTEX POSITIONS SET!");}
+return;}
+shape.unsetDirty();if(!shape._cleanupGLObjects)
+{shape._cleanupGLObjects=function(force,delGL)
+{if(this._webgl&&((arguments.length>0&&force)||this._parentNodes.length==0))
+{var sp=this._webgl.shader;for(var q=0;q<this._webgl.positions.length;q++){var q6=6*q;if(sp.position!==undefined){gl.deleteBuffer(this._webgl.buffers[q6+1]);gl.deleteBuffer(this._webgl.buffers[q6]);}
+if(sp.normal!==undefined){gl.deleteBuffer(this._webgl.buffers[q6+2]);}
+if(sp.texcoord!==undefined){gl.deleteBuffer(this._webgl.buffers[q6+3]);}
+if(sp.color!==undefined){gl.deleteBuffer(this._webgl.buffers[q6+4]);}
+if(sp.id!==undefined){gl.deleteBuffer(this._webgl.buffers[q6+5]);}}
+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);}}
+if(delGL===undefined)
+delGL=true;if(delGL){delete this._webgl;x3dom.BinaryContainerLoader.outOfMemory=false;}}};}
+shape._webgl={positions:geoNode._mesh._positions,normals:geoNode._mesh._normals,texcoords:geoNode._mesh._texCoords,colors:geoNode._mesh._colors,indexes:geoNode._mesh._indices,indexType:gl.UNSIGNED_SHORT,coordType:gl.FLOAT,normalType:gl.FLOAT,texCoordType:gl.FLOAT,colorType:gl.FLOAT,texture:[],dirtyLighting:x3dom.Utils.checkDirtyLighting(viewarea),imageGeometry:0,binaryGeometry:0,popGeometry:0,externalGeometry:0};textures=shape.getTextures();for(t=0;t<textures.length;++t){shape._webgl.texture.push(new x3dom.Texture(gl,shape._nameSpace.doc,this.cache,textures[t]));}
+shape._webgl.shader=this.cache.getShaderByProperties(gl,shape,shape.getShaderProperties(viewarea));var sp=shape._webgl.shader;var currAttribs=0;shape._webgl.buffers=[];shape._webgl.dynamicFields=[];if(x3dom.isa(geoNode,x3dom.nodeTypes.X3DBinaryContainerGeometryNode))
+{shape._webgl.primType=[];for(var primCnt=0;primCnt<geoNode._vf.primType.length;++primCnt)
+{shape._webgl.primType.push(x3dom.Utils.primTypeDic(gl,geoNode._vf.primType[primCnt]));}}
+else
+{shape._webgl.primType=x3dom.Utils.primTypeDic(gl,geoNode._mesh._primType);}
+if(x3dom.isa(geoNode,x3dom.nodeTypes.ExternalGeometry))
+{geoNode.updateRenderData(shape,sp,gl,viewarea,this);}
+else if(x3dom.isa(geoNode,x3dom.nodeTypes.BinaryGeometry))
+{x3dom.BinaryContainerLoader.setupBinGeo(shape,sp,gl,viewarea,this);}
+else if(x3dom.isa(geoNode,x3dom.nodeTypes.PopGeometry))
+{x3dom.BinaryContainerLoader.setupPopGeo(shape,sp,gl,viewarea,this);}
+else if(x3dom.isa(geoNode,x3dom.nodeTypes.ImageGeometry))
+{x3dom.BinaryContainerLoader.setupImgGeo(shape,sp,gl,viewarea,this);}
+else
+{for(q=0;q<shape._webgl.positions.length;q++)
+{q6=6*q;if(sp.position!==undefined){indicesBuffer=gl.createBuffer();shape._webgl.buffers[q6]=indicesBuffer;if(x3dom.caps.INDEX_UINT&&(shape._webgl.positions[0].length/3>65535)){indexArray=new Uint32Array(shape._webgl.indexes[q]);shape._webgl.indexType=gl.UNSIGNED_INT;}
+else{indexArray=new Uint16Array(shape._webgl.indexes[q]);shape._webgl.indexType=gl.UNSIGNED_SHORT;}
+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[q6+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,geoNode._mesh._numPosComponents,shape._webgl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);vertices=null;}
+if(sp.normal!==undefined||shape._webgl.normals[q]){normalBuffer=gl.createBuffer();shape._webgl.buffers[q6+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,geoNode._mesh._numNormComponents,shape._webgl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);normals=null;}
+if(sp.texcoord!==undefined){var texcBuffer=gl.createBuffer();shape._webgl.buffers[q6+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,geoNode._mesh._numTexComponents,shape._webgl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);texCoords=null;}
+if(sp.color!==undefined){colorBuffer=gl.createBuffer();shape._webgl.buffers[q6+4]=colorBuffer;var 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,geoNode._mesh._numColComponents,shape._webgl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);colors=null;}}
+for(var df in geoNode._mesh._dynamicFields)
+{if(!geoNode._mesh._dynamicFields.hasOwnProperty(df))
+continue;var attrib=geoNode._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;}}}};Context.prototype.setupScene=function(gl,bgnd){var sphere=null;var texture=null;var that=this;if(bgnd._webgl!==undefined){if(!bgnd._dirty){return;}
+if(bgnd._webgl.texture!==undefined&&bgnd._webgl.texture){gl.deleteTexture(bgnd._webgl.texture);}
+if(bgnd._cleanupGLObjects){bgnd._cleanupGLObjects();}
+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.cache.getShader(gl,x3dom.shader.BACKGROUND_CUBETEXTURE);bgnd._webgl.texture=x3dom.Utils.createTextureCube(gl,bgnd._nameSpace.doc,url,true,bgnd._vf.withCredentials,true,false);}
+else{bgnd._webgl={positions:[-w,-h,0,-w,h,0,w,-h,0,w,h,0],indexes:[0,1,2,3],buffers:[{},{}]};url=bgnd._nameSpace.getURL(url[0]);bgnd._webgl.texture=x3dom.Utils.createTexture2D(gl,bgnd._nameSpace.doc,url,true,bgnd._vf.withCredentials,true,false);bgnd._webgl.primType=gl.TRIANGLE_STRIP;bgnd._webgl.shader=this.cache.getShader(gl,x3dom.shader.BACKGROUND_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=x3dom.Utils.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||bgnd._vf.groundColor.length==1){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];}
+if(n==0&&bgnd._vf.groundColor.length==1){sky[sky.length]=Math.PI/2;colors[colors.length]=bgnd._vf.groundColor[0];}
+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++){interp._vf.set_fraction=i/(N-1.0);interp.fieldChanged("set_fraction");tmp[i]=interp._vf.value_changed;}
+tmp.reverse();var alpha=Math.floor((1.0-bgnd.getTransparency())*255);for(i=0;i<tmp.length;i++){arr.push(Math.floor(tmp[i].r*255),Math.floor(tmp[i].g*255),Math.floor(tmp[i].b*255),alpha);}
+var pixels=new Uint8Array(arr);var format=gl.RGBA;N=pixels.length/4;gl.bindTexture(gl.TEXTURE_2D,texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_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.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.cache.getShader(gl,x3dom.shader.BACKGROUND_SKYTEXTURE);}
+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._cleanupGLObjects=function(){var sp=this._webgl.shader;if(sp.position!==undefined){gl.deleteBuffer(this._webgl.buffers[0]);gl.deleteBuffer(this._webgl.buffers[1]);}
+if(sp.texcoord!==undefined){gl.deleteBuffer(this._webgl.buffers[2]);}};}
+bgnd._webgl.render=function(gl,mat_view,mat_proj)
+{var sp=bgnd._webgl.shader;var alpha=1.0-bgnd.getTransparency();var mat_scene=null;var projMatrix_22=mat_proj._22,projMatrix_23=mat_proj._23;var camPos=mat_view.e3();if((sp!==undefined&&sp!==null)&&(sp.texcoord!==undefined&&sp.texcoord!==null)&&(bgnd._webgl.texture!==undefined&&bgnd._webgl.texture!==null)){gl.clearColor(0,0,0,alpha);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);that.stateManager.frontFace(gl.CCW);that.stateManager.disable(gl.CULL_FACE);that.stateManager.disable(gl.DEPTH_TEST);that.stateManager.disable(gl.BLEND);that.stateManager.useProgram(sp);if(!sp.tex){sp.tex=0;}
+mat_proj._22=100001/99999;mat_proj._23=200000/99999;mat_view._03=0;mat_view._13=0;mat_view._23=0;mat_scene=mat_proj.mult(mat_view);sp.modelViewProjectionMatrix=mat_scene.toGL();mat_view._03=camPos.x;mat_view._13=camPos.y;mat_view._23=camPos.z;mat_proj._22=projMatrix_22;mat_proj._23=projMatrix_23;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,bgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_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);gl.bindBuffer(gl.ARRAY_BUFFER,bgnd._webgl.buffers[2]);gl.vertexAttribPointer(sp.texcoord,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.texcoord);gl.drawElements(bgnd._webgl.primType,bgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);gl.disableVertexAttribArray(sp.position);gl.disableVertexAttribArray(sp.texcoord);gl.clear(gl.DEPTH_BUFFER_BIT);}
+else if(!sp||!bgnd._webgl.texture||(bgnd._webgl.texture.textureCubeReady!==undefined&&bgnd._webgl.texture.textureCubeReady!==true)){var bgCol=bgnd.getSkyColor().toGL();gl.clearColor(bgCol[0],bgCol[1],bgCol[2],alpha);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);}
+else{gl.clearColor(0,0,0,alpha);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT|gl.STENCIL_BUFFER_BIT);that.stateManager.frontFace(gl.CCW);that.stateManager.disable(gl.CULL_FACE);that.stateManager.disable(gl.DEPTH_TEST);that.stateManager.disable(gl.BLEND);that.stateManager.useProgram(sp);if(!sp.tex){sp.tex=0;}
+if(bgnd._webgl.texture.textureCubeReady){mat_proj._22=100001/99999;mat_proj._23=200000/99999;mat_view._03=0;mat_view._13=0;mat_view._23=0;mat_scene=mat_proj.mult(mat_view);sp.modelViewProjectionMatrix=mat_scene.toGL();mat_view._03=camPos.x;mat_view._13=camPos.y;mat_view._23=camPos.z;mat_proj._22=projMatrix_22;mat_proj._23=projMatrix_23;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_CUBE_MAP,bgnd._webgl.texture);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.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);}
+else{gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,bgnd._webgl.texture);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.LINEAR);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAG_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);gl.drawElements(bgnd._webgl.primType,bgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);gl.disableVertexAttribArray(sp.position);gl.activeTexture(gl.TEXTURE0);if(bgnd._webgl.texture.textureCubeReady){gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);}
+else{gl.bindTexture(gl.TEXTURE_2D,null);}
+gl.clear(gl.DEPTH_BUFFER_BIT);}};};Context.prototype.setupFgnds=function(gl,scene){if(scene._fgnd!==undefined){return;}
+var that=this;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.cache.getShader(gl,x3dom.shader.FRONTGROUND_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;that.stateManager.frontFace(gl.CCW);that.stateManager.disable(gl.CULL_FACE);that.stateManager.disable(gl.DEPTH_TEST);that.stateManager.useProgram(sp);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.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,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);gl.drawElements(scene._fgnd._webgl.primType,scene._fgnd._webgl.indexes.length,gl.UNSIGNED_SHORT,0);gl.disableVertexAttribArray(sp.position);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);};};Context.prototype.renderShadowPass=function(gl,viewarea,mat_scene,mat_view,targetFbo,camOffset,isCameraView)
+{var scene=viewarea._scene;var sp=scene._webgl.shadowShader;this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,targetFbo.fbo);this.stateManager.viewport(0,0,targetFbo.width,targetFbo.height);this.stateManager.useProgram(sp);sp.cameraView=isCameraView;sp.offset=camOffset;{sp.PG_precisionLevel=1.0;sp.PG_powPrecision=1.0;sp.PG_maxBBSize=[0,0,0];sp.PG_bbMin=[0,0,0];sp.PG_bbMaxModF=[0,0,0];sp.PG_bboxShiftVec=[0,0,0];}
+gl.clearColor(1.0,1.0,1.0,0.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.enable(gl.CULL_FACE);this.stateManager.disable(gl.BLEND);var bgCenter=x3dom.fields.SFVec3f.NullVector.toGL();var bgSize=x3dom.fields.SFVec3f.OneVector.toGL();var env=scene.getEnvironment();var excludeTrans=env._vf.shadowExcludeTransparentObjects;var i,n=scene.drawableCollection.length;for(i=0;i<n;i++)
+{var drawable=scene.drawableCollection.get(i);var trafo=drawable.transform;var shape=drawable.shape;var s_gl=shape._webgl;if(!s_gl||(excludeTrans&&drawable.sortType=='transparent')){continue;}
+var s_geo=shape._cf.geometry.node;var s_msh=s_geo._mesh;sp.modelViewProjectionMatrix=mat_scene.mult(trafo).toGL();sp.imageGeometry=s_gl.imageGeometry;sp.popGeometry=s_gl.popGeometry;if(s_gl.coordType!=gl.FLOAT){if(!s_gl.popGeometry&&(x3dom.Utils.isUnsignedType(s_geo._vf.coordType))){sp.bgCenter=s_geo.getMin().toGL();}
+else{sp.bgCenter=s_geo._vf.position.toGL();}
+sp.bgSize=s_geo._vf.size.toGL();sp.bgPrecisionMax=s_geo.getPrecisionMax('coordType');}
+else{sp.bgCenter=bgCenter;sp.bgSize=bgSize;sp.bgPrecisionMax=1;}
+if(s_gl.colorType!=gl.FLOAT){sp.bgPrecisionColMax=s_geo.getPrecisionMax('colorType');}
+if(s_gl.texCoordType!=gl.FLOAT){sp.bgPrecisionTexMax=s_geo.getPrecisionMax('texCoordType');}
+if(s_gl.imageGeometry!=0&&!x3dom.caps.MOBILE)
+{sp.IG_bboxMin=s_geo.getMin().toGL();sp.IG_bboxMax=s_geo.getMax().toGL();sp.IG_implicitMeshSize=s_geo._vf.implicitMeshSize.toGL();var coordTex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_coords0");if(coordTex){sp.IG_coordTextureWidth=coordTex.texture.width;sp.IG_coordTextureHeight=coordTex.texture.height;}
+if(s_gl.imageGeometry==1){var indexTex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_index");if(indexTex){sp.IG_indexTextureWidth=indexTex.texture.width;sp.IG_indexTextureHeight=indexTex.texture.height;}
+gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,indexTex.texture);gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,coordTex.texture);}
+else{gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,coordTex.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_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);var texUnit=0;if(s_geo.getIndexTexture()){if(!sp.IG_indexTexture){sp.IG_indexTexture=texUnit++;}}
+if(s_geo.getCoordinateTexture(0)){if(!sp.IG_coordinateTexture){sp.IG_coordinateTexture=texUnit++;}}}
+if(shape.isSolid()){this.stateManager.enable(gl.CULL_FACE);if(shape.isCCW()){this.stateManager.frontFace(gl.CCW);}
+else{this.stateManager.frontFace(gl.CW);}}
+else{this.stateManager.disable(gl.CULL_FACE);}
+if(s_gl.popGeometry){var model_view=mat_view.mult(trafo);this.updatePopState(drawable,s_geo,sp,s_gl,scene,model_view,viewarea,this.x3dElem.runtime.fps);}
+var q_n;if(s_gl.externalGeometry!=0)
+{q_n=s_gl.primType.length;}
+else
+{q_n=s_gl.positions.length;}
+for(var q=0;q<q_n;q++){var q6=6*q;var v,v_n,offset;if(!(sp.position!==undefined&&s_gl.buffers[q6+1]&&(s_gl.indexes[q]||s_gl.externalGeometry!=0)))
+continue;if(s_gl.buffers[q6]){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,s_gl.buffers[q6]);}
+gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+1]);gl.vertexAttribPointer(sp.position,s_msh._numPosComponents,s_gl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(s_gl.binaryGeometry>0||s_gl.popGeometry>0){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawElements(s_gl.primType[v],s_geo._vf.vertexCount[v],s_gl.indexType,x3dom.Utils.getByteAwareOffset(offset,s_gl.indexType,gl));offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.binaryGeometry<0||s_gl.popGeometry<0||s_gl.imageGeometry){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawArrays(s_gl.primType[v],offset,s_geo._vf.vertexCount[v]);offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.externalGeometry==1)
+{gl.drawElements(s_gl.primType[q],s_gl.drawCount[q],s_gl.indexType,s_gl.indexOffset[q]);}
+else if(s_gl.externalGeometry==-1)
+{gl.drawArrays(s_gl.primType[q],0,s_gl.drawCount[q]);}
+else if(s_geo.hasIndexOffset()){var indOff=shape.tessellationProperties();for(v=0,v_n=indOff.length;v<v_n;v++){gl.drawElements(s_gl.primType,indOff[v].count,s_gl.indexType,indOff[v].offset*x3dom.Utils.getOffsetMultiplier(s_gl.indexType,gl));}}
+else if(s_gl.indexes[q].length==0){gl.drawArrays(s_gl.primType,0,s_gl.positions[q].length/3);}
+else{gl.drawElements(s_gl.primType,s_gl.indexes[q].length,s_gl.indexType,0);}
+gl.disableVertexAttribArray(sp.position);}
+if(s_gl.imageGeometry!=0&&!x3dom.caps.MOBILE){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);if(s_gl.imageGeometry==1){gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,null);}}}
+gl.flush();this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,null);};Context.prototype.renderPickingPass=function(gl,scene,mat_view,mat_scene,from,sceneSize,pickMode,lastX,lastY,width,height)
+{var ps=scene._webgl.pickScale;var bufHeight=scene._webgl.fboPick.height;var x=lastX*ps;var y=(bufHeight-1)-lastY*ps;var sp=null;switch(pickMode){case 0:sp=scene._webgl.pickShader;break;case 1:sp=scene._webgl.pickColorShader;break;case 2:sp=scene._webgl.pickTexCoordShader;break;case 3:sp=scene._webgl.pickShader24;break;case 4:sp=scene._webgl.pickShaderId;break;default:break;}
+if(!sp){return;}
+this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,scene._webgl.fboPick.fbo);this.stateManager.viewport(0,0,scene._webgl.fboPick.width,bufHeight);gl.clearColor(0.0,0.0,0.0,0.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);var viewarea=scene.drawableCollection.viewarea;var env=scene.getEnvironment();var n=scene.drawableCollection.length;if(env._vf.smallFeatureCulling&&env._lowPriorityThreshold<1&&viewarea.isMovingOrAnimating()){n=Math.floor(n*env._lowPriorityThreshold);if(!n&&scene.drawableCollection.length)
+n=1;}
+var bgCenter=x3dom.fields.SFVec3f.NullVector.toGL();var bgSize=x3dom.fields.SFVec3f.OneVector.toGL();this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.enable(gl.CULL_FACE);this.stateManager.disable(gl.BLEND);this.stateManager.useProgram(sp);if(pickMode==0)
+{sp.PG_precisionLevel=1.0;sp.PG_powPrecision=1.0;sp.PG_maxBBSize=[0,0,0];sp.PG_bbMin=[0,0,0];sp.PG_bbMaxModF=[0,0,0];sp.PG_bboxShiftVec=[0,0,0];}
+if(x3dom.Utils.needLineWidth){this.stateManager.lineWidth(2);}
+for(var i=0;i<n;i++)
+{var drawable=scene.drawableCollection.get(i);var trafo=drawable.transform;var shape=drawable.shape;var s_gl=shape._webgl;if(!s_gl||shape._objectID<1||!shape._vf.isPickable){continue;}
+var s_geo=shape._cf.geometry.node;var s_app=shape._cf.appearance.node;var s_msh=s_geo._mesh;sp.modelMatrix=trafo.toGL();sp.modelViewProjectionMatrix=mat_scene.mult(trafo).toGL();sp.lowBit=(shape._objectID&255)/255.0;sp.highBit=(shape._objectID>>>8)/255.0;sp.from=from.toGL();sp.sceneSize=sceneSize;sp.imageGeometry=s_gl.imageGeometry;sp.popGeometry=s_gl.popGeometry;sp.writeShadowIDs=(s_gl.binaryGeometry!=0&&s_geo._vf.idsPerVertex)?(x3dom.nodeTypes.Shape.objectID+2):0;sp.visibilityMap=0.0;if(s_gl.coordType!=gl.FLOAT){if(!s_gl.popGeometry&&(x3dom.Utils.isUnsignedType(s_geo._vf.coordType))){sp.bgCenter=s_geo.getMin().toGL();}
+else{sp.bgCenter=s_geo._vf.position.toGL();}
+sp.bgSize=s_geo._vf.size.toGL();sp.bgPrecisionMax=s_geo.getPrecisionMax('coordType');}
+else{sp.bgCenter=bgCenter;sp.bgSize=bgSize;sp.bgPrecisionMax=1;}
+if(s_gl.colorType!=gl.FLOAT){sp.bgPrecisionColMax=s_geo.getPrecisionMax('colorType');}
+if(s_gl.texCoordType!=gl.FLOAT){sp.bgPrecisionTexMax=s_geo.getPrecisionMax('texCoordType');}
+if(s_gl.imageGeometry!=0&&!x3dom.caps.MOBILE)
+{sp.IG_bboxMin=s_geo.getMin().toGL();sp.IG_bboxMax=s_geo.getMax().toGL();sp.IG_implicitMeshSize=s_geo._vf.implicitMeshSize.toGL();var coordTex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_coords0");if(coordTex){sp.IG_coordTextureWidth=coordTex.texture.width;sp.IG_coordTextureHeight=coordTex.texture.height;}
+if(s_gl.imageGeometry==1){var indexTex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_index");if(indexTex){sp.IG_indexTextureWidth=indexTex.texture.width;sp.IG_indexTextureHeight=indexTex.texture.height;}
+gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,indexTex.texture);gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,coordTex.texture);}
+else{gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,coordTex.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_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);var texUnit=0;if(s_geo.getIndexTexture()){if(!sp.IG_indexTexture){sp.IG_indexTexture=texUnit++;}}
+if(s_geo.getCoordinateTexture(0)){if(!sp.IG_coordinateTexture){sp.IG_coordinateTexture=texUnit++;}}}
+else if(s_gl.binaryGeometry!=0&&s_geo._vf.idsPerVertex){var shader=s_app._shader;if(shader&&x3dom.isa(s_app._shader,x3dom.nodeTypes.CommonSurfaceShader)){if(shader.getMultiVisibilityMap()){sp.visibilityMap=1.0;sp.multiVisibilityMap=0;var visTex=x3dom.Utils.findTextureByName(s_gl.texture,"multiVisibilityMap");sp.multiVisibilityWidth=visTex.texture.width;sp.multiVisibilityHeight=visTex.texture.height;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,visTex.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_MAG_FILTER,gl.NEAREST);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MIN_FILTER,gl.NEAREST);}}}
+if(shape.isSolid()){this.stateManager.enable(gl.CULL_FACE);if(shape.isCCW()){this.stateManager.frontFace(gl.CCW);}
+else{this.stateManager.frontFace(gl.CW);}}
+else{this.stateManager.disable(gl.CULL_FACE);}
+var depthMode=s_app?s_app._cf.depthMode.node:null;if(depthMode)
+{if(depthMode._vf.enableDepthTest)
+{this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(!depthMode._vf.readOnly);this.stateManager.depthFunc(x3dom.Utils.depthFunc(gl,depthMode._vf.depthFunc));this.stateManager.depthRange(depthMode._vf.zNearRange,depthMode._vf.zFarRange);}
+else
+{this.stateManager.disable(gl.DEPTH_TEST);}}
+else
+{this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(true);this.stateManager.depthFunc(gl.LEQUAL);}
+if(s_gl.popGeometry){var model_view=mat_view.mult(trafo);this.updatePopState(drawable,s_geo,sp,s_gl,scene,model_view,viewarea,this.x3dElem.runtime.fps);}
+var q_n;if(s_gl.externalGeometry!=0)
+{q_n=s_gl.primType.length;}
+else
+{q_n=s_gl.positions.length;}
+for(var q=0;q<q_n;q++){var q6=6*q;var v,v_n,offset;if(!(sp.position!==undefined&&s_gl.buffers[q6+1]&&(s_gl.indexes[q]||s_gl.externalGeometry!=0)))
+continue;if(s_gl.buffers[q6]){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,s_gl.buffers[q6]);}
+gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+1]);gl.vertexAttribPointer(sp.position,s_msh._numPosComponents,s_gl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(sp.texcoord!==undefined&&s_gl.buffers[q6+3]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+3]);gl.vertexAttribPointer(sp.texcoord,s_msh._numTexComponents,s_gl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+if(sp.color!==undefined&&s_gl.buffers[q6+4]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+4]);gl.vertexAttribPointer(sp.color,s_msh._numColComponents,s_gl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);}
+if(sp.id!==undefined&&s_gl.buffers[q6+5]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+5]);if(s_gl.binaryGeometry!=0&&s_geo._vf["idsPerVertex"]==true)
+{gl.vertexAttribPointer(sp.id,1,gl.FLOAT,false,4,0);gl.enableVertexAttribArray(sp.id);}
+else
+{}}
+if(s_gl.binaryGeometry>0||s_gl.popGeometry>0){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawElements(s_gl.primType[v],s_geo._vf.vertexCount[v],s_gl.indexType,x3dom.Utils.getByteAwareOffset(offset,s_gl.indexType,gl));offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.binaryGeometry<0||s_gl.popGeometry<0||s_gl.imageGeometry){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawArrays(s_gl.primType[v],offset,s_geo._vf.vertexCount[v]);offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.externalGeometry==1)
+{gl.drawElements(s_gl.primType[q],s_gl.drawCount[q],s_gl.indexType,s_gl.indexOffset[q]);}
+else if(s_gl.externalGeometry==-1)
+{gl.drawArrays(s_gl.primType[q],0,s_gl.drawCount[q]);}
+else if(s_geo.hasIndexOffset()){var indOff=shape.tessellationProperties();for(v=0,v_n=indOff.length;v<v_n;v++){gl.drawElements(s_gl.primType,indOff[v].count,s_gl.indexType,indOff[v].offset*x3dom.Utils.getOffsetMultiplier(s_gl.indexType,gl));}}
+else if(s_gl.indexes[q].length==0){gl.drawArrays(s_gl.primType,0,s_gl.positions[q].length/3);}
+else{gl.drawElements(s_gl.primType,s_gl.indexes[q].length,s_gl.indexType,0);}
+gl.disableVertexAttribArray(sp.position);if(sp.texcoord!==undefined&&s_gl.buffers[q6+3]){gl.disableVertexAttribArray(sp.texcoord);}
+if(sp.color!==undefined&&s_gl.buffers[q6+4]){gl.disableVertexAttribArray(sp.color);}
+if(sp.id!==undefined&&s_gl.buffers[q6+5]){gl.disableVertexAttribArray(sp.id);}}
+if(s_gl.imageGeometry!=0&&!x3dom.caps.MOBILE){gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);if(s_gl.imageGeometry==1){gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,null);}}}
+if(x3dom.Utils.needLineWidth){this.stateManager.lineWidth(1);}
+if(depthMode){this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(true);this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.depthRange(0,1);}
+gl.flush();try{var data=new Uint8Array(4*width*height);gl.readPixels(x,y,width,height,gl.RGBA,gl.UNSIGNED_BYTE,data);scene._webgl.fboPick.pixelData=data;}
+catch(se){scene._webgl.fboPick.pixelData=[];x3dom.debug.logException(se+" (cannot pick)");}
+this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,null);};Context.prototype.renderShape=function(drawable,viewarea,slights,numLights,mat_view,mat_scene,mat_light,mat_proj,gl)
+{var shape=drawable.shape;var transform=drawable.transform;if(!shape||!shape._webgl||!transform){x3dom.debug.logError("[Context|RenderShape] No valid Shape!");return;}
+var s_gl=shape._webgl;var sp=s_gl.shader;if(!sp){x3dom.debug.logError("[Context|RenderShape] No Shader is set!");return;}
+var changed=this.stateManager.useProgram(sp);var s_app=shape._cf.appearance.node;var s_geo=shape._cf.geometry.node;var s_msh=s_geo._mesh;var scene=viewarea._scene;var tex=null;if(s_gl.coordType!=gl.FLOAT){if(!s_gl.popGeometry&&(x3dom.Utils.isUnsignedType(s_geo._vf.coordType))){sp.bgCenter=s_geo.getMin().toGL();}
+else{sp.bgCenter=s_geo._vf.position.toGL();}
+sp.bgSize=s_geo._vf.size.toGL();sp.bgPrecisionMax=s_geo.getPrecisionMax('coordType');}
+else{sp.bgCenter=[0,0,0];sp.bgSize=[1,1,1];sp.bgPrecisionMax=1;}
+if(s_gl.colorType!=gl.FLOAT){sp.bgPrecisionColMax=s_geo.getPrecisionMax('colorType');}
+else{sp.bgPrecisionColMax=1;}
+if(s_gl.texCoordType!=gl.FLOAT){sp.bgPrecisionTexMax=s_geo.getPrecisionMax('texCoordType');}
+else{sp.bgPrecisionTexMax=1;}
+if(s_gl.normalType!=gl.FLOAT){sp.bgPrecisionNorMax=s_geo.getPrecisionMax('normalType');}
+else{sp.bgPrecisionNorMax=1;}
+if(s_gl.imageGeometry!=0){sp.IG_bboxMin=s_geo.getMin().toGL();sp.IG_bboxMax=s_geo.getMax().toGL();sp.IG_implicitMeshSize=s_geo._vf.implicitMeshSize.toGL();tex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_coords0");if(tex){sp.IG_coordTextureWidth=tex.texture.width;sp.IG_coordTextureHeight=tex.texture.height;}
+if(s_gl.imageGeometry==1){tex=x3dom.Utils.findTextureByName(s_gl.texture,"IG_index");if(tex){sp.IG_indexTextureWidth=tex.texture.width;sp.IG_indexTextureHeight=tex.texture.height;}}
+tex=null;}
+var fog=scene.getFog();if(fog&&changed){sp.fogColor=fog._vf.color.toGL();sp.fogRange=fog._vf.visibilityRange;sp.fogType=(fog._vf.fogType=="LINEAR")?0.0:1.0;}
+var mat=s_app?s_app._cf.material.node:null;var shader=s_app?s_app._shader:null;var isUserDefinedShader=shader&&x3dom.isa(shader,x3dom.nodeTypes.ComposedShader);if(s_gl.csshader){sp.diffuseColor=shader._vf.diffuseFactor.toGL();sp.specularColor=shader._vf.specularFactor.toGL();sp.emissiveColor=shader._vf.emissiveFactor.toGL();sp.shininess=shader._vf.shininessFactor;sp.ambientIntensity=(shader._vf.ambientFactor.x+
+shader._vf.ambientFactor.y+
+shader._vf.ambientFactor.z)/3;sp.transparency=1.0-shader._vf.alphaFactor;if(shader.getDisplacementMap()){tex=x3dom.Utils.findTextureByName(s_gl.texture,"displacementMap");sp.displacementWidth=tex.texture.width;sp.displacementHeight=tex.texture.height;sp.displacementFactor=shader._vf.displacementFactor;sp.displacementAxis=(shader._vf.displacementAxis=="x")?0.0:(shader._vf.displacementAxis=="y")?1.0:2.0;}
+else if(shader.getDiffuseDisplacementMap()){tex=x3dom.Utils.findTextureByName(s_gl.texture,"diffuseDisplacementMap");sp.displacementWidth=tex.texture.width;sp.displacementHeight=tex.texture.height;sp.displacementFactor=shader._vf.displacementFactor;sp.displacementAxis=(shader._vf.displacementAxis=="x")?0.0:(shader._vf.displacementAxis=="y")?1.0:2.0;}
+if(shader.getMultiDiffuseAlphaMap()){tex=x3dom.Utils.findTextureByName(s_gl.texture,"multiDiffuseAlphaMap");sp.multiDiffuseAlphaWidth=tex.texture.width;sp.multiDiffuseAlphaHeight=tex.texture.height;}
+if(shader.getMultiVisibilityMap()){tex=x3dom.Utils.findTextureByName(s_gl.texture,"multiVisibilityMap");sp.multiVisibilityWidth=tex.texture.width;sp.multiVisibilityHeight=tex.texture.height;}}
+else if(mat){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.diffuseColor=[1.0,1.0,1.0];sp.specularColor=[0.0,0.0,0.0];sp.emissiveColor=[0.0,0.0,0.0];sp.shininess=0.0;sp.ambientIntensity=1.0;sp.transparency=0.0;}
+if(shader){if(isUserDefinedShader){for(var fName in shader._vf){if(shader._vf.hasOwnProperty(fName)&&fName!=='language'){var field=shader._vf[fName];if(field){if(field.toGL){sp[fName]=field.toGL();}
+else{sp[fName]=field;}}}}}
+else if(x3dom.isa(shader,x3dom.nodeTypes.CommonSurfaceShader)){s_gl.csshader=shader;}}
+for(var p=0;p<numLights&&changed;p++){var light_transform=mat_view.mult(slights[p].getCurrentTransform());if(x3dom.isa(slights[p],x3dom.nodeTypes.DirectionalLight)){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']=light_transform.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)){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']=light_transform.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)){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']=light_transform.multMatrixVec(slights[p]._vf.direction).toGL();sp['light'+p+'_Attenuation']=slights[p]._vf.attenuation.toGL();sp['light'+p+'_Location']=light_transform.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&&changed){numLights=(numLights)?numLights:0;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;sp['light'+numLights+'_ShadowIntensity']=0.0;}
+var depthMode=s_app?s_app._cf.depthMode.node:null;if(depthMode)
+{if(depthMode._vf.enableDepthTest)
+{this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(!depthMode._vf.readOnly);this.stateManager.depthFunc(x3dom.Utils.depthFunc(gl,depthMode._vf.depthFunc));this.stateManager.depthRange(depthMode._vf.zNearRange,depthMode._vf.zFarRange);}
+else
+{this.stateManager.disable(gl.DEPTH_TEST);}}
+else
+{this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(true);this.stateManager.depthFunc(gl.LEQUAL);}
+var blendMode=s_app?s_app._cf.blendMode.node:null;if(blendMode)
+{var srcFactor=x3dom.Utils.blendFunc(gl,blendMode._vf.srcFactor);var destFactor=x3dom.Utils.blendFunc(gl,blendMode._vf.destFactor);if(srcFactor&&destFactor)
+{this.stateManager.enable(gl.BLEND);this.stateManager.blendFuncSeparate(srcFactor,destFactor,gl.ONE,gl.ONE);this.stateManager.blendColor(blendMode._vf.color.r,blendMode._vf.color.g,blendMode._vf.color.b,1.0-blendMode._vf.colorTransparency);this.stateManager.blendEquation(x3dom.Utils.blendEquation(gl,blendMode._vf.equation));}
+else
+{this.stateManager.disable(gl.BLEND);}}
+else
+{this.stateManager.enable(gl.BLEND);this.stateManager.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE);}
+var colorMaskMode=s_app?s_app._cf.colorMaskMode.node:null;if(colorMaskMode)
+{this.stateManager.colorMask(colorMaskMode._vf.maskR,colorMaskMode._vf.maskG,colorMaskMode._vf.maskB,colorMaskMode._vf.maskA);}
+else
+{this.stateManager.colorMask(true,true,true,true);}
+var lineProperties=s_app?s_app._cf.lineProperties.node:null;if(lineProperties)
+{this.stateManager.lineWidth(lineProperties._vf.linewidthScaleFactor);}
+else if(x3dom.Utils.needLineWidth)
+{this.stateManager.lineWidth(1);}
+if(shape.isSolid()){this.stateManager.enable(gl.CULL_FACE);if(shape.isCCW()){this.stateManager.frontFace(gl.CCW);}
+else{this.stateManager.frontFace(gl.CW);}}
+else{this.stateManager.disable(gl.CULL_FACE);}
+var model_view=mat_view.mult(transform);var model_view_inv=model_view.inverse();sp.modelViewMatrix=model_view.toGL();sp.viewMatrix=mat_view.toGL();sp.normalMatrix=model_view_inv.transpose().toGL();sp.modelViewMatrixInverse=model_view_inv.toGL();sp.modelViewProjectionMatrix=mat_scene.mult(transform).toGL();if(isUserDefinedShader){sp.projectionMatrix=mat_proj.toGL();sp.worldMatrix=transform.toGL();sp.worldInverseTranspose=transform.inverse().transpose().toGL();sp.viewMatrixInverse=mat_view.inverse().toGL();}
+if(s_gl.popGeometry){this.updatePopState(drawable,s_geo,sp,s_gl,scene,model_view,viewarea,this.x3dElem.runtime.fps);}
+for(var cnt=0,cnt_n=s_gl.texture.length;cnt<cnt_n;cnt++){tex=s_gl.texture[cnt];gl.activeTexture(gl.TEXTURE0+cnt);gl.bindTexture(tex.type,tex.texture);gl.texParameteri(tex.type,gl.TEXTURE_WRAP_S,tex.wrapS);gl.texParameteri(tex.type,gl.TEXTURE_WRAP_T,tex.wrapT);gl.texParameteri(tex.type,gl.TEXTURE_MAG_FILTER,tex.magFilter);gl.texParameteri(tex.type,gl.TEXTURE_MIN_FILTER,tex.minFilter);if(!shader||!isUserDefinedShader){if(!sp[tex.samplerName])
+sp[tex.samplerName]=cnt;}}
+if(s_app&&s_app._cf.textureTransform.node){var texTrafo=s_app.texTransformMatrix();sp.texTrafoMatrix=texTrafo.toGL();}
+var attrib=null;var df,df_n=s_gl.dynamicFields.length;for(df=0;df<df_n;df++){attrib=s_gl.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]);}}
+var v,v_n,offset,q_n;if(s_gl.externalGeometry!=0)
+{q_n=s_gl.primType.length;}
+else
+{q_n=s_gl.positions.length;}
+for(var q=0;q<q_n;q++){var q6=6*q;if(!(sp.position!==undefined&&s_gl.buffers[q6+1]&&(s_gl.indexes[q]||s_gl.externalGeometry!=0)))
+continue;if(s_gl.buffers[q6]){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,s_gl.buffers[q6]);}
+gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+1]);gl.vertexAttribPointer(sp.position,s_msh._numPosComponents,s_gl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(sp.normal!==undefined&&s_gl.buffers[q6+2]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+2]);gl.vertexAttribPointer(sp.normal,s_msh._numNormComponents,s_gl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);}
+if(sp.texcoord!==undefined&&s_gl.buffers[q6+3]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+3]);gl.vertexAttribPointer(sp.texcoord,s_msh._numTexComponents,s_gl.texCoordType,false,shape._texCoordStrideOffset[0],shape._texCoordStrideOffset[1]);gl.enableVertexAttribArray(sp.texcoord);}
+if(sp.color!==undefined&&s_gl.buffers[q6+4]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+4]);gl.vertexAttribPointer(sp.color,s_msh._numColComponents,s_gl.colorType,false,shape._colorStrideOffset[0],shape._colorStrideOffset[1]);gl.enableVertexAttribArray(sp.color);}
+if(sp.id!==undefined&&s_gl.buffers[q6+5]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+5]);if(s_gl.binaryGeometry!=0&&s_geo._vf["idsPerVertex"]==true)
+{gl.vertexAttribPointer(sp.id,1,gl.FLOAT,false,4,0);gl.enableVertexAttribArray(sp.id);}
+else
+{}}
+if(s_gl.popGeometry!=0&&s_gl.buffers[q6+5]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+5]);gl.vertexAttribPointer(sp.PG_vertexID,1,gl.FLOAT,false,4,0);gl.enableVertexAttribArray(sp.PG_vertexID);}
+var indOff,renderMode=viewarea.getRenderMode();if(renderMode>0){var polyMode=(renderMode==1)?gl.POINTS:gl.LINES;if(s_gl.binaryGeometry>0||s_gl.popGeometry>0){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawElements(polyMode,s_geo._vf.vertexCount[v],s_gl.indexType,x3dom.Utils.getByteAwareOffset(offset,s_gl.indexType,gl));offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.binaryGeometry<0||s_gl.popGeometry<0||s_gl.imageGeometry){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawArrays(polyMode,offset,s_geo._vf.vertexCount[v]);offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.externalGeometry==1)
+{gl.drawElements(polyMode,s_gl.drawCount[q],s_gl.indexType,s_gl.indexOffset[q]);}
+else if(s_gl.externalGeometry==-1)
+{gl.drawArrays(polyMode,0,s_gl.drawCount[q]);}
+else if(s_geo.hasIndexOffset()){indOff=shape.tessellationProperties();for(v=0,v_n=indOff.length;v<v_n;v++){gl.drawElements(polyMode,indOff[v].count,s_gl.indexType,indOff[v].offset*x3dom.Utils.getOffsetMultiplier(s_gl.indexType,gl));}}
+else if(s_gl.indexes[q].length==0){gl.drawArrays(polyMode,0,s_gl.positions[q].length/3);}
+else{gl.drawElements(polyMode,s_gl.indexes[q].length,s_gl.indexType,0);}}
+else{if(s_gl.binaryGeometry>0||s_gl.popGeometry>0){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawElements(s_gl.primType[v],s_geo._vf.vertexCount[v],s_gl.indexType,x3dom.Utils.getByteAwareOffset(offset,s_gl.indexType,gl));offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.binaryGeometry<0||s_gl.popGeometry<0||s_gl.imageGeometry){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawArrays(s_gl.primType[v],offset,s_geo._vf.vertexCount[v]);offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.externalGeometry==1)
+{gl.drawElements(s_gl.primType[q],s_gl.drawCount[q],s_gl.indexType,s_gl.indexOffset[q]);}
+else if(s_gl.externalGeometry==-1)
+{gl.drawArrays(s_gl.primType[q],0,s_gl.drawCount[q]);}
+else if(s_geo.hasIndexOffset()){indOff=shape.tessellationProperties();for(v=0,v_n=indOff.length;v<v_n;v++){gl.drawElements(s_gl.primType,indOff[v].count,s_gl.indexType,indOff[v].offset*x3dom.Utils.getOffsetMultiplier(s_gl.indexType,gl));}}
+else if(s_gl.indexes[q].length==0){gl.drawArrays(s_gl.primType,0,s_gl.positions[q].length/3);}
+else{gl.drawElements(s_gl.primType,s_gl.indexes[q].length,s_gl.indexType,0);}}
+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(sp.id!==undefined&&s_gl.buffers[q6+5]){gl.disableVertexAttribArray(sp.id);}
+if(s_gl.popGeometry!=0&&sp.PG_vertexID!==undefined){gl.disableVertexAttribArray(sp.PG_vertexID);}}
+for(df=0;df<df_n;df++){attrib=s_gl.dynamicFields[df];if(sp[attrib.name]!==undefined){gl.disableVertexAttribArray(sp[attrib.name]);}}
+if(s_gl.imageGeometry){v_n=s_geo._vf.vertexCount.length;this.numDrawCalls+=v_n;for(v=0;v<v_n;v++){if(s_gl.primType[v]==gl.TRIANGLE_STRIP)
+this.numFaces+=(s_geo._vf.vertexCount[v]-2);else
+this.numFaces+=(s_geo._vf.vertexCount[v]/3);this.numCoords+=s_geo._vf.vertexCount[v];}}
+else{this.numCoords+=s_msh._numCoords;this.numFaces+=s_msh._numFaces;if(s_gl.binaryGeometry||s_gl.popGeometry){this.numDrawCalls+=s_geo._vf.vertexCount.length;}
+else if(s_geo.hasIndexOffset()){this.numDrawCalls+=shape.tessellationProperties().length;}
+else{this.numDrawCalls+=q_n;}}
+if(depthMode){this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.depthMask(true);this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.depthRange(0,1);}
+if(blendMode){this.stateManager.enable(gl.BLEND);this.stateManager.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE);this.stateManager.blendColor(1,1,1,1);this.stateManager.blendEquation(gl.FUNC_ADD);}
+if(colorMaskMode){this.stateManager.colorMask(true,true,true,true);}
+if(lineProperties){this.stateManager.lineWidth(1);}
+var s_gl_tex=s_gl.texture;cnt_n=s_gl_tex?s_gl_tex.length:0;for(cnt=0;cnt<cnt_n;cnt++){if(!s_gl_tex[cnt])
+continue;if(s_app&&s_app._cf.texture.node){tex=s_app._cf.texture.node.getTexture(cnt);gl.activeTexture(gl.TEXTURE0+cnt);if(x3dom.isa(tex,x3dom.nodeTypes.X3DEnvironmentTextureNode)){gl.bindTexture(gl.TEXTURE_CUBE_MAP,null);}
+else{gl.bindTexture(gl.TEXTURE_2D,null);}}}};Context.prototype.updatePopState=function(drawable,popGeo,sp,s_gl,scene,model_view,viewarea,currFps)
+{var tol=x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor*popGeo._vf.precisionFactor;if(currFps<=1||viewarea.isMovingOrAnimating()){tol*=x3dom.nodeTypes.PopGeometry.PrecisionFactorOnMove;}
+var currentLOD=16;if(tol>0){var viewpoint=scene.getViewpoint();var imgPlaneHeightAtDistOne=viewpoint.getImgPlaneHeightAtDistOne();var near=viewpoint.getNear();var center=model_view.multMatrixPnt(popGeo._vf.position);var tightRad=model_view.multMatrixVec(popGeo._vf.size).length()*0.5;var largestRad=model_view.multMatrixVec(popGeo._vf.maxBBSize).length()*0.5;var dist=Math.max(-center.z-tightRad,near);var projPixelLength=dist*(imgPlaneHeightAtDistOne/viewarea._height);var arg=(2*largestRad)/(tol*projPixelLength);currentLOD=Math.ceil(Math.log(arg)/0.693147180559945);currentLOD=(currentLOD<1)?1:((currentLOD>16)?16:currentLOD);}
+var minPrec=popGeo._vf.minPrecisionLevel,maxPrec=popGeo._vf.maxPrecisionLevel;currentLOD=(minPrec!=-1&&currentLOD<minPrec)?minPrec:currentLOD;currentLOD=(maxPrec!=-1&&currentLOD>maxPrec)?maxPrec:currentLOD;var currentLOD_min=(s_gl.levelsAvailable<currentLOD)?s_gl.levelsAvailable:currentLOD;currentLOD=currentLOD_min;if(tol<=1)
+currentLOD=(currentLOD==popGeo.getNumLevels())?16:currentLOD;var hasIndex=popGeo._vf.indexedRendering;var p_msh=popGeo._mesh;p_msh._numCoords=0;p_msh._numFaces=0;for(var i=0;i<currentLOD_min;++i){var numVerticesAtLevel_i=s_gl.numVerticesAtLevel[i];p_msh._numCoords+=numVerticesAtLevel_i;p_msh._numFaces+=(hasIndex?popGeo.getNumIndicesByLevel(i):numVerticesAtLevel_i)/3;}
+x3dom.nodeTypes.PopGeometry.numRenderedVerts+=p_msh._numCoords;x3dom.nodeTypes.PopGeometry.numRenderedTris+=p_msh._numFaces;p_msh.currentLOD=currentLOD;popGeo.adaptVertexCount(hasIndex?p_msh._numFaces*3:p_msh._numCoords);sp.PG_maxBBSize=popGeo._vf.maxBBSize.toGL();sp.PG_bbMin=popGeo._bbMinBySize;sp.PG_numAnchorVertices=popGeo._vf.numAnchorVertices;sp.PG_bbMaxModF=popGeo._vf.bbMaxModF.toGL();sp.PG_bboxShiftVec=popGeo._vf.bbShiftVec.toGL();sp.PG_precisionLevel=currentLOD;sp.PG_powPrecision=x3dom.nodeTypes.PopGeometry.powLUT[currentLOD-1];};Context.prototype.pickValue=function(viewarea,x,y,buttonState,viewMat,sceneMat)
+{var gl=this.ctx3d;var scene=viewarea._scene;if(!gl||!scene||!scene._webgl||!scene.drawableCollection){return false;}
+var pm=scene._vf.pickMode.toLowerCase();var pickMode=0;switch(pm){case"box":return false;case"idbuf":pickMode=0;break;case"idbuf24":pickMode=3;break;case"idbufid":pickMode=4;break;case"color":pickMode=1;break;case"texcoord":pickMode=2;break;}
+x3dom.Utils.startMeasure("picking");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 min=x3dom.fields.SFVec3f.copy(scene._lastMin);var max=x3dom.fields.SFVec3f.copy(scene._lastMax);var from=mat_view.inverse().e3();var _min=x3dom.fields.SFVec3f.copy(from);var _max=x3dom.fields.SFVec3f.copy(from);if(_min.x>min.x){_min.x=min.x;}
+if(_min.y>min.y){_min.y=min.y;}
+if(_min.z>min.z){_min.z=min.z;}
+if(_max.x<max.x){_max.x=max.x;}
+if(_max.y<max.y){_max.y=max.y;}
+if(_max.z<max.z){_max.z=max.z;}
+scene._lastMin.setValues(_min);scene._lastMax.setValues(_max);var sceneSize=scene._lastMax.subtract(scene._lastMin).length();var cctowc=viewarea.getCCtoWCMatrix();scene._lastMin.setValues(min);scene._lastMax.setValues(max);var baseID=x3dom.nodeTypes.Shape.objectID+2;this.renderPickingPass(gl,scene,mat_view,mat_scene,from,sceneSize,pickMode,x,y,2,2);var pixelData=scene._webgl.fboPick.pixelData;if(pixelData&&pixelData.length)
+{var pickPos=new x3dom.fields.SFVec3f(0,0,0);var pickNorm=new x3dom.fields.SFVec3f(0,0,1);var index=0;var objId=pixelData[index+3],shapeId;var pixelOffset=1.0/scene._webgl.pickScale;var denom=1.0/256.0;var dist,line,lineoff,right,up;if(pickMode==0){objId+=256*pixelData[index+2];dist=(pixelData[index]/255.0)*denom+
+(pixelData[index+1]/255.0);line=viewarea.calcViewRay(x,y,cctowc);pickPos=line.pos.add(line.dir.multiply(dist*sceneSize));index=4;dist=(pixelData[index]/255.0)*denom+
+(pixelData[index+1]/255.0);lineoff=viewarea.calcViewRay(x+pixelOffset,y,cctowc);right=lineoff.pos.add(lineoff.dir.multiply(dist*sceneSize));right=right.subtract(pickPos).normalize();index=8;dist=(pixelData[index]/255.0)*denom+
+(pixelData[index+1]/255.0);lineoff=viewarea.calcViewRay(x,y-pixelOffset,cctowc);up=lineoff.pos.add(lineoff.dir.multiply(dist*sceneSize));up=up.subtract(pickPos).normalize();pickNorm=right.cross(up).normalize();}
+else if(pickMode==3){objId+=256*pixelData[index+2]+
+65536*pixelData[index+1];dist=pixelData[index]/255.0;line=viewarea.calcViewRay(x,y,cctowc);pickPos=line.pos.add(line.dir.multiply(dist*sceneSize));index=4;dist=pixelData[index]/255.0;lineoff=viewarea.calcViewRay(x+pixelOffset,y,cctowc);right=lineoff.pos.add(lineoff.dir.multiply(dist*sceneSize));right=right.subtract(pickPos).normalize();index=8;dist=pixelData[index]/255.0;lineoff=viewarea.calcViewRay(x,y-pixelOffset,cctowc);up=lineoff.pos.add(lineoff.dir.multiply(dist*sceneSize));up=up.subtract(pickPos).normalize();pickNorm=right.cross(up).normalize();}
+else if(pickMode==4){objId+=256*pixelData[index+2];shapeId=pixelData[index+1];shapeId+=256*pixelData[index];if(objId==0&&(shapeId>0&&shapeId<baseID)){objId=shapeId;}}
+else{pickPos.x=pixelData[index];pickPos.y=pixelData[index+1];pickPos.z=pixelData[index+2];}
+var eventType="shadowObjectIdChanged";var shadowObjectIdChanged,event;var button=Math.max(buttonState>>>8,buttonState&255);if(objId>=baseID){objId-=baseID;var hitObject;if(pickMode!=4){viewarea._pickingInfo.pickPos=pickPos;viewarea._pick.setValues(pickPos);viewarea._pickingInfo.pickNorm=pickNorm;viewarea._pickNorm.setValues(pickNorm);viewarea._pickingInfo.pickObj=null;viewarea._pickingInfo.lastClickObj=null;hitObject=scene._xmlNode;}
+else{viewarea._pickingInfo.pickObj=x3dom.nodeTypes.Shape.idMap.nodeID[shapeId];hitObject=viewarea._pickingInfo.pickObj._xmlNode;}
+shadowObjectIdChanged=(viewarea._pickingInfo.shadowObjectId!=objId);viewarea._pickingInfo.lastShadowObjectId=viewarea._pickingInfo.shadowObjectId;viewarea._pickingInfo.shadowObjectId=objId;if((shadowObjectIdChanged||button)&&scene._xmlNode&&(scene._xmlNode["on"+eventType]||scene._xmlNode.hasAttribute("on"+eventType)||scene._listeners[eventType]))
+{event={target:scene._xmlNode,type:eventType,button:button,mouseup:((buttonState>>>8)>0),layerX:x,layerY:y,shadowObjectId:objId,worldX:pickPos.x,worldY:pickPos.y,worldZ:pickPos.z,normalX:pickNorm.x,normalY:pickNorm.y,normalZ:pickNorm.z,hitPnt:pickPos.toGL(),hitObject:hitObject,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;},preventDefault:function(){this.cancelBubble=true;}};scene.callEvtHandler(("on"+eventType),event);}
+if(scene._shadowIdMap&&scene._shadowIdMap.mapping&&objId<scene._shadowIdMap.mapping.length){var shIds=scene._shadowIdMap.mapping[objId].usage;if(!line){line=viewarea.calcViewRay(x,y,cctowc);}
+for(var c=0;c<shIds.length;c++){var shObj=scene._nameSpace.defMap[shIds[c]];if(shObj&&shObj.doIntersect(line)){viewarea._pickingInfo.pickObj=shObj;break;}}
+for(var n=0;n<scene._nameSpace.childSpaces.length;n++)
+{for(var c=0;c<shIds.length;c++){var shObj=scene._nameSpace.childSpaces[n].defMap[shIds[c]];if(shObj&&shObj.doIntersect(line)){viewarea._pickingInfo.pickObj=shObj;break;}}}}}
+else{shadowObjectIdChanged=(viewarea._pickingInfo.shadowObjectId!=-1);viewarea._pickingInfo.shadowObjectId=-1;if(shadowObjectIdChanged&&scene._xmlNode&&(scene._xmlNode["on"+eventType]||scene._xmlNode.hasAttribute("on"+eventType)||scene._listeners[eventType]))
+{event={target:scene._xmlNode,type:eventType,button:button,mouseup:((buttonState>>>8)>0),layerX:x,layerY:y,shadowObjectId:viewarea._pickingInfo.shadowObjectId,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;},preventDefault:function(){this.cancelBubble=true;}};scene.callEvtHandler(("on"+eventType),event);}
+if(objId>0){viewarea._pickingInfo.pickPos=pickPos;viewarea._pickingInfo.pickNorm=pickNorm;viewarea._pickingInfo.pickObj=x3dom.nodeTypes.Shape.idMap.nodeID[objId];}
+else{viewarea._pickingInfo.pickObj=null;viewarea._pickingInfo.lastClickObj=null;}}}
+var pickTime=x3dom.Utils.stopMeasure("picking");this.x3dElem.runtime.addMeasurement('PICKING',pickTime);return true;};Context.prototype.pickRect=function(viewarea,x1,y1,x2,y2)
+{var gl=this.ctx3d;var scene=viewarea?viewarea._scene:null;if(!gl||!scene||!scene._webgl||!scene.drawableCollection)
+return false;var from=viewarea._last_mat_view.inverse().e3();var sceneSize=scene._lastMax.subtract(scene._lastMin).length();var x=(x1<=x2)?x1:x2;var y=(y1>=y2)?y1:y2;var width=(1+Math.abs(x2-x1))*scene._webgl.pickScale;var height=(1+Math.abs(y2-y1))*scene._webgl.pickScale;this.renderPickingPass(gl,scene,viewarea._last_mat_view,viewarea._last_mat_scene,from,sceneSize,0,x,y,(width<1)?1:width,(height<1)?1:height);var index;var pickedObjects=[];for(index=0;scene._webgl.fboPick.pixelData&&index<scene._webgl.fboPick.pixelData.length;index+=4){var objId=scene._webgl.fboPick.pixelData[index+3]+
+scene._webgl.fboPick.pixelData[index+2]*256;if(objId>0)
+pickedObjects.push(objId);}
+pickedObjects.sort();var pickedObjectsTemp=(function(arr){var a=[],l=arr.length;for(var i=0;i<l;i++){for(var j=i+1;j<l;j++){if(arr[i]===arr[j])
+j=++i;}
+a.push(arr[i]);}
+return a;})(pickedObjects);pickedObjects=pickedObjectsTemp;var pickedNodes=[];for(index=0;index<pickedObjects.length;index++){var obj=pickedObjects[index];obj=x3dom.nodeTypes.Shape.idMap.nodeID[obj];obj=(obj&&obj._xmlNode)?obj._xmlNode:null;if(obj)
+pickedNodes.push(obj);}
+return pickedNodes;};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;var texProp=null;var type=gl.UNSIGNED_BYTE;var shadowType=gl.UNSIGNED_BYTE;var nearestFilt=false;if(x3dom.caps.FP_TEXTURES&&!x3dom.caps.MOBILE){type=gl.FLOAT;shadowType=gl.FLOAT;if(!x3dom.caps.FPL_TEXTURES){nearestFilt=true;}}
+var shadowedLights,numShadowMaps;var i,j,n,size,sizeAvailable;var texType,refinementPos;var vertices=[-1,-1,1,-1,-1,1,-1,1,1,-1,1,1];scene.updateVolume();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=x3dom.Utils.initFBO(gl,scene._webgl._currFboWidth,scene._webgl._currFboHeight,gl.UNSIGNED_BYTE,false,true);scene._webgl.fboPick.pixelData=null;scene._webgl.pickShader=this.cache.getShader(gl,x3dom.shader.PICKING);scene._webgl.pickShader24=this.cache.getShader(gl,x3dom.shader.PICKING_24);scene._webgl.pickShaderId=this.cache.getShader(gl,x3dom.shader.PICKING_ID);scene._webgl.pickColorShader=this.cache.getShader(gl,x3dom.shader.PICKING_COLOR);scene._webgl.pickTexCoordShader=this.cache.getShader(gl,x3dom.shader.PICKING_TEXCOORD);scene._webgl.normalShader=this.cache.getShader(gl,x3dom.shader.NORMAL);scene._webgl.fboShadow=[];shadowedLights=viewarea.getShadowedLights();n=shadowedLights.length;for(i=0;i<n;i++)
+{size=shadowedLights[i]._vf.shadowMapSize;if(!x3dom.isa(shadowedLights[i],x3dom.nodeTypes.PointLight))
+numShadowMaps=Math.max(1,Math.min(shadowedLights[i]._vf.shadowCascades,6));else
+numShadowMaps=6;scene._webgl.fboShadow[i]=[];for(j=0;j<numShadowMaps;j++)
+scene._webgl.fboShadow[i][j]=x3dom.Utils.initFBO(gl,size,size,shadowType,false,true);}
+if(scene._webgl.fboShadow.length>0)
+scene._webgl.fboScene=x3dom.Utils.initFBO(gl,this.canvas.width,this.canvas.height,shadowType,false,true);scene._webgl.fboBlur=[];for(i=0;i<n;i++)
+{size=scene._webgl.fboShadow[i][0].height;sizeAvailable=false;for(j=0;j<scene._webgl.fboBlur.length;j++){if(size==scene._webgl.fboBlur[j].height)
+sizeAvailable=true;}
+if(!sizeAvailable)
+scene._webgl.fboBlur[scene._webgl.fboBlur.length]=x3dom.Utils.initFBO(gl,size,size,shadowType,false,true);}
+scene._webgl.ppBuffer=gl.createBuffer();gl.bindBuffer(gl.ARRAY_BUFFER,scene._webgl.ppBuffer);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);scene._webgl.shadowShader=this.cache.getShader(gl,x3dom.shader.SHADOW);scene._webgl.refinement={stamps:new Array(2),positionBuffer:gl.createBuffer()};gl.bindBuffer(gl.ARRAY_BUFFER,scene._webgl.refinement.positionBuffer);gl.bufferData(gl.ARRAY_BUFFER,new Float32Array(vertices),gl.STATIC_DRAW);for(rtl_i=0;rtl_i<rtl_n;rtl_i++){rt_tex=rentex[rtl_i];texProp=rt_tex._cf.textureProperties.node;texType=rt_tex.requirePingPong()?gl.UNSIGNED_BYTE:type;rt_tex._webgl={};rt_tex._webgl.fbo=x3dom.Utils.initFBO(gl,rt_tex._vf.dimensions[0],rt_tex._vf.dimensions[1],texType,(texProp&&texProp._vf.generateMipMaps),!rt_tex.requirePingPong());rt_tex._cleanupGLObjects=function(retainTex){if(!retainTex)
+gl.deleteTexture(this._webgl.fbo.tex);if(this._webgl.fbo.rbo)
+gl.deleteRenderbuffer(this._webgl.fbo.rbo);gl.bindFramebuffer(gl.FRAMEBUFFER,null);gl.deleteFramebuffer(this._webgl.fbo.fbo);this._webgl.fbo.rbo=null;this._webgl.fbo.fbo=null;};if(rt_tex.requirePingPong()){refinementPos=rt_tex._vf.dimensions[0]+"x"+rt_tex._vf.dimensions[1];if(scene._webgl.refinement[refinementPos]===undefined){scene._webgl.refinement[refinementPos]=x3dom.Utils.initFBO(gl,rt_tex._vf.dimensions[0],rt_tex._vf.dimensions[1],texType,false,false);}
+rt_tex._webgl.texture=null;}}
+viewarea._last_mat_view=x3dom.fields.SFMatrix4f.identity();viewarea._last_mat_proj=x3dom.fields.SFMatrix4f.identity();viewarea._last_mat_scene=x3dom.fields.SFMatrix4f.identity();this._calledViewpointChangedHandler=false;}
+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=x3dom.Utils.initFBO(gl,fboWidth,fboHeight,scene._webgl.fboPick.type,false,true);scene._webgl.fboPick.pixelData=null;x3dom.debug.logInfo("Refreshed picking FBO to size ("+fboWidth+", "+fboHeight+")");}
+for(rtl_i=0;rtl_i<rtl_n;rtl_i++){rt_tex=rentex[rtl_i];if(rt_tex._webgl&&rt_tex._webgl.fbo&&rt_tex._webgl.fbo.width==rt_tex._vf.dimensions[0]&&rt_tex._webgl.fbo.height==rt_tex._vf.dimensions[1])
+continue;rt_tex.invalidateGLObject();if(rt_tex._cleanupGLObjects)
+rt_tex._cleanupGLObjects();else
+rt_tex._cleanupGLObjects=function(retainTex){if(!retainTex)
+gl.deleteTexture(this._webgl.fbo.tex);if(this._webgl.fbo.rbo)
+gl.deleteRenderbuffer(this._webgl.fbo.rbo);gl.bindFramebuffer(gl.FRAMEBUFFER,null);gl.deleteFramebuffer(this._webgl.fbo.fbo);this._webgl.fbo.rbo=null;this._webgl.fbo.fbo=null;};texProp=rt_tex._cf.textureProperties.node;texType=rt_tex.requirePingPong()?gl.UNSIGNED_BYTE:type;rt_tex._webgl={};rt_tex._webgl.fbo=x3dom.Utils.initFBO(gl,rt_tex._vf.dimensions[0],rt_tex._vf.dimensions[1],texType,(texProp&&texProp._vf.generateMipMaps),!rt_tex.requirePingPong());if(rt_tex.requirePingPong()){refinementPos=rt_tex._vf.dimensions[0]+"x"+rt_tex._vf.dimensions[1];if(scene._webgl.refinement[refinementPos]===undefined){scene._webgl.refinement[refinementPos]=x3dom.Utils.initFBO(gl,rt_tex._vf.dimensions[0],rt_tex._vf.dimensions[1],texType,false,false);}
+rt_tex._webgl.texture=null;}
+x3dom.debug.logInfo("Init/resize RenderedTexture_"+rtl_i+" to size "+
+rt_tex._vf.dimensions[0]+" x "+rt_tex._vf.dimensions[1]);}
+shadowedLights=viewarea.getShadowedLights();n=shadowedLights.length;for(i=0;i<n;i++){size=shadowedLights[i]._vf.shadowMapSize;if(!x3dom.isa(shadowedLights[i],x3dom.nodeTypes.PointLight))
+numShadowMaps=Math.max(1,Math.min(shadowedLights[i]._vf.shadowCascades,6));else
+numShadowMaps=6;if(typeof scene._webgl.fboShadow[i]==="undefined"||scene._webgl.fboShadow[i].length!=numShadowMaps||scene._webgl.fboShadow[i][0].height!=size){scene._webgl.fboShadow[i]=[];for(j=0;j<numShadowMaps;j++){scene._webgl.fboShadow[i][j]=x3dom.Utils.initFBO(gl,size,size,shadowType,false,true);}}}
+for(i=0;i<n;i++){size=scene._webgl.fboShadow[i][0].height;sizeAvailable=false;for(j=0;j<scene._webgl.fboBlur.length;j++){if(size==scene._webgl.fboBlur[j].height)
+sizeAvailable=true;}
+if(!sizeAvailable)
+scene._webgl.fboBlur[scene._webgl.fboBlur.length]=x3dom.Utils.initFBO(gl,size,size,shadowType,false,true);}
+if(scene._webgl.fboShadow.length>0&&typeof scene._webgl.fboScene=="undefined"||scene._webgl.fboScene&&(this.canvas.width!=scene._webgl.fboScene.width||this.canvas.height!=scene._webgl.fboScene.height)){scene._webgl.fboScene=x3dom.Utils.initFBO(gl,this.canvas.width,this.canvas.height,shadowType,false,true);}}
+var env=scene.getEnvironment();env.checkSanity();var bgnd=scene.getBackground();this.setupScene(gl,bgnd);this.numFaces=0;this.numCoords=0;this.numDrawCalls=0;var mat_proj=viewarea.getProjectionMatrix();var mat_view=viewarea.getViewMatrix();if(!this._calledViewpointChangedHandler||!viewarea._last_mat_view.equals(mat_view)){var e_viewpoint=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;},preventDefault:function(){this.cancelBubble=true;}};e_viewpoint.callEvtHandler(("on"+e_eventType),e_event);this._calledViewpointChangedHandler=true;}}
+catch(e_e){x3dom.debug.logException(e_e);}}
+viewarea._last_mat_view=mat_view;viewarea._last_mat_proj=mat_proj;var mat_scene=mat_proj.mult(mat_view);viewarea._last_mat_scene=mat_scene;scene.drawableCollection=null;if(!scene.drawableCollection)
+{var drawableCollectionConfig={viewArea:viewarea,sortTrans:env._vf.sortTrans,viewMatrix:mat_view,projMatrix:mat_proj,sceneMatrix:mat_scene,frustumCulling:true,smallFeatureThreshold:env._smallFeatureThreshold,context:this,gl:gl};scene.drawableCollection=new x3dom.DrawableCollection(drawableCollectionConfig);x3dom.Utils.startMeasure('traverse');scene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),scene.drawableCollection,true,false,0);var traverseTime=x3dom.Utils.stopMeasure('traverse');this.x3dElem.runtime.addMeasurement('TRAVERSE',traverseTime);}
+x3dom.Utils.startMeasure('sorting');scene.drawableCollection.sort();var sortTime=x3dom.Utils.stopMeasure('sorting');this.x3dElem.runtime.addMeasurement('SORT',sortTime);var slights=viewarea.getLights();var numLights=slights.length;var mat_light;var WCToLCMatrices=[];var lMatrices=[];var shadowCount=0;x3dom.Utils.startMeasure('shadow');for(var p=0;p<numLights;p++){if(slights[p]._vf.shadowIntensity>0.0){var lightMatrix=viewarea.getLightMatrix()[p];shadowMaps=scene._webgl.fboShadow[shadowCount];var offset=Math.max(0.0,Math.min(1.0,slights[p]._vf.shadowOffset));if(!x3dom.isa(slights[p],x3dom.nodeTypes.PointLight)){var numCascades=Math.max(1,Math.min(slights[p]._vf.shadowCascades,6));mat_light=viewarea.getWCtoLCMatricesCascaded(lightMatrix,slights[p],mat_proj);for(i=0;i<numCascades;i++){this.renderShadowPass(gl,viewarea,mat_light[i],mat_view,shadowMaps[i],offset,false);}}
+else{mat_light=viewarea.getWCtoLCMatricesPointLight(lightMatrix,slights[p],mat_proj);for(i=0;i<6;i++){this.renderShadowPass(gl,viewarea,mat_light[i],mat_view,shadowMaps[i],offset,false);}}
+shadowCount++;WCToLCMatrices[WCToLCMatrices.length]=mat_light;lMatrices[lMatrices.length]=lightMatrix;}}
+if(shadowCount>0){this.renderShadowPass(gl,viewarea,mat_scene,mat_view,scene._webgl.fboScene,0.0,true);var shadowTime=x3dom.Utils.stopMeasure('shadow');this.x3dElem.runtime.addMeasurement('SHADOW',shadowTime);}
+else{this.x3dElem.runtime.removeMeasurement('SHADOW');}
+mat_light=viewarea.getWCtoLCMatrix(viewarea.getLightMatrix()[0]);for(rtl_i=0;rtl_i<rtl_n;rtl_i++){this.renderRTPass(gl,viewarea,rentex[rtl_i]);}
+x3dom.Utils.startMeasure('render');this.stateManager.viewport(0,0,this.canvas.width,this.canvas.height);bgnd._webgl.render(gl,mat_view,mat_proj);x3dom.nodeTypes.PopGeometry.numRenderedVerts=0;x3dom.nodeTypes.PopGeometry.numRenderedTris=0;n=scene.drawableCollection.length;if(env._vf.smallFeatureCulling&&env._lowPriorityThreshold<1&&viewarea.isMovingOrAnimating()){n=Math.floor(n*env._lowPriorityThreshold);if(!n&&scene.drawableCollection.length)
+n=1;}
+this.stateManager.unsetProgram();for(i=0;i<n;i++){var drawable=scene.drawableCollection.get(i);this.renderShape(drawable,viewarea,slights,numLights,mat_view,mat_scene,mat_light,mat_proj,gl);}
+if(shadowCount>0)
+this.renderShadows(gl,viewarea,shadowedLights,WCToLCMatrices,lMatrices,mat_view,mat_proj,mat_scene);this.stateManager.disable(gl.BLEND);this.stateManager.disable(gl.DEPTH_TEST);viewarea._numRenderedNodes=n;if(viewarea._visDbgBuf!==undefined&&viewarea._visDbgBuf)
+{var pm=scene._vf.pickMode.toLowerCase();if(pm.indexOf("idbuf")==0||pm=="color"||pm=="texcoord"){this.stateManager.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(shadowCount>0){this.stateManager.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.fboScene.tex);}
+var row=3,col=2;for(i=0;i<shadowCount;i++){var shadowMaps=scene._webgl.fboShadow[i];for(j=0;j<shadowMaps.length;j++){this.stateManager.viewport(col*this.canvas.width/4,row*this.canvas.height/4,this.canvas.width/4,this.canvas.height/4);scene._fgnd._webgl.render(gl,shadowMaps[j].tex);if(col<2){col++;}else{col=0;row--;}}}
+for(rtl_i=0;rtl_i<rtl_n;rtl_i++){rt_tex=rentex[rtl_i];if(!rt_tex._webgl.fbo.fbo)
+continue;this.stateManager.viewport(rtl_i*this.canvas.width/8,5*this.canvas.height/8,this.canvas.width/8,this.canvas.height/8);scene._fgnd._webgl.render(gl,rt_tex._webgl.fbo.tex);}}
+gl.finish();var renderTime=x3dom.Utils.stopMeasure('render');this.x3dElem.runtime.addMeasurement('RENDER',renderTime);this.x3dElem.runtime.addMeasurement('DRAW',(n?renderTime/n:0));this.x3dElem.runtime.addInfo('#NODES:',scene.drawableCollection.numberOfNodes);this.x3dElem.runtime.addInfo('#SHAPES:',viewarea._numRenderedNodes);this.x3dElem.runtime.addInfo("#DRAWS:",this.numDrawCalls);this.x3dElem.runtime.addInfo("#POINTS:",this.numCoords);this.x3dElem.runtime.addInfo("#TRIS:",this.numFaces);};Context.prototype.renderPingPongPass=function(gl,viewarea,rt){var scene=viewarea._scene;var refinementPos=rt._vf.dimensions[0]+"x"+rt._vf.dimensions[1];var refinementFbo=scene._webgl.refinement[refinementPos];if(rt._currLoadLevel==0&&(!scene._webgl.refinement.stamps[0]||!scene._webgl.refinement.stamps[1])){scene._webgl.refinement.stamps[0]=this.cache.getTexture2D(gl,rt._nameSpace.doc,rt._nameSpace.getURL(rt._vf.stamp0),false,false,false,false);scene._webgl.refinement.stamps[1]=this.cache.getTexture2D(gl,rt._nameSpace.doc,rt._nameSpace.getURL(rt._vf.stamp1),false,false,false,false);}
+if(rt._currLoadLevel<rt._loadLevel){rt._currLoadLevel++;if(rt._webgl.texture)
+gl.deleteTexture(rt._webgl.texture);var filename=rt._vf.url[0]+"/"+rt._currLoadLevel+"."+rt._vf.format;rt._webgl.texture=x3dom.Utils.createTexture2D(gl,rt._nameSpace.doc,rt._nameSpace.getURL(filename),false,false,false,false);if(rt._vf.iterations%2===0)
+(rt._currLoadLevel%2!==0)?rt._repeat.x*=2.0:rt._repeat.y*=2.0;else
+(rt._currLoadLevel%2===0)?rt._repeat.x*=2.0:rt._repeat.y*=2.0;}
+if(!rt._webgl.texture.ready||!scene._webgl.refinement.stamps[0].ready||!scene._webgl.refinement.stamps[1].ready)
+return;this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,refinementFbo.fbo);this.stateManager.viewport(0,0,refinementFbo.width,refinementFbo.height);this.stateManager.disable(gl.BLEND);this.stateManager.disable(gl.CULL_FACE);this.stateManager.disable(gl.DEPTH_TEST);gl.clearColor(0,0,0,1);gl.clearDepth(1);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);var sp=this.cache.getShader(gl,x3dom.shader.TEXTURE_REFINEMENT);this.stateManager.useProgram(sp);gl.bindBuffer(gl.ARRAY_BUFFER,scene._webgl.refinement.positionBuffer);gl.vertexAttribPointer(sp.position,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);sp.stamp=0;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,scene._webgl.refinement.stamps[(rt._currLoadLevel+1)%2]);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.REPEAT);gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_WRAP_T,gl.REPEAT);if(rt._currLoadLevel>1){sp.lastTex=1;gl.activeTexture(gl.TEXTURE1);gl.bindTexture(gl.TEXTURE_2D,rt._webgl.fbo.tex);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);}
+sp.curTex=2;gl.activeTexture(gl.TEXTURE2);gl.bindTexture(gl.TEXTURE_2D,rt._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);sp.mode=rt._currLoadLevel-1;sp.repeat=rt._repeat.toGL();gl.drawArrays(gl.TRIANGLES,0,6);this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,rt._webgl.fbo.fbo);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);sp.mode=0;sp.curTex=2;gl.activeTexture(gl.TEXTURE2);gl.bindTexture(gl.TEXTURE_2D,refinementFbo.tex);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.drawArrays(gl.TRIANGLES,0,6);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);gl.disableVertexAttribArray(sp.position);this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,null);this.stateManager.viewport(0,0,this.canvas.width,this.canvas.height);if(rt._vf.autoRefinement)
+rt.nextLevel();if(rt._currLoadLevel==rt._vf.maxLevel)
+rt._currLoadLevel++;if(rt._webgl.fbo.mipMap){gl.bindTexture(gl.TEXTURE_2D,rt._webgl.fbo.tex);gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null);}
+if(!rt.requirePingPong()){gl.deleteTexture(rt._webgl.texture);delete rt._webgl.texture;rt._cleanupGLObjects(true);}
+rt._renderedImage++;};Context.prototype.renderRTPass=function(gl,viewarea,rt)
+{if(x3dom.isa(rt,x3dom.nodeTypes.RefinementTexture)){if(rt.requirePingPong()){this.renderPingPongPass(gl,viewarea,rt);}
+return;}
+switch(rt._vf.update.toUpperCase()){case"NONE":return;case"NEXT_FRAME_ONLY":if(!rt._needRenderUpdate){return;}
+rt._needRenderUpdate=false;break;case"ALWAYS":default:break;}
+var scene=viewarea._scene;var bgnd=null;var mat_view=rt.getViewMatrix();var mat_proj=rt.getProjectionMatrix();var mat_scene=mat_proj.mult(mat_view);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;}
+this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,rt._webgl.fbo.fbo);this.stateManager.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_view,mat_proj);}
+else{bgnd=rt._cf.background.node;this.setupScene(gl,bgnd);bgnd._webgl.render(gl,mat_view,mat_proj);}
+this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.enable(gl.CULL_FACE);this.stateManager.blendFuncSeparate(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA,gl.ONE,gl.ONE);this.stateManager.enable(gl.BLEND);var slights=viewarea.getLights();var numLights=slights.length;var transform,shape,drawable;var locScene=rt._cf.scene.node;if(!locScene||locScene===scene){n=scene.drawableCollection.length;if(rt._vf.showNormals){this.renderNormals(gl,scene,scene._webgl.normalShader,mat_view,mat_scene);}
+else{this.stateManager.unsetProgram();for(i=0;i<n;i++){drawable=scene.drawableCollection.get(i);this.renderShape(drawable,viewarea,slights,numLights,mat_view,mat_scene,mat_light,mat_proj,gl);}}}
+else{var env=scene.getEnvironment();var drawableCollectionConfig={viewArea:viewarea,sortTrans:env._vf.sortTrans,viewMatrix:mat_view,projMatrix:mat_proj,sceneMatrix:mat_scene,frustumCulling:false,smallFeatureThreshold:1,context:this,gl:gl};locScene.numberOfNodes=0;locScene.drawableCollection=new x3dom.DrawableCollection(drawableCollectionConfig);locScene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),locScene.drawableCollection,true,false,0);locScene.drawableCollection.sort();n=locScene.drawableCollection.length;if(rt._vf.showNormals){this.renderNormals(gl,locScene,scene._webgl.normalShader,mat_view,mat_scene);}
+else{this.stateManager.unsetProgram();for(i=0;i<n;i++){drawable=locScene.drawableCollection.get(i);if(!drawable.shape._vf.render){continue;}
+this.renderShape(drawable,viewarea,slights,numLights,mat_view,mat_scene,mat_light,mat_proj,gl);}}}
+this.stateManager.disable(gl.BLEND);this.stateManager.disable(gl.DEPTH_TEST);gl.flush();this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,null);if(rt._webgl.fbo.mipMap){gl.bindTexture(gl.TEXTURE_2D,rt._webgl.fbo.tex);gl.generateMipmap(gl.TEXTURE_2D);gl.bindTexture(gl.TEXTURE_2D,null);}
+for(i=0;i<m;i++){if(arr[i]!==0){rt._cf.excludeNodes.nodes[i]._vf.render=true;}}};Context.prototype.renderNormals=function(gl,scene,sp,mat_view,mat_scene)
+{if(!sp||!scene){return;}
+this.stateManager.depthFunc(gl.LEQUAL);this.stateManager.enable(gl.DEPTH_TEST);this.stateManager.enable(gl.CULL_FACE);this.stateManager.disable(gl.BLEND);this.stateManager.useProgram(sp);var bgCenter=x3dom.fields.SFVec3f.NullVector.toGL();var bgSize=x3dom.fields.SFVec3f.OneVector.toGL();for(var i=0,n=scene.drawableCollection.length;i<n;i++)
+{var drawable=scene.drawableCollection.get(i);var trafo=drawable.transform;var shape=drawable.shape;var s_gl=shape._webgl;if(!s_gl||!shape||!shape._vf.render){continue;}
+var s_geo=shape._cf.geometry.node;var s_msh=s_geo._mesh;var model_view_inv=mat_view.mult(trafo).inverse();sp.normalMatrix=model_view_inv.transpose().toGL();sp.modelViewProjectionMatrix=mat_scene.mult(trafo).toGL();sp.imageGeometry=s_gl.imageGeometry;if(s_gl.coordType!=gl.FLOAT){if(s_gl.popGeometry!=0||(s_msh._numPosComponents==4&&x3dom.Utils.isUnsignedType(s_geo._vf.coordType)))
+sp.bgCenter=s_geo.getMin().toGL();else
+sp.bgCenter=s_geo._vf.position.toGL();sp.bgSize=s_geo._vf.size.toGL();sp.bgPrecisionMax=s_geo.getPrecisionMax('coordType');}
+else{sp.bgCenter=bgCenter;sp.bgSize=bgSize;sp.bgPrecisionMax=1;}
+if(s_gl.normalType!=gl.FLOAT){sp.bgPrecisionNorMax=s_geo.getPrecisionMax('normalType');}
+else{sp.bgPrecisionNorMax=1;}
+if(shape.isSolid()){this.stateManager.enable(gl.CULL_FACE);if(shape.isCCW()){this.stateManager.frontFace(gl.CCW);}
+else{this.stateManager.frontFace(gl.CW);}}
+else{this.stateManager.disable(gl.CULL_FACE);}
+for(var q=0,q_n=s_gl.positions.length;q<q_n;q++){var q6=6*q;var v,v_n,offset;if(!(sp.position!==undefined&&s_gl.buffers[q6+1]&&s_gl.indexes[q]))
+continue;if(s_gl.buffers[q6]){gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER,s_gl.buffers[q6]);}
+gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+1]);gl.vertexAttribPointer(sp.position,s_msh._numPosComponents,s_gl.coordType,false,shape._coordStrideOffset[0],shape._coordStrideOffset[1]);gl.enableVertexAttribArray(sp.position);if(sp.normal!==undefined&&s_gl.buffers[q6+2]){gl.bindBuffer(gl.ARRAY_BUFFER,s_gl.buffers[q6+2]);gl.vertexAttribPointer(sp.normal,s_msh._numNormComponents,s_gl.normalType,false,shape._normalStrideOffset[0],shape._normalStrideOffset[1]);gl.enableVertexAttribArray(sp.normal);}
+if(s_gl.binaryGeometry>0||s_gl.popGeometry>0){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawElements(s_gl.primType[v],s_geo._vf.vertexCount[v],s_gl.indexType,x3dom.Utils.getByteAwareOffset(offset,s_gl.indexType,gl));offset+=s_geo._vf.vertexCount[v];}}
+else if(s_gl.binaryGeometry<0||s_gl.popGeometry<0||s_gl.imageGeometry){for(v=0,offset=0,v_n=s_geo._vf.vertexCount.length;v<v_n;v++){gl.drawArrays(s_gl.primType[v],offset,s_geo._vf.vertexCount[v]);offset+=s_geo._vf.vertexCount[v];}}
+else if(s_geo.hasIndexOffset()){var indOff=shape.tessellationProperties();for(v=0,v_n=indOff.length;v<v_n;v++){gl.drawElements(s_gl.primType,indOff[v].count,s_gl.indexType,indOff[v].offset*x3dom.Utils.getOffsetMultiplier(s_gl.indexType,gl));}}
+else if(s_gl.indexes[q].length==0){gl.drawArrays(s_gl.primType,0,s_gl.positions[q].length/3);}
+else{gl.drawElements(s_gl.primType,s_gl.indexes[q].length,s_gl.indexType,0);}
+gl.disableVertexAttribArray(sp.position);if(sp.normal!==undefined){gl.disableVertexAttribArray(sp.normal);}}}};Context.prototype.shutdown=function(viewarea){var gl=this.ctx3d;var scene=viewarea._scene;if(gl==null||!scene){return;}
+var bgnd=scene.getBackground();if(bgnd._webgl.position!==undefined){gl.deleteBuffer(bgnd._webgl.buffers[1]);gl.deleteBuffer(bgnd._webgl.buffers[0]);}
+var fgnd=scene._fgnd;if(fgnd._webgl.position!==undefined){gl.deleteBuffer(fgnd._webgl.buffers[1]);gl.deleteBuffer(fgnd._webgl.buffers[0]);}
+var n=scene.drawableCollection?scene.drawableCollection.length:0;for(var i=0;i<n;i++){var shape=scene.drawableCollection.get(i).shape;if(shape._cleanupGLObjects)
+shape._cleanupGLObjects(true);}
+this.cache.Release(gl);};Context.prototype.renderShadows=function(gl,viewarea,shadowedLights,wctolc,lMatrices,mat_view,mat_proj,mat_scene)
+{var scene=viewarea._scene;var texLimit=x3dom.caps.MAX_TEXTURE_IMAGE_UNITS;if(texLimit<7)
+return;var texUnits=1;var renderSplit=[0];var shadowMaps,numShadowMaps;var i,j,k;for(i=0;i<shadowedLights.length;i++)
+{var filterSize=shadowedLights[i]._vf.shadowFilterSize;shadowMaps=scene._webgl.fboShadow[i];numShadowMaps=shadowMaps.length;for(j=0;j<numShadowMaps;j++){this.blurTex(gl,scene,shadowMaps[j],filterSize);}
+texUnits+=6;if(texUnits>texLimit){renderSplit[renderSplit.length]=i;texUnits=7;}}
+renderSplit[renderSplit.length]=shadowedLights.length;var n=renderSplit.length-1;var mat_proj_inv=mat_proj.inverse();var mat_scene_inv=mat_scene.inverse();this.stateManager.enable(gl.BLEND);this.stateManager.blendFunc(gl.DST_COLOR,gl.ZERO);for(var s=0;s<n;s++)
+{var startIndex=renderSplit[s];var endIndex=renderSplit[s+1];var currentLights=[];for(k=startIndex;k<endIndex;k++)
+currentLights[currentLights.length]=shadowedLights[k];var sp=this.cache.getShadowRenderingShader(gl,currentLights);this.stateManager.useProgram(sp);gl.bindBuffer(gl.ARRAY_BUFFER,scene._webgl.ppBuffer);gl.vertexAttribPointer(sp.position,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);sp.sceneMap=0;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,scene._webgl.fboScene.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.inverseProj=mat_proj_inv.toGL();sp.inverseViewProj=mat_scene_inv.toGL();var mat_light;var lightMatrix;var shadowIndex=0;for(var p=0,pn=currentLights.length;p<pn;p++){lightMatrix=lMatrices[p+startIndex];mat_light=wctolc[p+startIndex];shadowMaps=scene._webgl.fboShadow[p+startIndex];numShadowMaps=mat_light.length;for(i=0;i<numShadowMaps;i++){gl.activeTexture(gl.TEXTURE1+shadowIndex);gl.bindTexture(gl.TEXTURE_2D,shadowMaps[i].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['light'+p+'_'+i+'_ShadowMap']=shadowIndex+1;sp['light'+p+'_'+i+'_Matrix']=mat_light[i].toGL();shadowIndex++;}
+sp['light'+p+'_ViewMatrix']=lightMatrix.toGL();if(!x3dom.isa(currentLights[p],x3dom.nodeTypes.PointLight)){for(j=0;j<numShadowMaps;j++){var numCascades=Math.max(1,Math.min(currentLights[p]._vf.shadowCascades,6));var splitFactor=Math.max(0,Math.min(currentLights[p]._vf.shadowSplitFactor,1));var splitOffset=Math.max(0,Math.min(currentLights[p]._vf.shadowSplitOffset,1));var splitDepths=viewarea.getShadowSplitDepths(numCascades,splitFactor,splitOffset,false,mat_proj);sp['light'+p+'_'+j+'_Split']=splitDepths[j+1];}}
+var light_transform=mat_view.mult(currentLights[p].getCurrentTransform());if(x3dom.isa(currentLights[p],x3dom.nodeTypes.DirectionalLight))
+{sp['light'+p+'_Type']=0.0;sp['light'+p+'_On']=(currentLights[p]._vf.on)?1.0:0.0;sp['light'+p+'_Direction']=light_transform.multMatrixVec(currentLights[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']=currentLights[p]._vf.shadowIntensity;sp['light'+p+'_ShadowCascades']=currentLights[p]._vf.shadowCascades;sp['light'+p+'_ShadowOffset']=Math.max(0.0,Math.min(1.0,currentLights[p]._vf.shadowOffset));}
+else if(x3dom.isa(currentLights[p],x3dom.nodeTypes.PointLight))
+{sp['light'+p+'_Type']=1.0;sp['light'+p+'_On']=(currentLights[p]._vf.on)?1.0:0.0;sp['light'+p+'_Direction']=[1.0,1.0,1.0];sp['light'+p+'_Attenuation']=currentLights[p]._vf.attenuation.toGL();sp['light'+p+'_Location']=light_transform.multMatrixPnt(currentLights[p]._vf.location).toGL();sp['light'+p+'_Radius']=currentLights[p]._vf.radius;sp['light'+p+'_BeamWidth']=0.0;sp['light'+p+'_CutOffAngle']=0.0;sp['light'+p+'_ShadowIntensity']=currentLights[p]._vf.shadowIntensity;sp['light'+p+'_ShadowOffset']=Math.max(0.0,Math.min(1.0,currentLights[p]._vf.shadowOffset));}
+else if(x3dom.isa(currentLights[p],x3dom.nodeTypes.SpotLight))
+{sp['light'+p+'_Type']=2.0;sp['light'+p+'_On']=(currentLights[p]._vf.on)?1.0:0.0;sp['light'+p+'_Direction']=light_transform.multMatrixVec(currentLights[p]._vf.direction).toGL();sp['light'+p+'_Attenuation']=currentLights[p]._vf.attenuation.toGL();sp['light'+p+'_Location']=light_transform.multMatrixPnt(currentLights[p]._vf.location).toGL();sp['light'+p+'_Radius']=currentLights[p]._vf.radius;sp['light'+p+'_BeamWidth']=currentLights[p]._vf.beamWidth;sp['light'+p+'_CutOffAngle']=currentLights[p]._vf.cutOffAngle;sp['light'+p+'_ShadowIntensity']=currentLights[p]._vf.shadowIntensity;sp['light'+p+'_ShadowCascades']=currentLights[p]._vf.shadowCascades;sp['light'+p+'_ShadowOffset']=Math.max(0.0,Math.min(1.0,currentLights[p]._vf.shadowOffset));}}
+gl.drawArrays(gl.TRIANGLES,0,6);var nk=shadowIndex+1;for(k=0;k<nk;k++){gl.activeTexture(gl.TEXTURE0+k);gl.bindTexture(gl.TEXTURE_2D,null);}
+gl.disableVertexAttribArray(sp.position);}
+this.stateManager.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);};Context.prototype.blurTex=function(gl,scene,targetFbo,filterSize)
+{if(filterSize<=0)
+return;else if(filterSize<5)
+filterSize=3;else if(filterSize<7)
+filterSize=5;else
+filterSize=7;var width=targetFbo.width;var height=targetFbo.height;var fboBlur=null;for(var i=0,n=scene._webgl.fboBlur.length;i<n;i++)
+if(height==scene._webgl.fboBlur[i].height){fboBlur=scene._webgl.fboBlur[i];break;}
+this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,fboBlur.fbo);this.stateManager.viewport(0,0,width,height);this.stateManager.enable(gl.BLEND);this.stateManager.blendFunc(gl.ONE,gl.ZERO);this.stateManager.disable(gl.CULL_FACE);this.stateManager.disable(gl.DEPTH_TEST);gl.clearColor(1.0,1.0,1.0,0.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);var sp=this.cache.getShader(gl,x3dom.shader.BLUR);this.stateManager.useProgram(sp);gl.bindBuffer(gl.ARRAY_BUFFER,scene._webgl.ppBuffer);gl.vertexAttribPointer(sp.position,2,gl.FLOAT,false,0,0);gl.enableVertexAttribArray(sp.position);sp.pixelSizeHor=1.0/width;sp.pixelSizeVert=1.0/height;sp.filterSize=filterSize;sp.horizontal=true;sp.texture=0;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,targetFbo.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.drawArrays(gl.TRIANGLES,0,6);this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,targetFbo.fbo);gl.clearColor(1.0,1.0,1.0,0.0);gl.clearDepth(1.0);gl.clear(gl.COLOR_BUFFER_BIT|gl.DEPTH_BUFFER_BIT);sp.horizontal=false;gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,fboBlur.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.drawArrays(gl.TRIANGLES,0,6);gl.activeTexture(gl.TEXTURE0);gl.bindTexture(gl.TEXTURE_2D,null);gl.disableVertexAttribArray(sp.position);gl.flush();this.stateManager.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);this.stateManager.bindFramebuffer(gl.FRAMEBUFFER,null);this.stateManager.viewport(0,0,this.canvas.width,this.canvas.height);};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;},setBBox:function(id,center,size){var shape=x3dom.nodeTypes.Shape.idMap.nodeID[id];},setShapeDirty:function(id){var shape=x3dom.nodeTypes.Shape.idMap.nodeID[id];shape.setAllDirty();}};x3dom.gfx_flash=(function(){function Context(object,name,renderType){this.object=object;this.name=name;this.isAlreadySet=false;this.renderType=renderType;}
+function setupContext(object,renderType){x3dom.Utils.maxIndexableCoords=65535;return new Context(object,'flash',renderType);}
+Context.prototype.getName=function(){return this.name;};Context.prototype.renderScene=function(viewarea){var scene=viewarea._scene;var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();var vol=scene.getVolume();vol.getBounds(min,max);scene._lastMin=min;scene._lastMax=max;viewarea._last_mat_view=x3dom.fields.SFMatrix4f.identity();viewarea._last_mat_proj=x3dom.fields.SFMatrix4f.identity();viewarea._last_mat_scene=x3dom.fields.SFMatrix4f.identity();var viewpoint=scene.getViewpoint();if(viewpoint._vf.zNear==-1||viewpoint._vf.zFar==-1){viewpoint._vf.zFar=20000;viewpoint._vf.zNear=0.1;}
+var mat_view=viewarea.getViewMatrix();var mat_proj=viewarea.getProjectionMatrix();var mat_scene=mat_proj.mult(mat_view);this.setupScene(scene,viewarea);var background=scene.getBackground();this.setupBackground(background);scene.drawableCollection=null;var env=scene.getEnvironment();var drawableCollectionConfig={viewArea:viewarea,sortTrans:env._vf.sortTrans,viewMatrix:mat_view,projMatrix:mat_proj,sceneMatrix:mat_scene,frustumCulling:false,smallFeatureThreshold:false,context:null,gl:null};scene.drawableCollection=new x3dom.DrawableCollection(drawableCollectionConfig);scene.collectDrawableObjects(x3dom.fields.SFMatrix4f.identity(),scene.drawableCollection,true,false,0);scene.drawableCollection.concat();var numDrawableObjects=scene.drawableCollection.length;if(numDrawableObjects>0){var RefList=[];for(var i=0;i<numDrawableObjects;i++){var drawable=scene.drawableCollection.get(i);var trafo=drawable.transform;var obj3d=drawable.shape;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();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);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 viewpoint=scene.getViewpoint();var mat_proj=viewarea.getProjectionMatrix();this.object.setViewpoint({fov:viewpoint._vf.fov,zFar:viewpoint._vf.zFar,zNear:viewpoint._vf.zNear,viewMatrix:mat_view.toGL(),projectionMatrix:mat_proj.toGL()});var nav=scene.getNavigationInfo();if(nav._vf.headlight){this.object.setHeadLight({id:-1,on:1.0,color:[1.0,1.0,1.0],intensity:1.0,ambientIntensity:0.0,direction:[0.0,0.0,-1.0]});}
+if(this.renderType=="deferred"){var lights=viewarea.getLights();for(var i=0;i<lights.length;i++){if(lights[i]._dirty){if(x3dom.isa(lights[i],x3dom.nodeTypes.DirectionalLight)){this.object.setDirectionalLight({id:lights[i]._lightID,on:lights[i]._vf.on,color:lights[i]._vf.color.toGL(),intensity:lights[i]._vf.intensity,ambientIntensity:lights[i]._vf.ambientIntensity,direction:lights[i]._vf.direction.toGL()});}
+else if(x3dom.isa(lights[i],x3dom.nodeTypes.PointLight)){var light_transform=mat_view.mult(lights[i].getCurrentTransform());this.object.setPointLight({id:lights[i]._lightID,on:lights[i]._vf.on,color:lights[i]._vf.color.toGL(),intensity:lights[i]._vf.intensity,ambientIntensity:lights[i]._vf.ambientIntensity,attenuation:lights[i]._vf.attenuation.toGL(),location:lights[i]._vf.location.toGL(),radius:lights[i]._vf.radius});}
+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 doesn't support PointSets yet");}else if(x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.IndexedLineSet)){x3dom.debug.logError("Flash backend doesn't support LineSets yet");}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);var isBinaryGeometry=x3dom.isa(shape._cf.geometry.node,x3dom.nodeTypes.BinaryGeometry);var appearance=shape._cf.appearance.node;var sortType=(appearance)?shape._cf.appearance.node._vf.sortType:"auto";var sortKey=(appearance)?shape._cf.appearance.node._vf.sortKey:0
+if(isImageGeometry){this.object.setMeshProperties({id:shape._objectID,type:"ImageGeometry",sortType:sortType,sortKey:sortKey,solid:shape.isSolid(),bboxMin:shape._cf.geometry.node.getMin().toGL(),bboxMax:shape._cf.geometry.node.getMax().toGL(),bboxCenter:shape._cf.geometry.node.getCenter().toGL(),primType:shape._cf.geometry.node._vf.primType,vertexCount:shape._cf.geometry.node._vf.vertexCount});}else if(isBinaryGeometry){this.object.setMeshProperties({id:shape._objectID,type:"BinaryGeometry",sortType:sortType,sortKey:sortKey,solid:shape.isSolid(),bgCenter:shape._cf.geometry.node._vf.position.toGL(),bgSize:shape._cf.geometry.node._vf.size.toGL(),bboxCenter:shape._cf.geometry.node.getCenter().toGL(),primType:shape._cf.geometry.node._vf.primType,vertexCount:shape._cf.geometry.node._vf.vertexCount});}else{this.object.setMeshProperties({id:shape._objectID,type:"Default",sortType:sortType,sortKey:sortKey,solid:shape.isSolid()});}
+if(shape._dirty.indexes===true){if(isImageGeometry){}else if(isBinaryGeometry){this.object.setMeshIndices({id:shape._objectID,idx:0,indices:shape._nameSpace.getURL(shape._cf.geometry.node._vf.index)});}else{if(shape._cf.geometry.node._mesh._multiIndIndices&&shape._cf.geometry.node._mesh._multiIndIndices.length)
+{shape._cf.geometry.node._mesh.splitMesh(3,true);}
+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){this.object.setMeshVertices({id:shape._objectID,idx:0,coordinateTexture0:shape._cf.geometry.node.getCoordinateTextureURL(0),coordinateTexture1:shape._cf.geometry.node.getCoordinateTextureURL(1)});}else if(isBinaryGeometry){this.object.setMeshVertices({id:shape._objectID,idx:0,interleaved:shape._cf.geometry.node._hasStrideOffset,vertices:shape._nameSpace.getURL(shape._cf.geometry.node._vf.coord),normals:shape._nameSpace.getURL(shape._cf.geometry.node._vf.normal),texCoords:shape._nameSpace.getURL(shape._cf.geometry.node._vf.texCoord),colors:shape._nameSpace.getURL(shape._cf.geometry.node._vf.color),numColorComponents:shape._cf.geometry.node._mesh._numColComponents,numNormalComponents:shape._cf.geometry.node._mesh._numNormComponents,vertexType:shape._cf.geometry.node._vf.coordType,normalType:shape._cf.geometry.node._vf.normalType,texCoordType:shape._cf.geometry.node._vf.texCoordType,colorType:shape._cf.geometry.node._vf.colorType,vertexStrideOffset:shape._coordStrideOffset,normalStrideOffset:shape._normalStrideOffset,texCoordStrideOffset:shape._texCoordStrideOffset,colorStrideOffset:shape._colorStrideOffset});}else{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]});}}
+shape._dirty.positions=false;}
+if(shape._dirty.normals===true){if(isImageGeometry){this.object.setMeshNormals({id:shape._objectID,idx:0,normalTexture:shape._cf.geometry.node.getNormalTextureURL()});}else if(isBinaryGeometry){if(!shape._cf.geometry.node._hasStrideOffset){this.object.setMeshNormals({id:shape._objectID,idx:0,normals:shape._nameSpace.getURL(shape._cf.geometry.node._vf.normal)});}}else{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]});}}}
+shape._dirty.normals=false;}
+if(shape._dirty.colors===true){if(isImageGeometry){this.object.setMeshColors({id:shape._objectID,idx:0,colorTexture:shape._cf.geometry.node.getColorTextureURL(),components:shape._cf.geometry.node._mesh._numColComponents});}else if(isBinaryGeometry){if(!shape._cf.geometry.node._hasStrideOffset){this.object.setMeshColors({id:shape._objectID,idx:0,colors:shape._nameSpace.getURL(shape._cf.geometry.node._vf.color),components:shape._cf.geometry.node._mesh._numColComponents});}}else{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});}}}
+shape._dirty.colors=false;}
+if(shape._dirty.texcoords===true){if(isImageGeometry){this.object.setMeshTexCoords({id:shape._objectID,idx:0,texCoordTexture:shape._cf.geometry.node.getTexCoordTextureURL()});}else if(isBinaryGeometry){if(!shape._cf.geometry.node._hasStrideOffset){this.object.setMeshTexCoords({id:shape._objectID,idx:0,texCoords:shape._nameSpace.getURL(shape._cf.geometry.node._vf.texCoord)});}}else{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]});}}}
+shape._dirty.texcoords=false;}
+if(shape._dirty.material===true){if(appearance){var material=shape._cf.appearance.node._cf.material.node;if(material){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){if(appearance){var texTrafo=null;if(appearance._cf.textureTransform.node){texTrafo=appearance.texTransformMatrix().toGL();}
+var texture=shape._cf.appearance.node._cf.texture.node;if(texture){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(x3dom.isa(texture,x3dom.nodeTypes.ComposedCubeMapTexture)){this.object.setCubeTexture({id:shape._objectID,texURLs:texture.getTexUrl()});}else if(texture._isCanvas&&texture._canvas){this.object.setCanvasTexture({id:shape._objectID,width:texture._canvas.width,height:texture._canvas.height,dataURL:texture._canvas.toDataURL()});}else if(x3dom.isa(texture,x3dom.nodeTypes.MultiTexture)){x3dom.debug.logError("Flash backend doesn't support MultiTextures yet");}else if(x3dom.isa(texture,x3dom.nodeTypes.MovieTexture)){x3dom.debug.logError("Flash backend doesn'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],transform:texTrafo});}}else{this.object.removeTexture({id:shape._objectID});}}
+shape._dirty.texture=false;}
+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){var appearance=shape._cf.appearance.node;var sortType=(appearance)?shape._cf.appearance.node._vf.sortType:"auto";var sortKey=(appearance)?shape._cf.appearance.node._vf.sortKey:0
+if(shape._dirty.text===true){var fontStyleNode=shape._cf.geometry.node._cf.fontStyle.node;if(fontStyleNode===null){this.object.setMeshProperties({id:shape._objectID,type:"Text",sortType:sortType,sortKey:sortKey,solid:shape.isSolid(),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.setMeshProperties({id:shape._objectID,type:"Text",sortType:sortType,sortKey:sortKey,solid:shape.isSolid(),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){if(appearance){var material=shape._cf.appearance.node._cf.material.node;if(material){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;}}};Context.prototype.pickValue=function(viewarea,x,y,viewMat,sceneMat){var scene=viewarea._scene;if(this.object===null||scene===null||scene.drawableCollection===undefined||!scene.drawableCollection||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.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=name?this.defMap[name]:null;if(node){delete this.defMap[name];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){space.parent=null;for(var it=0;it<this.childSpaces.length;it++){if(this.childSpaces[it]==space){this.childSpaces.splice(it,1);}}};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.hasElementAttribute=function(attrName)
+{var ok=this.__hasAttribute(attrName);if(!ok&&attrName){ok=this.__hasAttribute(attrName.toLowerCase());}
+return ok;};x3dom.getElementAttribute=function(attrName)
+{var attrib=this.__getAttribute(attrName);if(!attrib&&attrib!=""&&attrName){attrib=this.__getAttribute(attrName.toLowerCase());}
+if(attrib||!this._x3domNode){return attrib;}
+else{return this._x3domNode._vf[attrName];}};x3dom.setElementAttribute=function(attrName,newVal)
+{this.__setAttribute(attrName,newVal);var x3dNode=this._x3domNode;if(x3dNode){x3dNode.updateField(attrName,newVal);x3dNode._nameSpace.doc.needRender=true;}};x3dom.getFieldValue=function(fieldName)
+{var x3dNode=this._x3domNode;if(x3dNode&&x3dNode._vf[fieldName]){return x3dNode._vf[fieldName].copy();}
+return null;};x3dom.setFieldValue=function(fieldName,fieldvalue){var x3dNode=this._x3domNode;if(x3dNode&&x3dNode._vf[fieldName]){if(fieldvalue instanceof Object&&'copy'in fieldvalue)
+{x3dNode._vf[fieldName]=fieldvalue.copy();}
+else
+x3dNode._vf[fieldName]=fieldvalue;x3dNode.fieldChanged(fieldName);x3dNode._nameSpace.doc.needRender=true;}};x3dom.requestFieldRef=function(fieldName)
+{var x3dNode=this._x3domNode;if(x3dNode&&x3dNode._vf[fieldName])
+{return x3dNode._vf[fieldName];}
+return null;};x3dom.releaseFieldRef=function(fieldName)
+{var x3dNode=this._x3domNode;if(x3dNode&&x3dNode._vf[fieldName])
+{x3dNode.fieldChanged(fieldName);x3dNode._nameSpace.doc.needRender=true;}};x3dom.NodeNameSpace.prototype.setupTree=function(domNode){var n=null;if(x3dom.isX3DElement(domNode)){if(domNode._x3domNode){x3dom.debug.logWarning('Tree is already initialized');return null;}
+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);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);}}}
+this.__removeEventListener(type,func,phase);};}
+if(domNode.hasAttribute('USE')||domNode.hasAttribute('use'))
+{if(!domNode.hasAttribute('USE')){domNode.setAttribute('USE',domNode.getAttribute('use'));}
+n=this.defMap[domNode.getAttribute('USE')];if(!n){var nsName=domNode.getAttribute('USE').split('__');if(nsName.length>=2){var otherNS=this;while(otherNS){if(otherNS.name==nsName[0])
+n=otherNS.defMap[nsName[1]];if(n)
+otherNS=null;else
+otherNS=otherNS.parent;}
+if(!n){n=null;x3dom.debug.logWarning('Could not USE: '+domNode.getAttribute('USE'));}}}
+if(n){domNode._x3domNode=n;}
+return n;}
+else{if(domNode.localName.toLowerCase()==='route'){var route=domNode;var fnAtt=route.getAttribute('fromNode')||route.getAttribute('fromnode');var tnAtt=route.getAttribute('toNode')||route.getAttribute('tonode');var fromNode=this.defMap[fnAtt];var toNode=this.defMap[tnAtt];if(!(fromNode&&toNode)){x3dom.debug.logWarning("Broken route - can't find all DEFs for "+fnAtt+" -> "+tnAtt);}
+else{fnAtt=route.getAttribute('fromField')||route.getAttribute('fromfield');tnAtt=route.getAttribute('toField')||route.getAttribute('tofield');fromNode.setupRoute(fnAtt,toNode,tnAtt);route._nodeNameSpace=this;}
+return null;}
+domNode.requestFieldRef=x3dom.requestFieldRef;domNode.releaseFieldRef=x3dom.releaseFieldRef;domNode.getFieldValue=x3dom.getFieldValue;domNode.setFieldValue=x3dom.setFieldValue;var nodeType=x3dom.nodeTypesLC[domNode.localName.toLowerCase()];if(nodeType===undefined){x3dom.debug.logWarning("Unrecognised X3D element &lt;"+domNode.localName+"&gt;.");}
+else{if((x3dom.userAgentFeature.supportsDOMAttrModified===false)&&(domNode instanceof Element)){if(domNode.setAttribute&&!domNode.__setAttribute){domNode.__setAttribute=domNode.setAttribute;domNode.setAttribute=x3dom.setElementAttribute;}
+if(domNode.getAttribute&&!domNode.__getAttribute){domNode.__getAttribute=domNode.getAttribute;domNode.getAttribute=x3dom.getElementAttribute;}
+if(domNode.hasAttribute&&!domNode.__hasAttribute){domNode.__hasAttribute=domNode.hasAttribute;domNode.hasAttribute=x3dom.hasElementAttribute;}}
+var ctx={doc:this.doc,xmlNode:domNode,nameSpace:this};n=new nodeType(ctx);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;}}
+if(domNode.highlight===undefined)
+{domNode.highlight=function(enable,colorStr){var color=x3dom.fields.SFColor.parse(colorStr);this._x3domNode.highlight(enable,color);this._x3domNode._nameSpace.doc.needRender=true;};}
+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.logWarning("Unrecognised X3D element &lt;"+domNode.localName+"&gt;.");n=null;}
+return n;};x3dom.registerNodeType("X3DNode","Core",defineClass(null,function(ctx){this._xmlNode=null;this._DEF=null;this._nameSpace=(ctx&&ctx.nameSpace)?ctx.nameSpace:null;this._vf={};this._vfFieldTypes={};this._cf={};this._cfFieldTypes={};this._fieldWatchers={};this._routes={};this._listeners={};this._parentNodes=[];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=node._parentNodes.length-1;i>=0;i--){if(node._parentNodes[i]===this){node._parentNodes.splice(i,1);node.parentRemoved(this);}}
+for(var j=this._childNodes.length-1;j>=0;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(){return null;},invalidateVolume:function(){},invalidateCache:function(){},volumeValid:function(){return false;},collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask){},highlight:function(enable,color)
+{if(this._vf.hasOwnProperty("diffuseColor"))
+{if(enable){if(this._actDiffuseColor===undefined){this._actDiffuseColor=new x3dom.fields.SFColor();this._highlightOn=false;}
+if(!this._highlightOn){this._actDiffuseColor.setValues(this._vf.diffuseColor);this._highlightOn=true;}
+this._vf.diffuseColor.setValues(color);}
+else{if(this._actDiffuseColor!==undefined){this._vf.diffuseColor.setValues(this._actDiffuseColor);this._highlightOn=false;delete this._actDiffuseColor;}}}
+for(var i=0,n=this._childNodes.length;i<n;i++)
+{if(this._childNodes[i])
+this._childNodes[i].highlight(enable,color);}},findX3DDoc:function(){return this._nameSpace.doc;},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 that=this;if(listeners){Array.forEach(listeners,function(l){l.call(that,msg);});}
+var eventObject={target:that._xmlNode,type:"onoutputchange",fieldName:field,value:msg};this.callEvtHandler(eventObject.type,eventObject);},updateField:function(field,msg){var f=this._vf[field];if(f===undefined){for(var key in this._vf){if(key.toLowerCase()==field){field=key;f=this._vf[field];break;}}
+var pre="set_";if(f===undefined&&field.indexOf(pre)==0){var fieldName=field.substr(pre.length,field.length-1);if(this._vf[fieldName]!==undefined){field=fieldName;f=this._vf[field];}}
+if(f===undefined){f=null;this._vf[field]=f;}}
+if(f!==null){try{this._vf[field].setValueByStr(msg);}
+catch(exc1){try{switch((typeof(this._vf[field])).toString()){case"number":if(typeof(msg)=="number")
+this._vf[field]=msg;else
+this._vf[field]=+msg;break;case"boolean":if(typeof(msg)=="boolean")
+this._vf[field]=msg;else
+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;}}}}
+var where=this._DEF+"&"+fromField+"&"+toNode._DEF+"&"+toField;if(!this._routes[where]){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);});this._routes[where]={from:this._fieldWatchers[fromField].length-1,to:toNode._fieldWatchers[toField].length-1};}},removeRoute: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;}}}}
+var where=this._DEF+"&"+fromField+"&"+toNode._DEF+"&"+toField;if(this._routes[where]){this._fieldWatchers[fromField].splice(this._routes[where].from,1);toNode._fieldWatchers[toField].splice(this._routes[where].to,1);delete this._routes[where];}},fieldChanged:function(fieldName){},nodeChanged:function(){},callEvtHandler:function(eventType,event){var node=this;if(!node._xmlNode){return event.cancelBubble;}
+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||!name)
+return;var nameLC=name.toLowerCase();if(xmlNode.__defineSetter__&&xmlNode.__defineGetter__){xmlNode.__defineSetter__(name,function(value){xmlNode.setAttribute(name,value);});xmlNode.__defineGetter__(name,function(){return xmlNode.getAttribute(name);});if(nameLC!=name){xmlNode.__defineSetter__(nameLC,function(value){xmlNode.setAttribute(name,value);});xmlNode.__defineGetter__(nameLC,function(){return xmlNode.getAttribute(name);});}}
+else{Object.defineProperty(xmlNode,name,{set:function(value){xmlNode.setAttribute(name,value);},get:function(){return xmlNode.getAttribute(name);},configurable:true,enumerable:true});}
+if(this._vf[name]&&!xmlNode.attributes[name]&&!xmlNode.attributes[name.toLowerCase()]){var str="";try{if(this._vf[name].toGL)
+str=this._vf[name].toGL().toString();else
+str=this._vf[name].toString();}
+catch(e){str=this._vf[name].toString();}
+if(!str){str="";}
+xmlNode.setAttribute(name,str);}},addField_SFInt32:function(ctx,name,n){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?parseInt(ctx.xmlNode.getAttribute(name),10):n;if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}
+this._vfFieldTypes[name]="SFInt32";},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);}
+this._vfFieldTypes[name]="SFFloat";},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);}
+this._vfFieldTypes[name]="SFDouble";},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);}
+this._vfFieldTypes[name]="SFTime";},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);}
+this._vfFieldTypes[name]="SFBool";},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);}
+this._vfFieldTypes[name]="SFString";},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);}
+this._vfFieldTypes[name]="SFColor";},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);}
+this._vfFieldTypes[name]="SFColorRGBA";},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);}
+this._vfFieldTypes[name]="SFVec2f";},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);}
+this._vfFieldTypes[name]="SFVec3f";},addField_SFVec3d:function(ctx,name,x,y,z){this.addField_SFVec3f(ctx,name,x,y,z);this._vfFieldTypes[name]="SFVec3d";},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);}
+this._vfFieldTypes[name]="SFRotation";},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);}
+this._vfFieldTypes[name]="SFMatrix4f";},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);}
+this._vfFieldTypes[name]="SFImage";},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);}
+this._vfFieldTypes[name]="MFString";},addField_MFBoolean:function(ctx,name,def){this._vf[name]=ctx&&ctx.xmlNode&&ctx.xmlNode.hasAttribute(name)?x3dom.fields.MFBoolean.parse(ctx.xmlNode.getAttribute(name)):new x3dom.fields.MFBoolean(def);if(ctx&&ctx.xmlNode){this.initSetter(ctx.xmlNode,name);}
+this._vfFieldTypes[name]="MFBoolean";},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);}
+this._vfFieldTypes[name]="MFInt32";},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);}
+this._vfFieldTypes[name]="MFFloat";},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);}
+this._vfFieldTypes[name]="MFDouble";},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);}
+this._vfFieldTypes[name]="MFColor";},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);}
+this._vfFieldTypes[name]="MFColorRGBA";},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);}
+this._vfFieldTypes[name]="MFVec2f";},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);}
+this._vfFieldTypes[name]="MFVec3f";},addField_MFVec3d:function(ctx,name,def){this.addField_MFVec3f(ctx,name,def);this._vfFieldTypes[name]="MFVec3d";},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);}
+this._vfFieldTypes[name]="MFRotation";},addField_SFNode:function(name,type){this._cf[name]=new x3dom.fields.SFNode(type);this._cfFieldTypes[name]="SFNode";},addField_MFNode:function(name,type){this._cf[name]=new x3dom.fields.MFNode(type);this._cfFieldTypes[name]="MFNode";}}));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("MetadataBoolean","Core",defineClass(x3dom.nodeTypes.X3DMetadataObject,function(ctx){x3dom.nodeTypes.MetadataBoolean.superClass.call(this,ctx);this.addField_MFBoolean(ctx,'value',[]);}));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,'bind',false);this.addField_SFString(ctx,'description',"");this.addField_SFBool(ctx,'isActive',false);this._autoGen=(ctx&&ctx.autoGen?true:false);if(this._autoGen)
+this._vf.description="default"+this.constructor.superClass._typeName;this._stack=null;},{bind:function(value){if(this._stack){if(value){this._stack.push(this);}
+else{this._stack.pop(this);}}
+else{x3dom.debug.logError('No BindStack in '+this.typeName()+'Bindable');}},activate:function(prev){this.postMessage('isActive',true);x3dom.debug.logInfo('activate '+this.typeName()+'Bindable '+
+this._DEF+'/'+this._vf.description);},deactivate:function(prev){this.postMessage('isActive',false);x3dom.debug.logInfo('deactivate '+this.typeName()+'Bindable '+
+this._DEF+'/'+this._vf.description);},fieldChanged:function(fieldName){if(fieldName.indexOf("bind")>=0){this.bind(this._vf.bind);}},nodeChanged:function(){this._stack=this._nameSpace.doc._bindableBag.addBindable(this);}}));x3dom.registerNodeType("X3DInfoNode","Core",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DInfoNode.superClass.call(this,ctx);}));x3dom.registerNodeType("WorldInfo","Core",defineClass(x3dom.nodeTypes.X3DInfoNode,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);this.addField_SFBool(ctx,'enabled',true);}));x3dom.registerNodeType("Param","Core",defineClass(x3dom.nodeTypes.X3DNode,function(ctx){x3dom.nodeTypes.Param.superClass.call(this,ctx);x3dom.debug.logWarning('DEPRECATED: Param element needs to be child of X3D element '
++'[<a href="http://x3dom.org/docs/latest/configuration.html">DOCS</a>]');}));x3dom.registerNodeType("X3DBoundedObject","Grouping",defineClass(x3dom.nodeTypes.X3DChildNode,function(ctx){x3dom.nodeTypes.X3DBoundedObject.superClass.call(this,ctx);this.addField_SFBool(ctx,'render',true);this.addField_SFVec3f(ctx,'bboxCenter',0,0,0);this.addField_SFVec3f(ctx,'bboxSize',-1,-1,-1);this._graph={boundedNode:this,localMatrix:x3dom.fields.SFMatrix4f.identity(),globalMatrix:null,volume:new x3dom.fields.BoxVolume(),worldVolume:new x3dom.fields.BoxVolume(),center:new x3dom.fields.SFVec3f(0,0,0),coverage:-1,needCulling:true};},{fieldChanged:function(fieldName){if(this._vf.hasOwnProperty(fieldName)){this.invalidateVolume();}},nodeChanged:function(){this.invalidateVolume();},parentAdded:function(parent){this.invalidateVolume();},getVolume:function()
+{var vol=this._graph.volume;if(!this.volumeValid()&&this._vf.render)
+{for(var i=0,n=this._childNodes.length;i<n;i++)
+{var child=this._childNodes[i];if(!child||child._vf.render!==true)
+continue;var childVol=child.getVolume();if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}}
+return vol;},invalidateVolume:function()
+{var graph=this._graph;graph.volume.invalidate();graph.worldVolume.invalidate();graph.globalMatrix=null;for(var i=0,n=this._parentNodes.length;i<n;i++){var node=this._parentNodes[i];if(node&&node.volumeValid())
+node.invalidateVolume();}},invalidateCache:function()
+{var graph=this._graph;graph.worldVolume.invalidate();graph.globalMatrix=null;},cacheInvalid:function()
+{return(this._graph.globalMatrix==null||!this._graph.worldVolume.isValid());},volumeValid:function()
+{return this._graph.volume.isValid();},graphState:function()
+{return this._graph;},forceUpdateCoverage:function()
+{return false;}}));x3dom.registerNodeType("X3DGroupingNode","Grouping",defineClass(x3dom.nodeTypes.X3DBoundedObject,function(ctx){x3dom.nodeTypes.X3DGroupingNode.superClass.call(this,ctx);this.addField_MFNode('children',x3dom.nodeTypes.X3DChildNode);},{collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+var cnode,childTransform;if(singlePath){if(!this._graph.globalMatrix){this._graph.globalMatrix=this.transformMatrix(transform);}
+childTransform=this._graph.globalMatrix;}
+else{childTransform=this.transformMatrix(transform);}
+for(var i=0,n=this._childNodes.length;i<n;i++){if((cnode=this._childNodes[i])){cnode.collectDrawableObjects(childTransform,drawableCollection,singlePath,invalidateCache,planeMask);}}}}));x3dom.registerNodeType("Switch","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Switch.superClass.call(this,ctx);this.addField_SFInt32(ctx,'whichChoice',-1);},{fieldChanged:function(fieldName){if(fieldName=="whichChoice"){this.invalidateVolume();}},getVolume:function()
+{var vol=this._graph.volume;if(!this.volumeValid()&&this._vf.render)
+{if(this._vf.whichChoice>=0&&this._vf.whichChoice<this._childNodes.length)
+{var child=this._childNodes[this._vf.whichChoice];var childVol=(child&&child._vf.render===true)?child.getVolume():null;if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}}
+return vol;},collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length||(planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask))<=0){return;}
+var cnode,childTransform;if(singlePath){if(!this._graph.globalMatrix){this._graph.globalMatrix=this.transformMatrix(transform);}
+childTransform=this._graph.globalMatrix;}
+else{childTransform=this.transformMatrix(transform);}
+if((cnode=this._childNodes[this._vf.whichChoice])){cnode.collectDrawableObjects(childTransform,drawableCollection,singlePath,invalidateCache,planeMask);}},doIntersect:function(line)
+{if(this._vf.whichChoice<0||this._vf.whichChoice>=this._childNodes.length){return false;}
+var child=this._childNodes[this._vf.whichChoice];if(child){return child.doIntersect(line);}
+return false;}}));x3dom.registerNodeType("X3DTransformNode","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.X3DTransformNode.superClass.call(this,ctx);if(ctx)
+ctx.doc._nodeBag.trans.push(this);else
+x3dom.debug.logWarning("X3DTransformNode: No runtime context found!");this._trafo=null;this._needCssStyleUpdates=true;},{tick:function(t)
+{var dom=this._xmlNode;if(dom&&(dom['ontransform']||dom.hasAttribute('ontransform')||this._listeners['transform'])){var transMatrix=this.getCurrentTransform();var event={target:dom,type:'transform',worldX:transMatrix._03,worldY:transMatrix._13,worldZ:transMatrix._23,cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;}};this.callEvtHandler("ontransform",event);}
+if(this._needCssStyleUpdates&&dom){var trans=x3dom.getStyle(dom,"-webkit-transform")||x3dom.getStyle(dom,"-moz-transform")||x3dom.getStyle(dom,"-ms-transform")||x3dom.getStyle(dom,"transform");if(trans&&(trans!='none')){this._trafo.setValueByStr(trans);this.invalidateVolume();return true;}
+this._needCssStyleUpdates=false;}
+return false;},transformMatrix:function(transform){return transform.mult(this._trafo);},getVolume:function()
+{var vol=this._graph.volume;if(!this.volumeValid()&&this._vf.render)
+{this._graph.localMatrix=this._trafo;for(var i=0,n=this._childNodes.length;i<n;i++)
+{var child=this._childNodes[i];if(!child||child._vf.render!==true)
+continue;var childVol=child.getVolume();if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}
+if(vol.isValid())
+vol.transform(this._trafo);}
+return vol;},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,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)
+{if(fieldName=="center"||fieldName=="translation"||fieldName=="rotation"||fieldName=="scale"||fieldName=="scaleOrientation")
+{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()));this.invalidateVolume();}
+else if(fieldName=="render"){this.invalidateVolume();}}}));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.transpose();},{fieldChanged:function(fieldName){if(fieldName=="matrix"){this._trafo=this._vf.matrix.transpose();this.invalidateVolume();}
+else if(fieldName=="render"){this.invalidateVolume();}}}));x3dom.registerNodeType("Group","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Group.superClass.call(this,ctx);}));x3dom.registerNodeType("Block","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Block.superClass.call(this,ctx);this.addField_MFString(ctx,'nameSpaceName',[]);}));x3dom.registerNodeType("StaticGroup","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.StaticGroup.superClass.call(this,ctx);this.addField_SFBool(ctx,'debug',false);this.addField_SFBool(ctx,'showDebugBoxVolumes',false);this.addField_SFString(ctx,'bvhType','jsBIH');this.addField_SFInt32(ctx,'maxObjectsPerNode',1);this.addField_SFInt32(ctx,'maxDepth',-1);this.addField_SFFloat(ctx,'minRelativeBBoxSize',0.01);this.needBvhRebuild=true;this.drawableCollection=null;this.bvh=null;},{getMaxDepth:function()
+{if(this._vf.maxDepth==-1)
+{return(this._vf.bvhType==('jsBIH'||'BIH'))?50:4;}
+return this._vf.maxDepth;},collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+var cnode,childTransform;if(singlePath){if(!this._graph.globalMatrix){this._graph.globalMatrix=this.transformMatrix(transform);}
+childTransform=this._graph.globalMatrix;}
+else{childTransform=this.transformMatrix(transform);}
+if(this.needBvhRebuild)
+{var drawableCollectionConfig={viewArea:drawableCollection.viewarea,sortTrans:drawableCollection.sortTrans,viewMatrix:drawableCollection.viewMatrix,projMatrix:drawableCollection.projMatrix,sceneMatrix:drawableCollection.sceneMatrix,frustumCulling:false,smallFeatureThreshold:0,context:drawableCollection.context};this.drawableCollection=new x3dom.DrawableCollection(drawableCollectionConfig);var i,n=this._childNodes.length;for(i=0;i<n;i++){if((cnode=this._childNodes[i])){cnode.collectDrawableObjects(childTransform,this.drawableCollection,singlePath,invalidateCache,planeMask);}}
+this.drawableCollection.concat();var scene=this._nameSpace.doc._scene;var bvhSettings=new x3dom.bvh.Settings(this._vf.debug,this._vf.showDebugBoxVolumes,this._vf.bvhType,this._vf.maxObjectsPerNode,this.getMaxDepth(),this._vf.minRelativeBBoxSize);this.bvh=(this._vf.bvhType=='jsBIH')?new x3dom.bvh.BIH(scene,bvhSettings):new x3dom.bvh.Culler(this.drawableCollection,scene,bvhSettings);if(this._vf.debug||this._vf.showDebugBoxVolumes)
+this.bvh=new x3dom.bvh.DebugDecorator(this.bvh,scene,bvhSettings);n=this.drawableCollection.length;for(i=0;i<n;i++)
+{this.bvh.addDrawable(this.drawableCollection.get(i))}
+this.bvh.compile();if(this._vf.debug)
+this.bvh.showCompileStats();this.needBvhRebuild=false;}
+x3dom.Utils.startMeasure('bvhTraverse');this.bvh.collectDrawables(drawableCollection);var dt=x3dom.Utils.stopMeasure('bvhTraverse');this._nameSpace.doc.ctx.x3dElem.runtime.addMeasurement('BVH',dt);this.bvh.showTraverseStats(this._nameSpace.doc.ctx.x3dElem.runtime);}}));x3dom.registerNodeType("RemoteSelectionGroup","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.RemoteSelectionGroup.superClass.call(this,ctx);this.addField_MFString(ctx,'url',["ws://localhost:35668/cstreams/0"]);this.addField_MFString(ctx,'label',[]);this.addField_SFInt32(ctx,'maxRenderedIds',-1);this.addField_SFBool(ctx,'reconnect',true);this.addField_SFFloat(ctx,'scaleRenderedIdsOnMove',1.0);this.addField_SFBool(ctx,'enableCulling',true);this.addField_MFString(ctx,'invisibleNodes',[]);this._idList=[];this._websocket=null;this._nameObjMap={};this._createTime=[];this._visibleList=[];if(ctx)
+this.initializeSocket();else
+x3dom.debug.logWarning("RemoteSelectionGroup: No runtime context found!");},{initializeSocket:function()
+{var that=this;if("WebSocket"in window)
+{var wsUrl="ws://localhost:35668/cstreams/0";if(this._vf.url.length&&this._vf.url[0].length)
+wsUrl=this._vf.url[0];this._websocket=new WebSocket(wsUrl);this._websocket._lastMsg=null;this._websocket._lastData="";this._websocket.onopen=function(evt)
+{x3dom.debug.logInfo("WS Connected");var view=that._nameSpace.doc._viewarea.getViewMatrix();this._lastMsg=view.toGL().toString();view=that._nameSpace.doc._viewarea.getProjectionMatrix();this._lastMsg+=(","+view.toGL().toString());this.send(this._lastMsg);x3dom.debug.logInfo("WS Sent: "+this._lastMsg);this._lastMsg="";this._lastData="";};this._websocket.onclose=function(evt)
+{x3dom.debug.logInfo("WS Disconnected");if(that._vf.reconnect)
+{window.setTimeout(function(){that.initializeSocket();},2000);}};this._websocket.onmessage=function(evt)
+{if(that._vf.maxRenderedIds<0)
+{that._idList=x3dom.fields.MFString.parse(evt.data);}
+else if(that._vf.maxRenderedIds>0)
+{that._idList=[];var arr=x3dom.fields.MFString.parse(evt.data);var n=Math.min(arr.length,Math.abs(that._vf.maxRenderedIds));for(var i=0;i<n;++i){that._idList[i]=arr[i];}}
+if(that._vf.maxRenderedIds!=0&&this._lastData!=evt.data)
+{this._lastData=evt.data;that._nameSpace.doc.needRender=true;that.invalidateVolume();}};this._websocket.onerror=function(evt)
+{x3dom.debug.logError(evt.data);};this._websocket.updateCamera=function()
+{var view=that._nameSpace.doc._viewarea.getViewMatrix();var message=view.toGL().toString();view=that._nameSpace.doc._viewarea.getProjectionMatrix();message+=(","+view.toGL().toString());if(this._lastMsg!=null&&this._lastMsg!=message)
+{this._lastMsg=message;this.send(message);}};}
+else
+{x3dom.debug.logError("Browser has no WebSocket support!");}},nodeChanged:function()
+{var n=this._vf.label.length;this._nameObjMap={};this._createTime=new Array(n);this._visibleList=new Array(n);for(var i=0;i<n;++i)
+{var shape=this._childNodes[i];if(shape&&x3dom.isa(shape,x3dom.nodeTypes.X3DShapeNode))
+{this._nameObjMap[this._vf.label[i]]={shape:shape,pos:i};this._visibleList[i]=true;}
+else{this._visibleList[i]=false;x3dom.debug.logError("Invalid children: "+this._vf.label[i]);}
+this._createTime[i]=0;}
+this.invalidateVolume();x3dom.debug.logInfo("RemoteSelectionGroup has "+n+" entries.");},fieldChanged:function(fieldName)
+{if(fieldName=="url")
+{if(this._websocket){this._websocket.close();this._websocket=null;}
+this.initializeSocket();}
+else if(fieldName=="invisibleNodes")
+{for(var i=0,n=this._vf.label.length;i<n;++i)
+{var shape=this._childNodes[i];if(shape&&x3dom.isa(shape,x3dom.nodeTypes.X3DShapeNode))
+{this._visibleList[i]=true;for(var j=0,numInvis=this._vf.invisibleNodes.length;j<numInvis;++j)
+{var nodeName=this._vf.invisibleNodes[j];var starInd=nodeName.lastIndexOf('*');var matchNameBegin=false;if(starInd>0){nodeName=nodeName.substring(0,starInd);matchNameBegin=true;}
+if(nodeName.length<=1)
+continue;if((matchNameBegin&&this._vf.label[i].indexOf(nodeName)==0)||this._vf.label[i]==nodeName){this._visibleList[i]=false;break;}}}
+else{this._visibleList[i]=false;}}
+this.invalidateVolume();}
+else if(fieldName=="render"){this.invalidateVolume();}},getNumRenderedObjects:function(len,isMoving)
+{var n=len;if(this._vf.maxRenderedIds>0)
+{var num=Math.max(this._vf.maxRenderedIds,16);var scale=1;if(isMoving)
+scale=Math.min(this._vf.scaleRenderedIdsOnMove,1);num=Math.max(Math.round(scale*num),0);n=Math.min(n,num);}
+return n;},collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+var viewarea=this._nameSpace.doc._viewarea;var isMoving=viewarea.isMovingOrAnimating();var ts=new Date().getTime();var maxLiveTime=10000;var i,n,numChild=this._childNodes.length;if(!this._vf.enableCulling)
+{n=this.getNumRenderedObjects(numChild,isMoving);var cnt=0;for(i=0;i<numChild;i++)
+{var shape=this._childNodes[i];if(shape)
+{var needCleanup=true;if(this._visibleList[i]&&cnt<n&&shape.collectDrawableObjects(transform,drawableCollection,singlePath,invalidateCache,planeMask))
+{this._createTime[i]=ts;cnt++;needCleanup=false;}
+if(needCleanup&&!isMoving&&this._createTime[i]>0&&ts-this._createTime[i]>maxLiveTime&&shape._cleanupGLObjects)
+{shape._cleanupGLObjects(true);this._createTime[i]=0;}}}
+return;}
+if(this._websocket)
+this._websocket.updateCamera();if(this._vf.label.length)
+{n=this.getNumRenderedObjects(this._idList.length,isMoving);for(i=0;i<n;i++)
+{var obj=this._nameObjMap[this._idList[i]];if(obj&&obj.shape){obj.shape.collectDrawableObjects(transform,drawableCollection,singlePath,invalidateCache,planeMask);this._createTime[obj.pos]=ts;}
+else
+x3dom.debug.logError("Invalid label: "+this._idList[i]);}
+for(i=0;i<this._childNodes.length;i++)
+{if(this._childNodes[i]&&!isMoving&&this._createTime[i]>0&&ts-this._createTime[i]>maxLiveTime&&this._childNodes[i]._cleanupGLObjects)
+{this._childNodes[i]._cleanupGLObjects(true);this._createTime[i]=0;}}}}}));x3dom.registerNodeType("Scene","Grouping",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.Scene.superClass.call(this,ctx);this.addField_SFString(ctx,'pickMode',"idBuf");this.addField_SFBool(ctx,'doPickPass',true);this.addField_SFString(ctx,'shadowObjectIdMapping',"");this._lastMin=new x3dom.fields.SFVec3f(0,0,0);this._lastMax=new x3dom.fields.SFVec3f(1,1,1);this._shadowIdMap=null;this.loadMapping();},{fieldChanged:function(fieldName)
+{if(fieldName=="shadowObjectIdMapping")
+this.loadMapping();},updateVolume:function()
+{var vol=this.getVolume();if(vol.isValid())
+{this._lastMin=x3dom.fields.SFVec3f.copy(vol.min);this._lastMax=x3dom.fields.SFVec3f.copy(vol.max);}},loadMapping:function()
+{this._shadowIdMap=null;if(this._vf.shadowObjectIdMapping.length==0){return;}
+var that=this;var xhr=new XMLHttpRequest();xhr.open("GET",encodeURI(this._nameSpace.getURL(this._vf.shadowObjectIdMapping)),true);xhr.send();xhr.onload=function()
+{that._shadowIdMap=eval("("+xhr.response+")");if(!that._shadowIdMap||!that._shadowIdMap.mapping){x3dom.debug.logWarning("Invalid ID map: "+that._vf.shadowObjectIdMapping);}
+else{x3dom.debug.assert(that._shadowIdMap.maxID<=that._shadowIdMap.mapping.length,"Too few ID map entries in "+that._vf.shadowObjectIdMapping+", "+"length of mapping array is only "+that._shadowIdMap.mapping.length+" instead of "+that._shadowIdMap.ids.length+"!");}};}}));x3dom.BindableStack=function(doc,type,defaultType,getter){this._doc=doc;this._type=type;this._defaultType=defaultType;this._defaultRoot=null;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){if(this._defaultRoot){x3dom.debug.logInfo('create new '+this._defaultType._typeName+' for '+this._type._typeName+'-stack');var obj=new this._defaultType({doc:this._doc,nameSpace:this._defaultRoot._nameSpace,autoGen:true});this._defaultRoot.addChild(obj);obj.nodeChanged();}
+else{x3dom.debug.logError('stack without defaultRoot');}}
+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);this.addType("X3DEnvironmentNode","Environment","getEnvironment",doc);};x3dom.BindableBag.prototype.addType=function(typeName,defaultTypeName,getter,doc){var type=x3dom.nodeTypes[typeName];var defaultType=x3dom.nodeTypes[defaultTypeName];if(type&&defaultType){var 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++){var stack=this._stacks[i];if(x3dom.isa(node,stack._type)){x3dom.debug.logInfo('register '+node.typeName()+'Bindable '+
+node._DEF+'/'+node._vf.description);stack._bindBag.push(node);var top=stack.top();if(top&&top._autoGen){stack.replaceTop(node);for(var j=0,m=stack._bindBag.length;j<m;j++){if(stack._bindBag[j]===top){stack._bindBag.splice(j,1);break;}}
+stack._defaultRoot.removeChild(top);}
+return stack;}}
+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.addField_SFBool(ctx,'useGeoCache',true);this.addField_SFBool(ctx,'lit',true);this._mesh=new x3dom.Mesh(this);},{getVolume:function(){return this._mesh.getVolume();},invalidateVolume:function(){this._mesh.invalidate();},getCenter:function(){return this._mesh.getCenter();},getDiameter:function(){return this._mesh.getDiameter();},doIntersect:function(line){return this._mesh.doIntersect(line);},forceUpdateCoverage:function(){return false;},hasIndexOffset:function(){return false;},getColorTexture:function(){return null;},getColorTextureURL:function(){return null;},parentAdded:function(parent){if(x3dom.isa(parent,x3dom.nodeTypes.X3DShapeNode)){if(parent._cleanupGLObjects){parent._cleanupGLObjects(true);}
+parent.setAllDirty();parent.invalidateVolume();}},needLighting:function(){var hasTris=this._mesh._primType.indexOf("TRIANGLE")>=0;return(this._vf.lit&&hasTris);}}));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.invalidateVolume();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.X3DCoordinateNode);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this._mesh._primType='POINTS';},{nodeChanged:function()
+{var time0=new Date().getTime();var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);var positions=coordNode.getPoints();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;}}
+this._mesh._numColComponents=numColComponents;this._mesh._lit=false;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.invalidateVolume();this._mesh._numCoords=this._mesh._positions[0].length/3;var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
+{var pnts=null;if(fieldName=="coord")
+{pnts=this._cf.coord.node.getPoints();this._mesh._positions[0]=pnts.toGL();this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName=="color")
+{pnts=this._cf.color.node._vf.color;this._mesh._colors[0]=pnts.toGL();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_SFString(ctx,'normalUpdateMode','fast');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("LineSet","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.LineSet.superClass.call(this,ctx);this.addField_MFInt32(ctx,'vertexCount',[]);this.addField_MFNode('attrib',x3dom.nodeTypes.X3DVertexAttributeNode);this.addField_SFNode('coord',x3dom.nodeTypes.X3DCoordinateNode);this.addField_SFNode('color',x3dom.nodeTypes.X3DColorNode);this._mesh._primType="LINES";x3dom.Utils.needLineWidth=true;},{nodeChanged:function(){var coordNode=this._cf.coord.node;x3dom.debug.assert(coordNode);var positions=coordNode.getPoints();this._mesh._positions[0]=positions.toGL();var colorNode=this._cf.color.node;if(colorNode){var colors=colorNode._vf.color;this._mesh._colors[0]=colors.toGL();var numColComponents=3;if(x3dom.isa(colorNode,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}}
+var cnt=0;this._mesh._indices[0]=[];for(var i=0,n=this._vf.vertexCount.length;i<n;i++){var vc=this._vf.vertexCount[i];if(vc<2){x3dom.debug.logError("LineSet.vertexCount must not be smaller than 2!");break;}
+for(var j=vc-2;j>=0;j--){this._mesh._indices[0].push(cnt++,cnt);if(j==0)cnt++;}}},fieldChanged:function(fieldName){if(fieldName=="coord"){var pnts=this._cf.coord.node.getPoints();this._mesh._positions[0]=pnts.toGL();this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName=="color"){var cols=this._cf.color.node._vf.color;this._mesh._colors[0]=cols.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}}}));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._mesh._primType='LINES';x3dom.Utils.needLineWidth=true;},{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)||positions.length>x3dom.Utils.maxIndexableCoords)
+{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 2: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:}}
+if(positions.length>x3dom.Utils.maxIndexableCoords)
+this._mesh.splitMesh(2);}
+else
+{var n=indexes.length;t=0;for(i=0;i<n;++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.invalidateVolume();this._mesh._numCoords=0;for(i=0;i<this._mesh._indices.length;i++){this._mesh._numCoords+=this._mesh._positions[i].length/3;}
+var time1=new Date().getTime()-time0;},fieldChanged:function(fieldName)
+{var pnts=null;if(fieldName=="coord")
+{pnts=this._cf.coord.node._vf.point;this._mesh._positions[0]=pnts.toGL();this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName=="color")
+{pnts=this._cf.color.node._vf.color;this._mesh._colors[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
+else if(fieldName=="coordIndex"){this._mesh._indices[0]=[];var indexes=this._vf.coordIndex;var p0,p1,t=0;for(var i=0,n=indexes.length;i<n;++i){if(indexes[i]==-1){t=0;}
+else{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.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.indexes=true;node.invalidateVolume();});}}}));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 colPerVert=this._vf.colorPerVertex;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(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+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(!normPerVert||posMax>x3dom.Utils.maxIndexableCoords)
+{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];if(normPerVert){n0=p0;}else if(!normPerVert){n0=faceCnt;}
+t0=p0;if(colPerVert){c0=p0;}else if(!colPerVert){c0=faceCnt;}
+t=1;break;case 1:p1=+indexes[i];if(normPerVert){n1=p1;}else if(!normPerVert){n1=faceCnt;}
+t1=p1;if(colPerVert){c1=p1;}else if(!colPerVert){c1=faceCnt;}
+t=2;break;case 2:p2=+indexes[i];if(normPerVert){n2=p2;}else if(!normPerVert){n2=faceCnt;}
+t2=p2;if(colPerVert){c2=p2;}else if(!colPerVert){c2=faceCnt;}
+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(normPerVert?Math.PI:0);}
+if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
+this._mesh.splitMesh();}
+else
+{faceCnt=0;for(i=0;i<indexes.length;i++)
+{if((i>0)&&(i%3===0)){faceCnt++;}
+this._mesh._indices[0].push(indexes[i]);if(!normPerVert&&hasNormal){this._mesh._normals[0].push(normals[faceCnt].x);this._mesh._normals[0].push(normals[faceCnt].y);this._mesh._normals[0].push(normals[faceCnt].z);}
+if(!colPerVert&&hasColor){this._mesh._colors[0].push(colors[faceCnt].r);this._mesh._colors[0].push(colors[faceCnt].g);this._mesh._colors[0].push(colors[faceCnt].b);if(numColComponents===4){this._mesh._colors[0].push(colors[faceCnt].a);}}}
+this._mesh._positions[0]=positions.toGL();if(hasNormal){this._mesh._normals[0]=normals.toGL();}
+else{this._mesh.calcNormals(normPerVert?Math.PI:0);}
+if(hasTexCoord){this._mesh._texCoords[0]=texCoords.toGL();this._mesh._numTexComponents=numTexComponents;}
+else{this._mesh.calcTexCoords(texMode);}
+if(hasColor&&colPerVert){this._mesh._colors[0]=colors.toGL();this._mesh._numColComponents=numColComponents;}}
+this.invalidateVolume();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;if(pnts.length>x3dom.Utils.maxIndexableCoords)
+{x3dom.debug.logWarning("IndexedTriangleSet: fieldChanged with "+"too many coordinates not yet implemented!");return;}
+if(fieldName=="coord")
+{this._mesh._positions[0]=pnts.toGL();this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName=="color")
+{pnts=this._cf.color.node._vf.color;if(this._vf.colorPerVertex){this._mesh._colors[0]=pnts.toGL();}else if(!this._vf.colorPerVertex){var faceCnt=0;var numColComponents=3;if(x3dom.isa(this._cf.color.node,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}
+this._mesh._colors[0]=[];var indexes=this._vf.index;for(var i=0;i<indexes.length;++i)
+{if((i>0)&&(i%3===0)){faceCnt++;}
+this._mesh._colors[0].push(pnts[faceCnt].r);this._mesh._colors[0].push(pnts[faceCnt].g);this._mesh._colors[0].push(pnts[faceCnt].b);if(numColComponents===4){this._mesh._colors[0].push(pnts[faceCnt].a);}}}
+Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
+else if(fieldName=="normal")
+{pnts=this._cf.normal.node._vf.vector;if(this._vf.normalPerVertex){this._mesh._normals[0]=pnts.toGL();}else if(!this._vf.normalPerVertex){var indexes=this._vf.index;this._mesh._normals[0]=[];var faceCnt=0;for(var i=0;i<indexes.length;++i)
+{if((i>0)&&(i%3===0)){faceCnt++;}
+this._mesh._normals[0].push(pnts[faceCnt].x);this._mesh._normals[0].push(pnts[faceCnt].y);this._mesh._normals[0].push(pnts[faceCnt].z);}}
+Array.forEach(this._parentNodes,function(node){node._dirty.normals=true;});}
+else if(fieldName=="texCoord")
+{var texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+pnts=texCoordNode._vf.point;this._mesh._texCoords[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.texcoords=true;});}}}));x3dom.registerNodeType("IndexedTriangleStripSet","Rendering",defineClass(x3dom.nodeTypes.X3DComposedGeometryNode,function(ctx){x3dom.nodeTypes.IndexedTriangleStripSet.superClass.call(this,ctx);this.addField_MFInt32(ctx,'index',[]);this._hasIndexOffset=false;this._indexOffset=null;},{hasIndexOffset:function(){return this._hasIndexOffset;},nodeChanged:function()
+{this.handleAttribs();var hasNormal=false,hasTexCoord=false,hasColor=false;var colPerVert=this._vf.colorPerVertex;var normPerVert=this._vf.normalPerVertex;var indexes=this._vf.index;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(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+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]=[];this.invalidateVolume();this._mesh._numFaces=0;this._mesh._numCoords=0;var faceCnt=0,cnt=0;if(hasNormal&&positions.length<=x3dom.Utils.maxIndexableCoords)
+{this._hasIndexOffset=true;this._indexOffset=[];this._mesh._primType='TRIANGLESTRIP';var indexOffset=[0];for(i=0;i<indexes.length;i++)
+{if(indexes[i]==-1){faceCnt++;indexOffset.push(this._mesh._indices[0].length);}
+else{this._mesh._indices[0].push(+indexes[i]);if(!normPerVert){this._mesh._normals[0].push(normals[faceCnt].x);this._mesh._normals[0].push(normals[faceCnt].y);this._mesh._normals[0].push(normals[faceCnt].z);}
+if(!colPerVert){this._mesh._colors[0].push(colors[faceCnt].r);this._mesh._colors[0].push(colors[faceCnt].g);this._mesh._colors[0].push(colors[faceCnt].b);if(numColComponents===4){this._mesh._colors[0].push(colors[faceCnt].a);}}}}
+this._mesh._positions[0]=positions.toGL();if(normPerVert){this._mesh._normals[0]=normals.toGL();}
+if(hasTexCoord){this._mesh._texCoords[0]=texCoords.toGL();this._mesh._numTexComponents=numTexComponents;}
+else{x3dom.debug.logWarning("IndexedTriangleStripSet: no texCoords given and won't calculate!");}
+if(hasColor){if(colPerVert){this._mesh._colors[0]=colors.toGL();}
+this._mesh._numColComponents=numColComponents;}
+for(i=1;i<indexOffset.length;i++){var triCnt=indexOffset[i]-indexOffset[i-1];this._indexOffset.push({count:triCnt,offset:2*indexOffset[i-1]});this._mesh._numFaces+=(triCnt-2);}
+this._mesh._numCoords=this._mesh._positions[0].length/3;}
+else
+{this._hasIndexOffset=false;var p1,p2,p3,n1,n2,n3,t1,t2,t3,c1,c2,c3;var swapOrder=false;for(var i=1;i<indexes.length-2;++i)
+{if(indexes[i+1]==-1){i=i+2;faceCnt++;continue;}
+if(swapOrder){p1=indexes[i];p2=indexes[i-1];p3=indexes[i+1];}
+else{p1=indexes[i-1];p2=indexes[i];p3=indexes[i+1];}
+swapOrder=!swapOrder;if(normPerVert){n1=p1;n2=p2;n3=p3;}else if(!normPerVert){n1=n2=n3=faceCnt;}
+t1=p1;t2=p2;t3=p3;if(colPerVert){c1=p1;c2=p2;c3=p3;}else if(!colPerVert){c1=c2=c3=faceCnt;}
+this._mesh._indices[0].push(cnt++,cnt++,cnt++);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);this._mesh._positions[0].push(positions[p3].x);this._mesh._positions[0].push(positions[p3].y);this._mesh._positions[0].push(positions[p3].z);if(hasNormal){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);this._mesh._normals[0].push(normals[n3].x);this._mesh._normals[0].push(normals[n3].y);this._mesh._normals[0].push(normals[n3].z);}
+if(hasColor){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);}
+this._mesh._colors[0].push(colors[c3].r);this._mesh._colors[0].push(colors[c3].g);this._mesh._colors[0].push(colors[c3].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c3].a);}}
+if(hasTexCoord){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);}
+this._mesh._texCoords[0].push(texCoords[t3].x);this._mesh._texCoords[0].push(texCoords[t3].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t3].z);}}}
+if(!hasNormal){this._mesh.calcNormals(Math.PI);}
+if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
+this._mesh.splitMesh();this.invalidateVolume();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;}}},fieldChanged:function(fieldName)
+{if(fieldName!="coord"&&fieldName!="normal"&&fieldName!="texCoord"&&fieldName!="color")
+{x3dom.debug.logWarning("IndexedTriangleStripSet: fieldChanged for "+
+fieldName+" not yet implemented!");return;}
+var pnts=this._cf.coord.node._vf.point;if((this._cf.normal.node===null)||(pnts.length>x3dom.Utils.maxIndexableCoords))
+{if(fieldName=="coord"){this._mesh._positions[0]=[];this._mesh._indices[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];var hasNormal=false,hasTexCoord=false,hasColor=false;var colPerVert=this._vf.colorPerVertex;var normPerVert=this._vf.normalPerVertex;var indexes=this._vf.index;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(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+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 faceCnt=0,cnt=0;var p1,p2,p3,n1,n2,n3,t1,t2,t3,c1,c2,c3;var swapOrder=false;if(hasNormal||hasTexCoord||hasColor){for(var i=1;i<indexes.length-2;++i)
+{if(indexes[i+1]==-1){i=i+2;faceCnt++;continue;}
+if(swapOrder){p1=indexes[i];p2=indexes[i-1];p3=indexes[i+1];}
+else{p1=indexes[i-1];p2=indexes[i];p3=indexes[i+1];}
+swapOrder=!swapOrder;if(normPerVert){n1=p1;n2=p2;n3=p3;}else if(!normPerVert){n1=n2=n3=faceCnt;}
+t1=p1;t2=p2;t3=p3;if(colPerVert){c1=p1;c2=p2;c3=p3;}else if(!colPerVert){c1=c2=c3=faceCnt;}
+this._mesh._indices[0].push(cnt++,cnt++,cnt++);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);this._mesh._positions[0].push(positions[p3].x);this._mesh._positions[0].push(positions[p3].y);this._mesh._positions[0].push(positions[p3].z);if(hasNormal){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);this._mesh._normals[0].push(normals[n3].x);this._mesh._normals[0].push(normals[n3].y);this._mesh._normals[0].push(normals[n3].z);}
+if(hasColor){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);}
+this._mesh._colors[0].push(colors[c3].r);this._mesh._colors[0].push(colors[c3].g);this._mesh._colors[0].push(colors[c3].b);if(numColComponents===4){this._mesh._colors[0].push(colors[c3].a);}}
+if(hasTexCoord){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);}
+this._mesh._texCoords[0].push(texCoords[t3].x);this._mesh._texCoords[0].push(texCoords[t3].y);if(numTexComponents===3){this._mesh._texCoords[0].push(texCoords[t3].z);}}}
+if(!hasNormal){this._mesh.calcNormals(Math.PI);}
+if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
+this._mesh.splitMesh();}else{var swapOrder=false;for(var i=1;i<indexes.length;++i)
+{if(indexes[i+1]==-1){i=i+2;continue;}
+if(swapOrder){this._mesh._indices[0].push(indexes[i]);this._mesh._indices[0].push(indexes[i-1]);this._mesh._indices[0].push(indexes[i+1]);}
+else{this._mesh._indices[0].push(indexes[i-1]);this._mesh._indices[0].push(indexes[i]);this._mesh._indices[0].push(indexes[i+1]);}
+swapOrder=!swapOrder;}
+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.invalidateVolume();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;}
+Array.forEach(this._parentNodes,function(node){node.setAllDirty();node.invalidateVolume();});}
+else if(fieldName=="color"){var col=this._cf.color.node._vf.color;var faceCnt=0;var c1=c2=c3=0;var numColComponents=3;if(x3dom.isa(this._cf.color.node,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}
+this._mesh._colors[0]=[];var indexes=this._vf.index;var swapOrder=false;for(i=1;i<indexes.length-2;++i)
+{if(indexes[i+1]==-1){i=i+2;faceCnt++;continue;}
+if(this._vf.colorPerVertex){if(swapOrder){c1=indexes[i];c2=indexes[i-1];c3=indexes[i+1];}
+else{c1=indexes[i-1];c2=indexes[i];c3=indexes[i+1];}
+swapOrder=!swapOrder;}else if(!this._vf.colorPerVertex){c1=c2=c3=faceCnt;}
+this._mesh._colors[0].push(col[c1].r);this._mesh._colors[0].push(col[c1].g);this._mesh._colors[0].push(col[c1].b);if(numColComponents===4){this._mesh._colors[0].push(col[c1].a);}
+this._mesh._colors[0].push(col[c2].r);this._mesh._colors[0].push(col[c2].g);this._mesh._colors[0].push(col[c2].b);if(numColComponents===4){this._mesh._colors[0].push(col[c2].a);}
+this._mesh._colors[0].push(col[c3].r);this._mesh._colors[0].push(col[c3].g);this._mesh._colors[0].push(col[c3].b);if(numColComponents===4){this._mesh._colors[0].push(col[c3].a);}}
+Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
+else if(fieldName=="normal"){var nor=this._cf.normal.node._vf.vector;var faceCnt=0;var n1=n2=n3=0;this._mesh._normals[0]=[];var indexes=this._vf.index;var swapOrder=false;for(i=1;i<indexes.length-2;++i)
+{if(indexes[i+1]==-1){i=i+2;faceCnt++;continue;}
+if(this._vf.normalPerVertex){if(swapOrder){n1=indexes[i];n2=indexes[i-1];n3=indexes[i+1];}
+else{n1=indexes[i-1];n2=indexes[i];n3=indexes[i+1];}
+swapOrder=!swapOrder;}else if(!this._vf.normalPerVertex){n1=n2=n3=faceCnt;}
+this._mesh._normals[0].push(nor[n1].x);this._mesh._normals[0].push(nor[n1].y);this._mesh._normals[0].push(nor[n1].z);this._mesh._normals[0].push(nor[n2].x);this._mesh._normals[0].push(nor[n2].y);this._mesh._normals[0].push(nor[n2].z);this._mesh._normals[0].push(nor[n3].x);this._mesh._normals[0].push(nor[n3].y);this._mesh._normals[0].push(nor[n3].z);}
+Array.forEach(this._parentNodes,function(node){node._dirty.normals=true;});}
+else if(fieldName=="texCoord"){var texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+var tex=texCoordNode._vf.point;var t1=t2=t3=0;var numTexComponents=2;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.TextureCoordinate3D)){numTexComponents=3;}
+this._mesh._texCoords[0]=[];var indexes=this._vf.index;var swapOrder=false;for(i=1;i<indexes.length-2;++i)
+{if(indexes[i+1]==-1){i=i+2;continue;}
+if(swapOrder){t1=indexes[i];t2=indexes[i-1];t3=indexes[i+1];}
+else{t1=indexes[i-1];t2=indexes[i];t3=indexes[i+1];}
+swapOrder=!swapOrder;this._mesh._texCoords[0].push(tex[t1].x);this._mesh._texCoords[0].push(tex[t1].y);if(numTexComponents===3){this._mesh._texCoords[0].push(tex[t1].z);}
+this._mesh._texCoords[0].push(tex[t2].x);this._mesh._texCoords[0].push(tex[t2].y);if(numTexComponents===3){this._mesh._texCoords[0].tex(col[t2].z);}
+this._mesh._texCoords[0].push(tex[t3].x);this._mesh._texCoords[0].push(tex[t3].y);if(numTexComponents===3){this._mesh._texCoords[0].push(tex[t3].z);}}
+Array.forEach(this._parentNodes,function(node){node._dirty.texcoords=true;});}}
+else
+{if(fieldName=="coord")
+{this._mesh._positions[0]=pnts.toGL();this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName=="color")
+{pnts=this._cf.color.node._vf.color;if(this._vf.colorPerVertex){this._mesh._colors[0]=pnts.toGL();}else if(!this._vf.colorPerVertex){var faceCnt=0;var numColComponents=3;if(x3dom.isa(this._cf.color.node,x3dom.nodeTypes.ColorRGBA)){numColComponents=4;}
+this._mesh._colors[0]=[];var indexes=this._vf.index;for(i=0;i<indexes.length;++i)
+{if(indexes[i]==-1){faceCnt++;continue;}
+this._mesh._colors[0].push(pnts[faceCnt].r);this._mesh._colors[0].push(pnts[faceCnt].g);this._mesh._colors[0].push(pnts[faceCnt].b);if(numColComponents===4){this._mesh._colors[0].push(pnts[faceCnt].a);}}}
+Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
+else if(fieldName=="normal")
+{pnts=this._cf.normal.node._vf.vector;if(this._vf.normalPerVertex){this._mesh._normals[0]=pnts.toGL();}else if(!this._vf.normalPerVertex){var indexes=this._vf.index;this._mesh._normals[0]=[];var faceCnt=0;for(i=0;i<indexes.length;++i)
+{if(indexes[i]==-1){faceCnt++;continue;}
+this._mesh._normals[0].push(pnts[faceCnt].x);this._mesh._normals[0].push(pnts[faceCnt].y);this._mesh._normals[0].push(pnts[faceCnt].z);}}
+Array.forEach(this._parentNodes,function(node){node._dirty.normals=true;});}
+else if(fieldName=="texCoord")
+{var texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+pnts=texCoordNode._vf.point;this._mesh._texCoords[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.texcoords=true;});}}}}));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){if(fieldName==="coord"||fieldName==="point"){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){if(fieldName==="normal"||fieldName==="vector"){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){if(fieldName==="color"){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("ParticleSet","Rendering",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.ParticleSet.superClass.call(this,ctx);this.addField_SFString(ctx,'mode','ViewDirQuads');this.addField_SFString(ctx,'mode','ViewDirQuads');this.addField_SFNode(ctx,'coord',null);this.addField_SFNode(ctx,'secCoord',null);this.addField_SFNode(ctx,'color',null);this.addField_SFNode(ctx,'normal',null);this.addField_MFVec3f(ctx,'size',null);this.addField_MFInt32(ctx,'index',null);this.addField_MFFloat(ctx,'textureZ',null);},{getVolume:function(){},fieldChanged:function(fieldName)
+{if(fieldName=='mode')
+{console.log("mode has been changed");}},getCenter:function(){},getDiameter:function(){}}));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('lineProperties',x3dom.nodeTypes.LineProperties);this.addField_SFNode('colorMaskMode',x3dom.nodeTypes.ColorMaskMode);this.addField_SFNode('blendMode',x3dom.nodeTypes.BlendMode);this.addField_SFNode('depthMode',x3dom.nodeTypes.DepthMode);this.addField_MFNode('shaders',x3dom.nodeTypes.X3DShaderNode);this.addField_SFString(ctx,'sortType','auto');this.addField_SFInt32(ctx,'sortKey',0);this._shader=null;},{nodeChanged:function(){if(!this._cf.material.node){}
+if(this._cf.shaders.nodes.length){this._shader=this._cf.shaders.nodes[0];}
+Array.forEach(this._parentNodes,function(shape){shape.setAppDirty();});this.checkSortType();},checkSortType:function(){if(this._vf.sortType=='auto'){if(this._cf.material.node&&this._cf.material.node._vf.transparency>0){this._vf.sortType='transparent';}
+else if(this._cf.texture.node&&this._cf.texture.node._vf.url.length){if(this._cf.texture.node._vf.url[0].toLowerCase().indexOf('.'+'png')>=0){this._vf.sortType='transparent';}
+else{this._vf.sortType='opaque';}}
+else{this._vf.sortType='opaque';}}},texTransformMatrix:function(){if(this._cf.textureTransform.node===null){return x3dom.fields.SFMatrix4f.identity();}
+else{return this._cf.textureTransform.node.texTransformMatrix();}},parentAdded:function(parent){if(this!=x3dom.nodeTypes.Appearance._defaultNode){parent.setAppDirty();}}}));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("ColorMaskMode","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.ColorMaskMode.superClass.call(this,ctx);this.addField_SFBool(ctx,'maskR',true);this.addField_SFBool(ctx,'maskG',true);this.addField_SFBool(ctx,'maskB',true);this.addField_SFBool(ctx,'maskA',true);}));x3dom.registerNodeType("LineProperties","Shape",defineClass(x3dom.nodeTypes.X3DAppearanceChildNode,function(ctx){x3dom.nodeTypes.LineProperties.superClass.call(this,ctx);this.addField_SFBool(ctx,'applied',true);this.addField_SFInt32(ctx,'linetype',1);this.addField_SFFloat(ctx,'linewidthScaleFactor',0);}));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;});app.checkSortType();});}}}));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("TwoSidedMaterial","Shape",defineClass(x3dom.nodeTypes.X3DMaterialNode,function(ctx){x3dom.nodeTypes.TwoSidedMaterial.superClass.call(this,ctx);this.addField_SFFloat(ctx,'backAmbientIntensity',0.2);this.addField_SFColor(ctx,'backDiffuseColor',0.8,0.8,0.8);this.addField_SFColor(ctx,'backEmissiveColor',0,0,0);this.addField_SFFloat(ctx,'backShininess',0.2);this.addField_SFColor(ctx,'backSpecularColor',0,0,0);this.addField_SFFloat(ctx,'backTransparency',0);this.addField_SFBool(ctx,'separateBackColor',false);},{fieldChanged:function(fieldName){if(fieldName=="ambientIntensity"||fieldName=="diffuseColor"||fieldName=="emissiveColor"||fieldName=="shininess"||fieldName=="specularColor"||fieldName=="transparency"||fieldName=="backAmbientIntensity"||fieldName=="backDiffuseColor"||fieldName=="backEmissiveColor"||fieldName=="backShininess"||fieldName=="backSpecularColor"||fieldName=="backTransparency"||fieldName=="separateBackColor")
+{Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.material=true;});app.checkSortType();});}}}));x3dom.registerNodeType("X3DShapeNode","Shape",defineClass(x3dom.nodeTypes.X3DBoundedObject,function(ctx){x3dom.nodeTypes.X3DShapeNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'isPickable',true);this.addField_SFNode('appearance',x3dom.nodeTypes.X3DAppearanceNode);this.addField_SFNode('geometry',x3dom.nodeTypes.X3DGeometryNode);this._objectID=0;this._shaderProperties=null;this._cleanupGLObjects=null;this._dirty={positions:true,normals:true,texcoords:true,colors:true,indexes:true,texture:true,material:true,text:true,shader:true};this._coordStrideOffset=[0,0];this._normalStrideOffset=[0,0];this._texCoordStrideOffset=[0,0];this._colorStrideOffset=[0,0];this._tessellationProperties=[];},{collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{var graphState=this.graphState();if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();if(!this._cf.geometry.node||drawableCollection.cull(transform,graphState,singlePath,planeMask)<=0){return false;}
+if(singlePath&&!this._graph.globalMatrix)
+this._graph.globalMatrix=transform;drawableCollection.addShape(this,transform,graphState);return true;},getVolume:function()
+{var vol=this._graph.volume;if(!this.volumeValid()&&this._vf.render)
+{var geo=this._cf.geometry.node;var childVol=geo?geo.getVolume():null;if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}
+return vol;},getCenter:function(){var geo=this._cf.geometry.node;return(geo?geo.getCenter():new x3dom.fields.SFVec3f(0,0,0));},getDiameter:function(){var geo=this._cf.geometry.node;return(geo?geo.getDiameter():0);},doIntersect:function(line){return this._cf.geometry.node.doIntersect(line);},forceUpdateCoverage:function()
+{var geo=this._cf.geometry.node;return(geo?geo.forceUpdateCoverage():false);},tessellationProperties:function()
+{var geo=this._cf.geometry.node;if(geo&&geo._indexOffset)
+return geo._indexOffset;else
+return this._tessellationProperties;},isLit:function(){return this._cf.geometry.node._vf.lit;},isSolid:function(){return this._cf.geometry.node._vf.solid;},isCCW:function(){return this._cf.geometry.node._vf.ccw;},parentRemoved:function(parent){for(var i=0,n=this._childNodes.length;i<n;i++){var child=this._childNodes[i];if(child){child.parentRemoved(this);}}
+if(parent)
+parent.invalidateVolume();if(this._parentNodes.length>0)
+this.invalidateVolume();if(this._cleanupGLObjects){this._cleanupGLObjects();}},unsetDirty:function(){this._dirty.positions=false;this._dirty.normals=false;this._dirty.texcoords=false;this._dirty.colors=false;this._dirty.indexes=false;this._dirty.texture=false;this._dirty.material=false;this._dirty.text=false;this._dirty.shader=false;},unsetGeoDirty:function(){this._dirty.positions=false;this._dirty.normals=false;this._dirty.texcoords=false;this._dirty.colors=false;this._dirty.indexes=false;},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;this.invalidateVolume();},setAppDirty:function(){this._dirty.texture=true;this._dirty.material=true;this._dirty.shader=true;},setGeoDirty:function(){this._dirty.positions=true;this._dirty.normals=true;this._dirty.texcoords=true;this._dirty.colors=true;this._dirty.indexes=true;this.invalidateVolume();},getShaderProperties:function(viewarea)
+{if(this._shaderProperties==null||this._dirty.shader==true||(this._webgl!==undefined&&this._webgl.dirtyLighting!=x3dom.Utils.checkDirtyLighting(viewarea))||x3dom.Utils.checkDirtyEnvironment(viewarea,this._shaderProperties)==true)
+{this._shaderProperties=x3dom.Utils.generateProperties(viewarea,this);this._dirty.shader=false;if(this._webgl!==undefined)
+{this._webgl.dirtyLighting=x3dom.Utils.checkDirtyLighting(viewarea);}}
+return this._shaderProperties;},getTextures:function(){var textures=[];var appearance=this._cf.appearance.node;if(appearance){var tex=appearance._cf.texture.node;if(tex){if(x3dom.isa(tex,x3dom.nodeTypes.MultiTexture)){textures=textures.concat(tex.getTextures());}
+else{textures.push(tex);}}
+var shader=appearance._cf.shaders.nodes[0];if(shader){if(x3dom.isa(shader,x3dom.nodeTypes.CommonSurfaceShader)){textures=textures.concat(shader.getTextures());}}}
+var geometry=this._cf.geometry.node;if(geometry){if(x3dom.isa(geometry,x3dom.nodeTypes.ImageGeometry)){textures=textures.concat(geometry.getTextures());}
+else if(x3dom.isa(geometry,x3dom.nodeTypes.Text)){textures=textures.concat(geometry);}}
+return textures;}}));x3dom.registerNodeType("Shape","Shape",defineClass(x3dom.nodeTypes.X3DShapeNode,function(ctx){x3dom.nodeTypes.Shape.superClass.call(this,ctx);},{nodeChanged:function(){if(!this._cf.appearance.node){}
+if(!this._cf.geometry.node){if(this._DEF)
+x3dom.debug.logError("No geometry given in Shape/"+this._DEF);}
+else if(!this._objectID){this._objectID=++x3dom.nodeTypes.Shape.objectID;x3dom.nodeTypes.Shape.idMap.nodeID[this._objectID]=this;}
+this.invalidateVolume();}}));x3dom.nodeTypes.Shape.shaderPartID=0;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);if(ctx)
+ctx.doc._nodeBag.lights.push(this);else
+x3dom.debug.logWarning("X3DLightNode: No runtime context found!");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);this.addField_SFInt32(ctx,'shadowMapSize',1024);this.addField_SFInt32(ctx,'shadowFilterSize',0);this.addField_SFFloat(ctx,'shadowOffset',0);this.addField_SFFloat(ctx,'zFar',-1);},{getViewMatrix:function(vec){return x3dom.fields.SFMatrix4f.identity;},nodeChanged:function(){if(!this._lightID){this._lightID=++x3dom.nodeTypes.X3DLightNode.lightID;}},fieldChanged:function(fieldName)
+{if(this._vf.hasOwnProperty(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);this.addField_SFInt32(ctx,'shadowCascades',1);this.addField_SFFloat(ctx,'shadowSplitFactor',1);this.addField_SFFloat(ctx,'shadowSplitOffset',0.1);},{getViewMatrix:function(vec){var dir=this.getCurrentTransform().multMatrixVec(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.getCurrentTransform().multMatrixPnt(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.addField_SFInt32(ctx,'shadowCascades',1);this.addField_SFFloat(ctx,'shadowSplitFactor',1);this.addField_SFFloat(ctx,'shadowSplitOffset',0.1);this._vf.global=true;},{getViewMatrix:function(vec){var pos=this.getCurrentTransform().multMatrixPnt(this._vf.location);var dir=this.getCurrentTransform().multMatrixVec(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);if(ctx)
+ctx.doc._nodeBag.followers.push(this);else
+x3dom.debug.logWarning("X3DFollowerNode: No runtime context found!");this.addField_SFBool(ctx,'isActive',false);this._eps=x3dom.fields.Eps;},{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',1);this._initDone=false;this._stepTime=0;this._currTime=0;this._bufferEndTime=0;this._numSupports=60;}));x3dom.registerNodeType("X3DDamperNode","Followers",defineClass(x3dom.nodeTypes.X3DFollowerNode,function(ctx){x3dom.nodeTypes.X3DDamperNode.superClass.call(this,ctx);this.addField_SFTime(ctx,'tau',0.3);this.addField_SFFloat(ctx,'tolerance',-1);this.addField_SFInt32(ctx,'order',3);this._eps=this._vf.tolerance<0?this._eps:this._vf.tolerance;this._lastTick=0;}));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,'value',0,0,0);this.addField_SFColor(ctx,'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);this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName.indexOf("destination")>=0)
+{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
+else if(fieldName.indexOf("value")>=0)
+{this.initialize();this._previousValue.setValues(this._vf.value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.value);}
+this.postMessage('value',this._vf.value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
+{if(!this._initDone)
+{this._initDone=true;this._vf.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],this._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',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,this._eps)){this._value.setValues(Output);this.postMessage('value',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.destination.multiply((1-Alpha)));}}
+else
+{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.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,'value',0,0,0);this.addField_SFColor(ctx,'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();},{fieldChanged:function(fieldName)
+{if(fieldName==="tolerance")
+{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}
+else if(fieldName.indexOf("destination")>=0)
+{if(!this._value0.equals(this._vf.destination,this._eps)){this._value0=this._vf.destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
+else if(fieldName.indexOf("value")>=0)
+{this._value1.setValues(this._vf.value);this._value2.setValues(this._vf.value);this._value3.setValues(this._vf.value);this._value4.setValues(this._vf.value);this._value5.setValues(this._vf.value);this._lastTick=0;this.postMessage('value',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',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
+this.postMessage('value',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,'value',0,1,0,0);this.addField_SFRotation(ctx,'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);this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName.indexOf("destination")>=0)
+{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
+else if(fieldName.indexOf("value")>=0)
+{this.initialize();this._previousValue.setValues(this._vf.value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.value);}
+this.postMessage('value',this._vf.value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
+{if(!this._initDone)
+{this._initDone=true;this._vf.destination=x3dom.fields.Quaternion.copy(this._vf.initialDestination);this._buffer.length=this._numSupports;this._buffer[0]=x3dom.fields.Quaternion.copy(this._vf.initialDestination);for(var C=1;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.Quaternion.copy(this._vf.initialValue);}
+this._previousValue=x3dom.fields.Quaternion.copy(this._vf.initialValue);this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],this._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=x3dom.fields.Quaternion.copy(this._vf.initialValue);this.postMessage('value',this._value);return true;}
+var Frac=this.updateBuffer(now);var Output=x3dom.fields.Quaternion.copy(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,this._eps)){Output=Output.normalize(Output);this._value.setValues(Output);this.postMessage('value',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=x3dom.fields.Quaternion.copy(this._buffer[this._buffer.length-NumToShift]);for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=x3dom.fields.Quaternion.copy(this._buffer[C-NumToShift]);}
+for(C=0;C<NumToShift;C++)
+{Alpha=C/NumToShift;this._buffer[C]=this._vf.destination.slerp(this._buffer[NumToShift],Alpha);}}
+else
+{this._previousValue=x3dom.fields.Quaternion.copy((NumToShift==this._buffer.length)?this._buffer[0]:this._vf.destination);for(C=0;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.Quaternion.copy(this._vf.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,'value',0,1,0,0);this.addField_SFRotation(ctx,'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();},{fieldChanged:function(fieldName)
+{if(fieldName==="tolerance")
+{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}
+else if(fieldName.indexOf("destination")>=0)
+{if(!this._value0.equals(this._vf.destination,this._eps)){this._value0=this._vf.destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
+else if(fieldName.indexOf("value")>=0)
+{this._value1.setValues(this._vf.value);this._value2.setValues(this._vf.value);this._value3.setValues(this._vf.value);this._value4.setValues(this._vf.value);this._value5.setValues(this._vf.value);this._lastTick=0;this.postMessage('value',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',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
+this.postMessage('value',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,'value',0,0,0);this.addField_SFVec3f(ctx,'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);this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName.indexOf("destination")>=0)
+{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
+else if(fieldName.indexOf("value")>=0)
+{this.initialize();this._previousValue.setValues(this._vf.value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.value);}
+this.postMessage('value',this._vf.value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
+{if(!this._initDone)
+{this._initDone=true;this._vf.destination=x3dom.fields.SFVec3f.copy(this._vf.initialDestination);this._buffer.length=this._numSupports;this._buffer[0]=x3dom.fields.SFVec3f.copy(this._vf.initialDestination);for(var C=1;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.SFVec3f.copy(this._vf.initialValue);}
+this._previousValue=x3dom.fields.SFVec3f.copy(this._vf.initialValue);this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],this._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=x3dom.fields.SFVec3f.copy(this._vf.initialValue);this.postMessage('value',this._value);return true;}
+var Frac=this.updateBuffer(now);var Output=x3dom.fields.SFVec3f.copy(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,this._eps)){this._value.setValues(Output);this.postMessage('value',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=x3dom.fields.SFVec3f.copy(this._buffer[this._buffer.length-NumToShift]);for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=x3dom.fields.SFVec3f.copy(this._buffer[C-NumToShift]);}
+for(C=0;C<NumToShift;C++)
+{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift].multiply(Alpha).add(this._vf.destination.multiply((1-Alpha)));}}
+else
+{this._previousValue=x3dom.fields.SFVec3f.copy((NumToShift==this._buffer.length)?this._buffer[0]:this._vf.destination);for(C=0;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.SFVec3f.copy(this._vf.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,'value',0,0);this.addField_SFVec2f(ctx,'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);this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName.indexOf("destination")>=0)
+{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
+else if(fieldName.indexOf("value")>=0)
+{this.initialize();this._previousValue.setValues(this._vf.value);for(var C=1;C<this._buffer.length;C++){this._buffer[C].setValues(this._vf.value);}
+this.postMessage('value',this._vf.value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
+{if(!this._initDone)
+{this._initDone=true;this._vf.destination=x3dom.fields.SFVec2f.copy(this._vf.initialDestination);this._buffer.length=this._numSupports;this._buffer[0]=x3dom.fields.SFVec2f.copy(this._vf.initialDestination);for(var C=1;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.SFVec2f.copy(this._vf.initialValue);}
+this._previousValue=x3dom.fields.SFVec2f.copy(this._vf.initialValue);this._stepTime=this._vf.duration/this._numSupports;var active=!this._buffer[0].equals(this._buffer[1],this._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=x3dom.fields.SFVec2f.copy(this._vf.initialValue);this.postMessage('value',this._value);return true;}
+var Frac=this.updateBuffer(now);var Output=x3dom.fields.SFVec2f.copy(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,this._eps)){this._value.setValues(Output);this.postMessage('value',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=x3dom.fields.SFVec2f.copy(this._buffer[this._buffer.length-NumToShift]);for(C=this._buffer.length-1;C>=NumToShift;C--){this._buffer[C]=x3dom.fields.SFVec2f.copy(this._buffer[C-NumToShift]);}
+for(C=0;C<NumToShift;C++)
+{Alpha=C/NumToShift;this._buffer[C]=this._buffer[NumToShift].multiply(Alpha).add(this._vf.destination.multiply((1-Alpha)));}}
+else
+{this._previousValue=x3dom.fields.SFVec2f.copy((NumToShift==this._buffer.length)?this._buffer[0]:this._vf.destination);for(C=0;C<this._buffer.length;C++){this._buffer[C]=x3dom.fields.SFVec2f.copy(this._vf.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,'value',0,0,0);this.addField_SFVec3f(ctx,'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();},{fieldChanged:function(fieldName)
+{if(fieldName==="tolerance")
+{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}
+else if(fieldName.indexOf("destination")>=0)
+{if(!this._value0.equals(this._vf.destination,this._eps)){this._value0=this._vf.destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
+else if(fieldName.indexOf("value")>=0)
+{this._value1.setValues(this._vf.value);this._value2.setValues(this._vf.value);this._value3.setValues(this._vf.value);this._value4.setValues(this._vf.value);this._value5.setValues(this._vf.value);this._lastTick=0;this.postMessage('value',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',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
+this.postMessage('value',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,'value',0,0);this.addField_SFVec2f(ctx,'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();},{fieldChanged:function(fieldName)
+{if(fieldName==="tolerance")
+{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}
+else if(fieldName.indexOf("destination")>=0)
+{if(!this._value0.equals(this._vf.destination,this._eps)){this._value0=this._vf.destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
+else if(fieldName.indexOf("value")>=0)
+{this._value1.setValues(this._vf.value);this._value2.setValues(this._vf.value);this._value3.setValues(this._vf.value);this._value4.setValues(this._vf.value);this._value5.setValues(this._vf.value);this._lastTick=0;this.postMessage('value',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',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
+this.postMessage('value',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,'value',0);this.addField_SFFloat(ctx,'destination',0);this._buffer=[];this._previousValue=0;this._value=0;this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName.indexOf("destination")>=0)
+{this.initialize();this.updateBuffer(this._currTime);if(!this._vf.isActive){this.postMessage('isActive',true);}}
+else if(fieldName.indexOf("value")>=0)
+{this.initialize();this._previousValue=this._vf.value;for(var C=1;C<this._buffer.length;C++){this._buffer[C]=this._vf.value;}
+this.postMessage('value',this._vf.value);if(!this._vf.isActive){this.postMessage('isActive',true);}}},initialize:function()
+{if(!this._initDone)
+{this._initDone=true;this._vf.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])>this._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',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)>this._eps){this._value=Output;this.postMessage('value',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.destination*(1-Alpha);}}
+else
+{this._previousValue=(NumToShift==this._buffer.length)?this._buffer[0]:this._vf.destination;for(C=0;C<this._buffer.length;C++){this._buffer[C]=this._vf.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,'value',0);this.addField_SFFloat(ctx,'destination',0);this._value0=0;this._value1=0;this._value2=0;this._value3=0;this._value4=0;this._value5=0;this.initialize();},{fieldChanged:function(fieldName)
+{if(fieldName==="tolerance")
+{this._eps=this._vf.tolerance<0?0.001:this._vf.tolerance;}
+else if(fieldName.indexOf("destination")>=0)
+{if(Math.abs(this._value0-this._vf.destination)>this._eps){this._value0=this._vf.destination;if(!this._vf.isActive){this.postMessage('isActive',true);}}}
+else if(fieldName.indexOf("value")>=0)
+{this._value1=this._vf.value;this._value2=this._vf.value;this._value3=this._vf.value;this._value4=this._vf.value;this._value5=this._vf.value;this._lastTick=0;this.postMessage('value',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',this._value0);this.postMessage('isActive',false);this._lastTick=0;return false;}
+this.postMessage('value',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,'value',[]);this.addField_MFVec3f(ctx,'destination',[]);x3dom.debug.logWarning("CoordinateDamper NYI");}));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,'value',[]);this.addField_MFVec2f(ctx,'destination',[]);x3dom.debug.logWarning("TexCoordDamper2D NYI");}));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(time,interp){if(time<=this._vf.key[0])
+return this._vf.keyValue[0];else if(time>=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]<time)&&(time<=this._vf.key[i+1]))
+return interp(this._vf.keyValue[i],this._vf.keyValue[i+1],(time-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);this.addField_MFRotation(ctx,'keyValue',[]);},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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);this.addField_MFVec3f(ctx,'keyValue',[]);},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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);this.addField_MFVec3f(ctx,'keyValue',[]);},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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);this.addField_MFColor(ctx,'keyValue',[]);},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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);this.addField_MFFloat(ctx,'keyValue',[]);},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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.addField_MFVec3f(ctx,'keyValue',[]);if(ctx&&ctx.xmlNode.hasAttribute('keyValue')){this._vf.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);}}},{fieldChanged:function(fieldName)
+{if(fieldName==="set_fraction")
+{var value=this.linearInterp(this._vf.set_fraction,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);if(ctx)
+ctx.doc._nodeBag.timer.push(this);else
+x3dom.debug.logWarning("TimeSensor: No runtime context found!");this.addField_SFTime(ctx,'cycleInterval',1);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_SFTime(ctx,'elapsedTime',0);this.addField_SFFloat(ctx,'fraction_changed',0);this.addField_SFBool(ctx,'isActive',false);this.addField_SFBool(ctx,'isPaused',false);this.addField_SFTime(ctx,'time',0);this.addField_SFBool(ctx,'first',true);this.addField_SFFloat(ctx,'firstCycle',0.0);this._prevCycle=-1;this._lastTime=0;this._cycleStopTime=0;this._activatedTime=0;if(this._vf.startTime>0){this._updateCycleStopTime();}
+this._backupStartTime=this._vf.startTime;this._backupStopTime=this._vf.stopTime;this._backupCycleInterval=this._vf.cycleInterval;},{tick:function(time)
+{if(!this._vf.enabled){this._lastTime=time;return false;}
+var isActive=(this._vf.cycleInterval>0&&time>=this._vf.startTime&&(time<this._vf.stopTime||this._vf.stopTime<=this._vf.startTime)&&(this._vf.loop==true||(this._vf.loop==false&&time<this._cycleStopTime)));if(isActive&&!this._vf.isActive){this.postMessage('isActive',true);this._activatedTime=time;}
+if(isActive||this._vf.isActive){this.postMessage('elapsedTime',time-this._activatedTime);var isPaused=(time>=this._vf.pauseTime&&this._vf.pauseTime>this._vf.resumeTime);if(isPaused&&!this._vf.isPaused){this.postMessage('isPaused',true);this.postMessage('pauseTime',time);}else if(!isPaused&&this._vf.isPaused){this.postMessage('isPaused',false);this.postMessage('resumeTime',time);}
+if(!isPaused){var cycleFrac=this._getCycleAt(time);var cycle=Math.floor(cycleFrac);var cycleTime=this._vf.startTime+cycle*this._vf.cycleInterval;var adjustTime=0;if(this._vf.stopTime>this._vf.startTime&&this._lastTime<this._vf.stopTime&&time>=this._vf.stopTime)
+adjustTime=this._vf.stopTime;else if(this._lastTime<cycleTime&&time>=cycleTime)
+adjustTime=cycleTime;if(adjustTime>0){time=adjustTime;cycleFrac=this._getCycleAt(time);cycle=Math.floor(cycleFrac);}
+var fraction=cycleFrac-cycle;if(fraction<x3dom.fields.Eps){fraction=(this._lastTime<this._vf.startTime?0.0:1.0);this.postMessage('cycleTime',time);}
+this.postMessage('fraction_changed',fraction);this.postMessage('time',time);}}
+if(!isActive&&this._vf.isActive)
+this.postMessage('isActive',false);this._lastTime=time;return true;},fieldChanged:function(fieldName)
+{if(fieldName=="enabled"){if(!this._vf.enabled&&this._vf.isActive){this.postMessage('isActive',false);}}
+else if(fieldName=="startTime"){if(this._vf.isActive){this._vf.startTime=this._backupStartTime;return;}
+this._backupStartTime=this._vf.startTime;this._updateCycleStopTime();}
+else if(fieldName=="stopTime"){if(this._vf.isActive&&this._vf.stopTime<=this._vf.startTime){this._vf.stopTime=this._backupStopTime;return;}
+this._backupStopTime=this._vf.stopTime;}
+else if(fieldName=="cycleInterval"){if(this._vf.isActive){this._vf.cycleInterval=this._backupCycleInterval;return;}
+this._backupCycleInterval=this._vf.cycleInterval;}
+else if(fieldName=="loop"){this._updateCycleStopTime();}},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);}}}},_getCycleAt:function(time)
+{return Math.max(0.0,time-this._vf.startTime)/this._vf.cycleInterval;},_updateCycleStopTime:function()
+{if(this._vf.loop==false){var now=new Date().getTime()/1000;var cycleToStop=Math.floor(this._getCycleAt(now))+1;this._cycleStopTime=this._vf.startTime+cycleToStop*this._vf.cycleInterval;}
+else{this._cycleStopTime=0;}}}));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',[]);this.addField_MFString(ctx,'parameter',[]);this.addField_SFString(ctx,'description',"");},{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(){var url=this._vf.url.length?this._vf.url[0]:"";var aPos=url.search("#");var anchor="";if(aPos>=0)
+anchor=url.slice(aPos+1);var param=this._vf.parameter.length?this._vf.parameter[0]:"";var tPos=param.search("target=");var target="";if(tPos>=0)
+target=param.slice(tPos+7);x3dom.debug.logInfo("Anchor url="+url+", target="+target+", #viewpoint="+anchor);if(target.length==0||target=="_blank"){window.open(this._nameSpace.getURL(url),target);}
+else{window.location=this._nameSpace.getURL(url);}}}));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.initDone=false;this.count=0;this.numRetries=x3dom.nodeTypes.Inline.MaximumRetries;},{fieldChanged:function(fieldName)
+{if(fieldName=="url"){if(this._vf.nameSpaceName.length!=0){var node=this._xmlNode;if(node&&node.hasChildNodes())
+{while(node.childNodes.length>=1)
+{node.removeChild(node.firstChild);}}}
+this.loadInline();}
+else if(fieldName=="render"){this.invalidateVolume();}},nodeChanged:function()
+{if(!this.initDone){this.initDone=true;this.loadInline();}},fireEvents:function(eventType)
+{if(this._xmlNode&&(this._xmlNode['on'+eventType]||this._xmlNode.hasAttribute('on'+eventType)||this._listeners[eventType]))
+{var event={target:this._xmlNode,type:eventType,error:(eventType=="error")?"XMLHttpRequest Error":"",cancelBubble:false,stopPropagation:function(){this.cancelBubble=true;}};try{var attrib=this._xmlNode["on"+eventType];if(typeof(attrib)==="function"){attrib.call(this._xmlNode,event);}
+else{var funcStr=this._xmlNode.getAttribute("on"+eventType);var func=new Function('event',funcStr);func.call(this._xmlNode,event);}
+var list=this._listeners[eventType];if(list){for(var i=0;i<list.length;i++){list[i].call(this._xmlNode,event);}}}
+catch(ex){x3dom.debug.logException(ex);}}},loadInline:function()
+{var that=this;var xhr=new window.XMLHttpRequest();if(xhr.overrideMimeType)
+xhr.overrideMimeType('text/xml');xhr.onreadystatechange=function()
+{if(xhr.readyState!=4){return xhr;}
+if(xhr.status===x3dom.nodeTypes.Inline.AwaitTranscoding&&that.count<that.numRetries){that.count++;var refreshTime=+xhr.getResponseHeader("Refresh")||5;x3dom.debug.logInfo('Statuscode '+xhr.status+' and send new request in '+refreshTime+' sec.');window.setTimeout(function(){that._nameSpace.doc.downloadCount-=1;that.loadInline();},refreshTime*1000);return xhr;}
+else if((xhr.status!==200)&&(xhr.status!==0)){that.fireEvents("error");x3dom.debug.logError('XHR status: '+xhr.status+' - XMLHttpRequest requires web server running!');that._nameSpace.doc.downloadCount-=1;that.count=0;return xhr;}
+else if((xhr.status==200)||(xhr.status==0)){that.count=0;}
+x3dom.debug.logInfo('Inline: downloading '+that._vf.url[0]+' done.');var inlScene=null,newScene=null,nameSpace=null,xml=null;if(navigator.appName!="Microsoft Internet Explorer")
+xml=xhr.responseXML;else
+xml=new DOMParser().parseFromString(xhr.responseText,"text/xml");if(xml!==undefined&&xml!==null)
+{inlScene=xml.getElementsByTagName('Scene')[0]||xml.getElementsByTagName('scene')[0];}
+else{that.fireEvents("error");}
+if(inlScene)
+{var nsName=(that._vf.nameSpaceName.length!=0)?that._vf.nameSpaceName.toString().replace(' ',''):"";nameSpace=new x3dom.NodeNameSpace(nsName,that._nameSpace.doc);var url=that._vf.url.length?that._vf.url[0]:"";if((url[0]==='/')||(url.indexOf(":")>=0))
+nameSpace.setBaseURL(url);else
+nameSpace.setBaseURL(that._nameSpace.baseURL+url);newScene=nameSpace.setupTree(inlScene);that._nameSpace.addSpace(nameSpace);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._xmlNode.appendChild(childDomNode);}});}}
+else{if(xml&&xml.localName)
+x3dom.debug.logError('No Scene in '+xml.localName);else
+x3dom.debug.logError('No Scene in resource');}
+var global=x3dom.getGlobal();if(that._childNodes.length>0&&that._childNodes[0]&&that._childNodes[0]._nameSpace)
+that._nameSpace.removeSpace(that._childNodes[0]._nameSpace);while(that._childNodes.length!==0)
+global['_remover']=that.removeChild(that._childNodes[0]);delete global['_remover'];if(newScene)
+{that.addChild(newScene);that.invalidateVolume();that._nameSpace.doc.downloadCount-=1;that._nameSpace.doc.needRender=true;x3dom.debug.logInfo('Inline: added '+that._vf.url[0]+' to scene.');var theScene=that._nameSpace.doc._scene;if(theScene){theScene.invalidateVolume();window.setTimeout(function(){that.invalidateVolume();theScene.updateVolume();that._nameSpace.doc.needRender=true;},1000);}
+that.fireEvents("load");}
+newScene=null;nameSpace=null;inlScene=null;xml=null;return xhr;};if(this._vf.url.length&&this._vf.url[0].length)
+{var xhrURI=this._nameSpace.getURL(this._vf.url[0]);if(!(xhrURI.substr(0,5)==="blob:"))
+{xhrURI=encodeURI(xhrURI);}
+xhr.open('GET',xhrURI,true);this._nameSpace.doc.downloadCount+=1;try{xhr.send(null);}
+catch(ex){this.fireEvents("error");x3dom.debug.logError(this._vf.url[0]+": "+ex);}}}}));x3dom.nodeTypes.Inline.AwaitTranscoding=202;x3dom.nodeTypes.Inline.MaximumRetries=15;function setNamespace(prefix,childDomNode,mapDEFToID)
+{if(childDomNode instanceof Element&&childDomNode.__setAttribute!==undefined){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.id)
+childDomNode.id=childDomNode.__getAttribute('id');}}
+if(childDomNode.hasChildNodes()){Array.forEach(childDomNode.childNodes,function(children){setNamespace(prefix,children,mapDEFToID);});}}
+x3dom.registerNodeType("MultiPart","Networking",defineClass(x3dom.nodeTypes.Inline,function(ctx){x3dom.nodeTypes.MultiPart.superClass.call(this,ctx);this.addField_MFString(ctx,'urlIDMap',[]);this._idMap=null;this._oldPixels=null;this._inlineNamespace=null;this._highlightedParts=[];},{fieldChanged:function(fieldName)
+{if(fieldName=="url"){if(this._vf.nameSpaceName.length!=0){var node=this._xmlNode;if(node&&node.hasChildNodes())
+{while(node.childNodes.length>=1)
+{node.removeChild(node.firstChild);}}}
+this.loadInline();}
+else if(fieldName=="render"){this.invalidateVolume();}},nodeChanged:function()
+{if(!this.initDone){this.initDone=true;this.loadIDMap();this.appendAPI();this.appendEventListeners();}},appendEventListeners:function()
+{var that=this;this._xmlNode._shadowObjectID=-1
+this._xmlNode.addEventListener("mousedown",function(e){if(!that._nameSpace.doc._viewarea._isMoving){e.partID=that._idMap.mapping[e.shadowObjectId].name;this.dispatchEvent(new CustomEvent("partclick",{detail:e}));}},false);this._xmlNode.addEventListener("mouseout",function(e){if(!that._nameSpace.doc._viewarea._isMoving){if(e.shadowObjectId==-1){e.partID=that._idMap.mapping[this._shadowObjectID].name;this._shadowObjectID=-1;var event=new CustomEvent("partout",{detail:e});this.dispatchEvent(event);}}},false);this._xmlNode.addEventListener("mousemove",function(e){if(!that._nameSpace.doc._viewarea._isMoving){e.partID=that._idMap.mapping[e.shadowObjectId].name
+this.dispatchEvent(new CustomEvent("partmove",{detail:e}));if(e.shadowObjectId!=this._shadowObjectID){var tmp=e.shadowObjectId;if(this._shadowObjectID!=-1){e.partID=that._idMap.mapping[this._shadowObjectID].name;this.dispatchEvent(new CustomEvent("partout",{detail:e}));}
+this._shadowObjectID=e.shadowObjectId=tmp;e.partID=that._idMap.mapping[e.shadowObjectId].name;this.dispatchEvent(new CustomEvent("partover",{detail:e}));}}},false);},loadIDMap:function()
+{if(this._vf.urlIDMap.length&&this._vf.urlIDMap[0].length)
+{var that=this;var idMapURI=this._nameSpace.getURL(this._vf.urlIDMap[0]);var xhr=new XMLHttpRequest();xhr.open("GET",idMapURI,true);xhr.onload=function()
+{that._idMap=JSON.parse(this.responseText);that._nameSpace.doc._scene._shadowIdMap=eval("("+this.response+")");that.loadInline();};xhr.send(null);}},createImageData:function()
+{var diffuseColor,transparency,rgba;var size=x3dom.Utils.nextHighestPowerOfTwo(Math.sqrt(this._idMap.numberOfIDs));var imageData=size+" "+size+" 4";for(var i=0;i<size*size;i++)
+{if(i<this._idMap.mapping.length)
+{var appName=this._idMap.mapping[i].appearance;for(var a=0;a<this._idMap.appearance.length;a++)
+{if(this._idMap.appearance[a].name==appName)
+{diffuseColor=this._idMap.appearance[a].material.diffuseColor;transparency=this._idMap.appearance[a].material.transparency;rgba=x3dom.fields.SFColorRGBA.parse(diffuseColor+" "+transparency);imageData+=" "+rgba.toUint();}}}
+else
+{imageData+=" 255";}}
+return imageData;},createVisibilityData:function()
+{var size=x3dom.Utils.nextHighestPowerOfTwo(Math.sqrt(this._idMap.numberOfIDs));var visibilityData=size+" "+size+" 1";for(var i=0;i<size*size;i++)
+{if(i<this._idMap.mapping.length)
+{visibilityData+=" 255";}
+else
+{visibilityData+=" 0";}}
+return visibilityData;},replaceMaterials:function(inlScene)
+{var css;var firstMat=true;if(inlScene&&inlScene.hasChildNodes())
+{var shapes=inlScene.getElementsByTagName("Shape");for(var s=0;s<shapes.length;s++)
+{var appearances=shapes[s].getElementsByTagName("Appearance");if(appearances.length)
+{for(var a=0;a<appearances.length;a++)
+{var materials=appearances[a].getElementsByTagName("Material");if(materials.length)
+{if(firstMat){firstMat=false;css=document.createElement("CommonSurfaceShader");css.setAttribute("DEF","MultiMaterial");var sstDA=document.createElement("SurfaceShaderTexture");sstDA.setAttribute("containerField","multiDiffuseAlphaTexture");var ptDA=document.createElement("PixelTexture");ptDA.setAttribute("id","MultiMaterial_ColorMap");ptDA.setAttribute("image",this.createImageData());var sstV=document.createElement("SurfaceShaderTexture");sstV.setAttribute("containerField","multiVisibilityTexture");var ptV=document.createElement("PixelTexture");ptV.setAttribute("id","MultiMaterial_VisibilityMap");ptV.setAttribute("image",this.createVisibilityData());sstDA.appendChild(ptDA);sstV.appendChild(ptV);css.appendChild(sstDA);css.appendChild(sstV);}
+else
+{css=document.createElement("CommonSurfaceShader");css.setAttribute("USE","MultiMaterial");}
+materials[0].parentNode.replaceChild(css,materials[0]);}
+else
+{console.log("Add Material");}}}
+else
+{console.log("Add Appearance + Material");}}}},appendAPI:function()
+{var multiPart=this;this._xmlNode.getParts=function(selector)
+{var i,m;var selection=[]
+if(selector==undefined||selector.length==0){for(m=0;m<multiPart._idMap.mapping.length;m++){selection.push(m);}}
+else
+{for(i=0;i<selector.length;i++){for(m=0;m<multiPart._idMap.mapping.length;m++){if(selector[i].id==multiPart._idMap.mapping[m].name||selector[i].app==multiPart._idMap.mapping[m].appearance){selection.push(m);}}}}
+var Parts=function(ids,colorMap,visibilityMap)
+{var parts=this;this.ids=ids;this.colorMap=colorMap;this.visibilityMap=visibilityMap;this.setColor=function(color){var i,x,y;var colorRGBA=x3dom.fields.SFColorRGBA.parse(color);if(ids.length&&ids.length>1)
+{var pixels=parts.colorMap.getPixels();for(i=0;i<parts.ids.length;i++){if(multiPart._highlightedParts[parts.ids[i]]){multiPart._highlightedParts[parts.ids[i]]=colorRGBA;}else{pixels[parts.ids[i]]=colorRGBA;}}
+parts.colorMap.setPixels(pixels);}
+else
+{if(multiPart._highlightedParts[parts.ids[0]]){multiPart._highlightedParts[parts.ids[0]]=colorRGBA;}else{x=parts.ids[0]%parts.colorMap.getWidth();y=Math.floor(parts.ids[0]/parts.colorMap.getHeight());parts.colorMap.setPixel(x,y,colorRGBA);}}};this.setTransparency=function(transparency){var i,x,y;if(ids.length&&ids.length>1)
+{var pixels=parts.colorMap.getPixels();for(i=0;i<parts.ids.length;i++){if(multiPart._highlightedParts[parts.ids[i]]){multiPart._highlightedParts[parts.ids[i]].a=transparency;}else{pixels[parts.ids[i]].a=transparency;}}
+parts.colorMap.setPixels(pixels);}
+else
+{if(multiPart._highlightedParts[parts.ids[0]]){multiPart._highlightedParts[parts.ids[0]].a=transparency;}else{x=parts.ids[0]%parts.colorMap.getWidth();y=Math.floor(parts.ids[0]/parts.colorMap.getHeight());var pixel=parts.colorMap.getPixel(x,y);pixel.a=transparency;parts.colorMap.setPixel(x,y,pixel);}}};this.setVisibility=function(visibility){var i,x,y;if(ids.length&&ids.length>1)
+{var pixels=parts.visibilityMap.getPixels();for(i=0;i<parts.ids.length;i++){pixels[parts.ids[i]].r=(visibility)?1:0;}
+parts.visibilityMap.setPixels(pixels);}
+else
+{x=parts.ids[0]%parts.colorMap.getWidth();y=Math.floor(parts.ids[0]/parts.colorMap.getHeight());var pixel=parts.visibilityMap.getPixel(x,y);pixel.r=(visibility)?1:0;parts.visibilityMap.setPixel(x,y,pixel);}};this.highlight=function(color){var i,x,y;var colorRGBA=x3dom.fields.SFColorRGBA.parse(color);if(ids.length&&ids.length>1)
+{var pixels=parts.colorMap.getPixels();for(i=0;i<parts.ids.length;i++){if(multiPart._highlightedParts[parts.ids[i]]==undefined){multiPart._highlightedParts[parts.ids[i]]=pixels[parts.ids[i]]
+pixels[parts.ids[i]]=colorRGBA;}}
+parts.colorMap.setPixels(pixels);}
+else
+{if(multiPart._highlightedParts[parts.ids[0]]==undefined){x=parts.ids[0]%parts.colorMap.getWidth();y=Math.floor(parts.ids[0]/parts.colorMap.getHeight());multiPart._highlightedParts[parts.ids[0]]=parts.colorMap.getPixel(x,y);parts.colorMap.setPixel(x,y,colorRGBA);}}};this.unhighlight=function(){var i,x,y;if(ids.length&&ids.length>1)
+{var pixels=parts.colorMap.getPixels();for(i=0;i<parts.ids.length;i++){if(multiPart._highlightedParts[parts.ids[i]]){pixels[parts.ids[i]]=multiPart._highlightedParts[parts.ids[i]];multiPart._highlightedParts[parts.ids[i]]=undefined;}}
+parts.colorMap.setPixels(pixels);}
+else
+{if(multiPart._highlightedParts[parts.ids[0]]){x=parts.ids[0]%parts.colorMap.getWidth();y=Math.floor(parts.ids[0]/parts.colorMap.getHeight());var pixel=multiPart._highlightedParts[parts.ids[0]];multiPart._highlightedParts[parts.ids[0]]=undefined;parts.colorMap.setPixel(x,y,pixel);}}};};var colorMap=multiPart._inlineNamespace.defMap["MultiMaterial_ColorMap"];var visibilityMap=multiPart._inlineNamespace.defMap["MultiMaterial_VisibilityMap"];return new Parts(selection,colorMap,visibilityMap);}},loadInline:function()
+{var that=this;var xhr=new window.XMLHttpRequest();if(xhr.overrideMimeType)
+xhr.overrideMimeType('text/xml');xhr.onreadystatechange=function()
+{if(xhr.readyState!=4){return xhr;}
+if(xhr.status===x3dom.nodeTypes.Inline.AwaitTranscoding&&that.count<that.numRetries){that.count++;var refreshTime=+xhr.getResponseHeader("Refresh")||5;x3dom.debug.logInfo('Statuscode '+xhr.status+' and send new request in '+refreshTime+' sec.');window.setTimeout(function(){that._nameSpace.doc.downloadCount-=1;that.loadInline();},refreshTime*1000);return xhr;}
+else if((xhr.status!==200)&&(xhr.status!==0)){that.fireEvents("error");x3dom.debug.logError('XHR status: '+xhr.status+' - XMLHttpRequest requires web server running!');that._nameSpace.doc.downloadCount-=1;that.count=0;return xhr;}
+else if((xhr.status==200)||(xhr.status==0)){that.count=0;}
+x3dom.debug.logInfo('Inline: downloading '+that._vf.url[0]+' done.');var inlScene=null,newScene=null,nameSpace=null,xml=null;if(navigator.appName!="Microsoft Internet Explorer")
+xml=xhr.responseXML;else
+xml=new DOMParser().parseFromString(xhr.responseText,"text/xml");if(xml!==undefined&&xml!==null)
+{inlScene=xml.getElementsByTagName('Scene')[0]||xml.getElementsByTagName('scene')[0];}
+else{that.fireEvents("error");}
+if(inlScene)
+{var nsName=(that._vf.nameSpaceName.length!=0)?that._vf.nameSpaceName.toString().replace(' ',''):"";that._inlineNamespace=new x3dom.NodeNameSpace(nsName,that._nameSpace.doc);var url=that._vf.url.length?that._vf.url[0]:"";if((url[0]==='/')||(url.indexOf(":")>=0))
+{that._inlineNamespace.setBaseURL(url);}
+else
+{that._inlineNamespace.setBaseURL(that._nameSpace.baseURL+url);}
+that.replaceMaterials(inlScene);newScene=that._inlineNamespace.setupTree(inlScene);that._nameSpace.addSpace(that._inlineNamespace);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._xmlNode.appendChild(childDomNode);}});}}
+else{if(xml&&xml.localName){x3dom.debug.logError('No Scene in '+xml.localName);}else{x3dom.debug.logError('No Scene in resource');}}
+var global=x3dom.getGlobal();if(that._childNodes.length>0&&that._childNodes[0]&&that._childNodes[0]._nameSpace){that._nameSpace.removeSpace(that._childNodes[0]._nameSpace);}
+while(that._childNodes.length!==0){global['_remover']=that.removeChild(that._childNodes[0]);}
+delete global['_remover'];if(newScene)
+{that.addChild(newScene);that.invalidateVolume();that._nameSpace.doc.downloadCount-=1;that._nameSpace.doc.needRender=true;x3dom.debug.logInfo('Inline: added '+that._vf.url[0]+' to scene.');var theScene=that._nameSpace.doc._scene;if(theScene){theScene.invalidateVolume();window.setTimeout(function(){that.invalidateVolume();theScene.updateVolume();that._nameSpace.doc.needRender=true;},1000);}
+that.fireEvents("load");}
+newScene=null;inlScene=null;xml=null;return xhr;};if(this._vf.url.length&&this._vf.url[0].length)
+{var xhrURI=this._nameSpace.getURL(this._vf.url[0]);if(!(xhrURI.substr(0,5)==="blob:"))
+{xhrURI=encodeURI(xhrURI);}
+xhr.open('GET',xhrURI,true);this._nameSpace.doc.downloadCount+=1;try{xhr.send(null);}
+catch(ex){this.fireEvents("error");x3dom.debug.logError(this._vf.url[0]+": "+ex);}}}}));x3dom.registerNodeType("X3DBackgroundNode","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DBackgroundNode.superClass.call(this,ctx);var trans=(ctx&&ctx.autoGen)?1:0;this.addField_SFBool(ctx,'withCredentials',false);this.addField_MFColor(ctx,'groundColor',[]);this.addField_MFFloat(ctx,'groundAngle',[]);this.addField_MFColor(ctx,'skyColor',[new x3dom.fields.SFColor(0,0,0)]);this.addField_MFFloat(ctx,'skyAngle',[]);this.addField_SFFloat(ctx,'transparency',trans);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);this.addField_SFColor(ctx,'color',1,1,1);this.addField_SFString(ctx,'fogType',"LINEAR");this.addField_SFFloat(ctx,'visibilityRange',0);},{}));x3dom.registerNodeType("Fog","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DFogNode,function(ctx){x3dom.nodeTypes.Fog.superClass.call(this,ctx);},{}));x3dom.registerNodeType("Background","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBackgroundNode,function(ctx){x3dom.nodeTypes.Background.superClass.call(this,ctx);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||fieldName=="transparency"||fieldName.search("sky")>=0||fieldName.search("ground")>=0){this._dirty=true;}
+else if(fieldName.indexOf("bind")>=0){this.bind(this._vf.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("X3DEnvironmentNode","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DEnvironmentNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Environment","EnvironmentalEffects",defineClass(x3dom.nodeTypes.X3DEnvironmentNode,function(ctx){x3dom.nodeTypes.Environment.superClass.call(this,ctx);this.addField_SFBool(ctx,'sortTrans',true);this.addField_SFBool(ctx,'shadowExcludeTransparentObjects',false);this.addField_SFString(ctx,'gammaCorrectionDefault',"linear");this.addField_SFBool(ctx,'frustumCulling',true);this.addField_SFBool(ctx,'smallFeatureCulling',false);this.addField_SFFloat(ctx,'smallFeatureThreshold',1.0);this.addField_SFBool(ctx,'occlusionCulling',false);this.addField_SFFloat(ctx,'occlusionVisibilityThreshold',0.0);this.addField_SFBool(ctx,'lowPriorityCulling',false);this.addField_SFFloat(ctx,'lowPriorityThreshold',1.0);this.addField_SFBool(ctx,'tessellationDetailCulling',false);this.addField_SFFloat(ctx,'tessellationErrorThreshold',0.0);this.addField_SFBool(ctx,'enableARC',false);this.addField_SFFloat(ctx,'minFrameRate',1.0);this.addField_SFFloat(ctx,'maxFrameRate',62.5);this.addField_SFFloat(ctx,'userDataFactor',-1);this.addField_SFFloat(ctx,'smallFeatureFactor',-1);this.addField_SFFloat(ctx,'occlusionVisibilityFactor',-1);this.addField_SFFloat(ctx,'lowPriorityFactor',-1);this.addField_SFFloat(ctx,'tessellationErrorFactor',-1);this._validGammaCorrectionTypes=["none","fastlinear","linear"];this.checkSanity();},{checkSanity:function()
+{var checkParam=function(flag,value,defaultOn,defaultOff)
+{if(flag&&(value==defaultOff))
+return defaultOn;if(!flag&&(value!=defaultOff))
+return defaultOff;return value;};this._smallFeatureThreshold=checkParam(this._vf.smallFeatureCulling,this._vf.smallFeatureThreshold,10,0);this._lowPriorityThreshold=checkParam(this._vf.lowPriorityCulling,this._vf.lowPriorityThreshold,0.5,1);this._occlusionVisibilityThreshold=checkParam(this._vf.occlusionCulling,this._vf.occlusionVisibilityThreshold,1,0);this._tessellationErrorThreshold=checkParam(this._vf.tessellationDetailCulling,this._vf.tessellationErrorThreshold,1,0);var checkGamma=function(field,that){field=field.toLowerCase();if(that._validGammaCorrectionTypes.indexOf(field)>-1){return field;}
+else{x3dom.debug.logWarning(field+" gammaCorrectionDefault may only be linear (default), fastLinear, or none");return that._validGammaCorrectionTypes[0];}};this._vf.gammaCorrectionDefault=checkGamma(this._vf.gammaCorrectionDefault,this);}}));x3dom.registerNodeType("X3DViewpointNode","Navigation",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DViewpointNode.superClass.call(this,ctx);if(ctx&&ctx.xmlNode){var domNode=ctx.xmlNode;if(!domNode.resetView&&!domNode.getFieldOfView&&!domNode.getNear&&!domNode.getFar)
+{domNode.resetView=function(){var that=this._x3domNode;that.resetView();that._nameSpace.doc.needRender=true;};domNode.getFieldOfView=function(){return this._x3domNode.getFieldOfView();};domNode.getNear=function(){return this._x3domNode.getNear();};domNode.getFar=function(){return this._x3domNode.getFar();};}}},{activate:function(prev){var viewarea=this._nameSpace.doc._viewarea;if(prev){viewarea.animateTo(this,prev._autoGen?null:prev);}
+viewarea._needNavigationMatrixUpdate=true;x3dom.nodeTypes.X3DBindableNode.prototype.activate.call(this,prev);},deactivate:function(prev){x3dom.nodeTypes.X3DBindableNode.prototype.deactivate.call(this,prev);},getTransformation:function(){return this.getCurrentTransform();},getCenterOfRotation:function(){return new x3dom.fields.SFVec3f(0,0,0);},setCenterOfRotation:function(cor){this._vf.centerOfRotation.setValues(cor);},getFieldOfView:function(){return 1.57079633;},setView:function(newView){var mat=this.getCurrentTransform();this._viewMatrix=newView.mult(mat);},setViewAbsolute:function(newView)
+{this._viewMatrix=newView},setProjectionMatrix:function(matrix)
+{},resetView:function(){},getNear:function(){return 0.1;},getFar:function(){return 10000;},getImgPlaneHeightAtDistOne:function(){return 2.0;},getViewMatrix:function(){return null;},getProjectionMatrix:function(aspect){return null;}}));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',-1);this.addField_SFFloat(ctx,'zFar',-1);this._viewMatrix=x3dom.fields.SFMatrix4f.translation(this._vf.position).mult(this._vf.orientation.toMatrix()).inverse();this._projMatrix=null;this._lastAspect=1.0;this._zRatio=10000;this._zNear=this._vf.zNear;this._zFar=this._vf.zFar;this._imgPlaneHeightAtDistOne=2.0*Math.tan(this._vf.fieldOfView/2.0);},{fieldChanged:function(fieldName){if(fieldName=="position"||fieldName=="orientation"){this.resetView();}
+else if(fieldName=="fieldOfView"||fieldName=="zNear"||fieldName=="zFar"){this._projMatrix=null;this._zNear=this._vf.zNear;this._zFar=this._vf.zFar;this._imgPlaneHeightAtDistOne=2.0*Math.tan(this._vf.fieldOfView/2.0);}
+else if(fieldName.indexOf("bind")>=0){this.bind(this._vf.bind);}},setProjectionMatrix:function(matrix)
+{this._projMatrix=matrix;},getCenterOfRotation:function(){return this._vf.centerOfRotation;},getViewMatrix:function(){return this._viewMatrix;},getFieldOfView:function(){return this._vf.fieldOfView;},resetView:function(){this._viewMatrix=x3dom.fields.SFMatrix4f.translation(this._vf.position).mult(this._vf.orientation.toMatrix()).inverse();},getNear:function(){return this._zNear;},getFar:function(){return this._zFar;},getImgPlaneHeightAtDistOne:function(){return this._imgPlaneHeightAtDistOne;},getProjectionMatrix:function(aspect)
+{var fovy=this._vf.fieldOfView;var zfar=this._vf.zFar;var znear=this._vf.zNear;if(znear<=0||zfar<=0)
+{var nearScale=0.8,farScale=1.2;var viewarea=this._nameSpace.doc._viewarea;var scene=viewarea._scene;var min=x3dom.fields.SFVec3f.copy(scene._lastMin);var max=x3dom.fields.SFVec3f.copy(scene._lastMax);var dia=max.subtract(min);var sRad=dia.length()/2;var mat=viewarea.getViewMatrix().inverse();var vp=mat.e3();var translation=new x3dom.fields.SFVec3f(0,0,0),scaleFactor=new x3dom.fields.SFVec3f(1,1,1);var rotation=new x3dom.fields.Quaternion(0,0,1,0),scaleOrientation=new x3dom.fields.Quaternion(0,0,1,0);mat.getTransform(translation,rotation,scaleFactor,scaleOrientation);var minScal=scaleFactor.x,maxScal=scaleFactor.x;if(maxScal<scaleFactor.y)maxScal=scaleFactor.y;if(minScal>scaleFactor.y)minScal=scaleFactor.y;if(maxScal<scaleFactor.z)maxScal=scaleFactor.z;if(minScal>scaleFactor.z)minScal=scaleFactor.z;if(maxScal>1)
+nearScale/=maxScal;else if(minScal>x3dom.fields.Eps&&minScal<1)
+farScale/=minScal;var sCenter=min.add(dia.multiply(0.5));var vDist=(vp.subtract(sCenter)).length();if(sRad){if(vDist>sRad)
+znear=(vDist-sRad)*nearScale;else
+znear=0;zfar=(vDist+sRad)*farScale;}
+else{znear=0.1;zfar=100000;}
+var zNearLimit=zfar/this._zRatio;znear=Math.max(znear,Math.max(x3dom.fields.Eps,zNearLimit));if(zfar>this._vf.zNear&&this._vf.zNear>0)
+znear=this._vf.zNear;if(this._vf.zFar>znear)
+zfar=this._vf.zFar;if(zfar<=znear)
+zfar=znear+1;}
+if(this._projMatrix==null)
+{this._projMatrix=x3dom.fields.SFMatrix4f.perspective(fovy,aspect,znear,zfar);}
+else if(this._zNear!=znear||this._zFar!=zfar)
+{var div=znear-zfar;this._projMatrix._22=(znear+zfar)/div;this._projMatrix._23=2*znear*zfar/div;}
+else if(this._lastAspect!=aspect)
+{this._projMatrix._00=(1/Math.tan(fovy/2))/aspect;this._lastAspect=aspect;}
+this._zNear=znear;this._zFar=zfar;return this._projMatrix;}}));x3dom.registerNodeType("OrthoViewpoint","Navigation",defineClass(x3dom.nodeTypes.X3DViewpointNode,function(ctx){x3dom.nodeTypes.OrthoViewpoint.superClass.call(this,ctx);this.addField_MFFloat(ctx,'fieldOfView',[-1,-1,1,1]);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',10000);this._viewMatrix=null;this._projMatrix=null;this._lastAspect=1.0;this.resetView();},{fieldChanged:function(fieldName){if(fieldName=="position"||fieldName=="orientation"){this.resetView();}
+else if(fieldName=="fieldOfView"||fieldName=="zNear"||fieldName=="zFar"){this._projMatrix=null;this.resetView();}
+else if(fieldName.indexOf("bind")>=0){this.bind(this._vf.bind);}},getCenterOfRotation:function(){return this._vf.centerOfRotation;},getViewMatrix:function(){return this._viewMatrix;},resetView:function(){var offset=x3dom.fields.SFMatrix4f.translation(new x3dom.fields.SFVec3f((this._vf.fieldOfView[0]+this._vf.fieldOfView[2])/2,(this._vf.fieldOfView[1]+this._vf.fieldOfView[3])/2,0));this._viewMatrix=x3dom.fields.SFMatrix4f.translation(this._vf.position).mult(this._vf.orientation.toMatrix());this._viewMatrix=this._viewMatrix.mult(offset).inverse();},getNear:function(){return this._vf.zNear;},getFar:function(){return this._vf.zFar;},getProjectionMatrix:function(aspect)
+{if(this._projMatrix==null||this._lastAspect!=aspect)
+{var near=this.getNear();var far=this.getFar();var left=this._vf.fieldOfView[0];var bottom=this._vf.fieldOfView[1];var right=this._vf.fieldOfView[2];var top=this._vf.fieldOfView[3];this._projMatrix=x3dom.fields.SFMatrix4f.ortho(left,right,bottom,top,near,far,aspect);}
+this._lastAspect=aspect;return this._projMatrix;}}));x3dom.registerNodeType("Viewfrustum","Navigation",defineClass(x3dom.nodeTypes.X3DViewpointNode,function(ctx){x3dom.nodeTypes.Viewfrustum.superClass.call(this,ctx);this.addField_SFMatrix4f(ctx,'modelview',1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);this.addField_SFMatrix4f(ctx,'projection',1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);this._viewMatrix=this._vf.modelview.transpose().inverse();this._projMatrix=this._vf.projection.transpose();this._centerOfRotation=new x3dom.fields.SFVec3f(0,0,0);},{fieldChanged:function(fieldName){if(fieldName=="modelview"){this.resetView();}
+else if(fieldName=="projection"){this._projMatrix=this._vf.projection.transpose();}
+else if(fieldName.indexOf("bind")>=0){this.bind(this._vf.bind);}},getCenterOfRotation:function(){return this._centerOfRotation;},setCenterOfRotation:function(cor){this._centerOfRotation.setValues(cor);},getViewMatrix:function(){return this._viewMatrix;},getFieldOfView:function(){return(2.0*Math.atan(1.0/this._projMatrix._11));},getImgPlaneHeightAtDistOne:function(){return 2.0/this._projMatrix._11;},resetView:function(){this._viewMatrix=this._vf.modelview.transpose().inverse();this._centerOfRotation=new x3dom.fields.SFVec3f(0,0,0);},getProjectionMatrix:function(aspect){return this._projMatrix;}}));x3dom.registerNodeType("X3DNavigationInfoNode","Navigation",defineClass(x3dom.nodeTypes.X3DBindableNode,function(ctx){x3dom.nodeTypes.X3DNavigationInfoNode.superClass.call(this,ctx);}));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,'typeParams',[-0.4,60,0.05,2.8]);this.addField_SFString(ctx,'explorationMode','all');this.addField_MFFloat(ctx,'avatarSize',[0.25,1.6,0.75]);this.addField_SFFloat(ctx,'visibilityLimit',0.0);this.addField_SFFloat(ctx,'speed',1.0);this.addField_SFTime(ctx,'transitionTime',1.0);this.addField_MFString(ctx,'transitionType',["LINEAR"]);this._validTypes=["none","examine","turntable","fly","freefly","lookat","lookaround","walk","game","helicopter","any"];this._heliUpdated=false;var type=this.checkType(this.getType());x3dom.debug.logInfo("NavType: "+type);},{fieldChanged:function(fieldName){if(fieldName=="typeParams"){this._heliUpdated=false;}
+else if(fieldName=="type"){var type=this.checkType(this.getType());switch(type){case'game':this._nameSpace.doc._viewarea.initMouseState();break;case'helicopter':this._heliUpdated=false;break;case"turntable":this._nameSpace.doc._viewarea.initMouseState();this._nameSpace.doc._viewarea.initTurnTable(this);break;default:break;}
+this._vf.type[0]=type;x3dom.debug.logInfo("Switch to "+type+" mode.");}},setType:function(type,viewarea){var navType=this.checkType(type.toLowerCase());var oldType=this.checkType(this.getType());switch(navType){case'game':if(oldType!==navType){if(viewarea)
+viewarea.initMouseState();else
+this._nameSpace.doc._viewarea.initMouseState();}
+break;case'helicopter':if(oldType!==navType){this._heliUpdated=false;}
+break;case"turntable":if(oldType!==navType){if(viewarea){viewarea.initMouseState();viewarea.initTurnTable(this);}
+else{this._nameSpace.doc._viewarea.initMouseState();this._nameSpace.doc._viewarea.initTurnTable(this);}}
+break;default:break;}
+this._vf.type[0]=navType;x3dom.debug.logInfo("Switch to "+navType+" mode.");},getType:function(){var type=this._vf.type[0].toLowerCase();if(type.length<=1)
+type="none";else if(type=="any")
+type="examine";return type;},getTypeParams:function(){var length=this._vf.typeParams.length;var theta=(length>=1)?this._vf.typeParams[0]:-0.4;var height=(length>=2)?this._vf.typeParams[1]:60.0;var minAngle=(length>=3)?this._vf.typeParams[2]:x3dom.fields.Eps;var maxAngle=(length>=4)?this._vf.typeParams[3]:Math.PI-x3dom.fields.Eps;var params=[theta,height,minAngle,maxAngle];if(length>=5)
+{params.push(this._vf.typeParams[4]);}
+return params;},setTypeParams:function(params){for(var i=0;i<params.length;i++){this._vf.typeParams[i]=params[i];}},checkType:function(type){if(this._validTypes.indexOf(type)>-1){return type;}
+else{x3dom.debug.logWarning(type+" is no valid navigation type, use one of "+
+this._validTypes.toString());return"examine";}},getExplorationMode:function(){switch(this._vf.explorationMode.toLowerCase()){case"all":return 7;case"rotate":return 1;case"zoom":return 2;case"pan":return 4;case"none":return 0;default:return 7;}}}));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);},{collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+singlePath=false;var vol=this.getVolume();var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();vol.getBounds(min,max);var mat_view=drawableCollection.viewMatrix;var center=new x3dom.fields.SFVec3f(0,0,0);center=mat_view.inverse().multMatrixPnt(center);var mat_view_model=mat_view.mult(transform);this._eye=transform.inverse().multMatrixPnt(center);this._eyeViewUp=new x3dom.fields.SFVec3f(mat_view_model._10,mat_view_model._11,mat_view_model._12);this._eyeLook=new x3dom.fields.SFVec3f(mat_view_model._20,mat_view_model._21,mat_view_model._22);var rotMat=x3dom.fields.SFMatrix4f.identity();var mid=max.add(min).multiply(0.5);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).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));}
+var childTransform=this.transformMatrix(transform.mult(rotMat));for(var i=0,i_n=this._childNodes.length;i<i_n;i++)
+{var cnode=this._childNodes[i];if(cnode){cnode.collectDrawableObjects(childTransform,drawableCollection,singlePath,invalidateCache,planeMask);}}}}));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);this.addField_SFTime("collideTime",0);this.addField_SFBool("isActive",true);},{collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+var cnode,childTransform;if(singlePath){if(!this._graph.globalMatrix){this._graph.globalMatrix=this.transformMatrix(transform);}
+childTransform=this._graph.globalMatrix;}
+else{childTransform=this.transformMatrix(transform);}
+for(var i=0,n=this._childNodes.length;i<n;i++)
+{if((cnode=this._childNodes[i])&&(cnode!==this._cf.proxy.node)){cnode.collectDrawableObjects(childTransform,drawableCollection,singlePath,invalidateCache,planeMask);}}}}));x3dom.registerNodeType("X3DLODNode","Navigation",defineClass(x3dom.nodeTypes.X3DGroupingNode,function(ctx){x3dom.nodeTypes.X3DLODNode.superClass.call(this,ctx);this.addField_SFBool(ctx,"forceTransitions",false);this.addField_SFVec3f(ctx,"center",0,0,0);this._eye=new x3dom.fields.SFVec3f(0,0,0);},{collectDrawableObjects:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{if(singlePath&&(this._parentNodes.length>1))
+singlePath=false;if(singlePath&&(invalidateCache=invalidateCache||this.cacheInvalid()))
+this.invalidateCache();planeMask=drawableCollection.cull(transform,this.graphState(),singlePath,planeMask);if(planeMask<=0){return;}
+singlePath=false;this.visitChildren(transform,drawableCollection,singlePath,invalidateCache,planeMask);},visitChildren:function(transform,drawableCollection,singlePath,invalidateCache,planeMask){}}));x3dom.registerNodeType("LOD","Navigation",defineClass(x3dom.nodeTypes.X3DLODNode,function(ctx){x3dom.nodeTypes.LOD.superClass.call(this,ctx);this.addField_MFFloat(ctx,"range",[]);this._lastRangePos=-1;},{visitChildren:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{var i=0,n=this._childNodes.length;var vol=this.getVolume();var min=x3dom.fields.SFVec3f.MAX();var max=x3dom.fields.SFVec3f.MIN();vol.getBounds(min,max);var mat_view=drawableCollection.viewMatrix;var center=new x3dom.fields.SFVec3f(0,0,0);center=mat_view.inverse().multMatrixPnt(center);this._eye=transform.inverse().multMatrixPnt(center);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;}
+this._lastRangePos=i;var cnode=this._childNodes[i];if(n&&cnode)
+{var childTransform=this.transformMatrix(transform);cnode.collectDrawableObjects(childTransform,drawableCollection,singlePath,invalidateCache,planeMask);}},getVolume:function()
+{var vol=this._graph.volume;if(!this.volumeValid()&&this._vf.render)
+{var child,childVol;if(this._lastRangePos>=0){child=this._childNodes[this._lastRangePos];childVol=(child&&child._vf.render===true)?child.getVolume():null;if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}
+else{for(var i=0,n=this._childNodes.length;i<n;i++)
+{if(!(child=this._childNodes[i])||child._vf.render!==true)
+continue;childVol=child.getVolume();if(childVol&&childVol.isValid())
+vol.extendBounds(childVol.min,childVol.max);}}}
+return vol;},nodeChanged:function(){this.invalidateVolume();},fieldChanged:function(fieldName){if(fieldName=="render"||fieldName=="center"||fieldName=="range"){this.invalidateVolume();}}}));x3dom.registerNodeType("DynamicLOD","Navigation",defineClass(x3dom.nodeTypes.X3DLODNode,function(ctx){x3dom.nodeTypes.DynamicLOD.superClass.call(this,ctx);this.addField_SFFloat(ctx,'subScale',0.5);this.addField_SFVec2f(ctx,'size',2,2);this.addField_SFVec2f(ctx,'subdivision',1,1);this.addField_SFNode('root',x3dom.nodeTypes.X3DShapeNode);this.addField_SFString(ctx,'urlHead',"http://r");this.addField_SFString(ctx,'urlCenter',".ortho.tiles.virtualearth.net/tiles/h");this.addField_SFString(ctx,'urlTail',".png?g=-1");this.rootGeometry=new x3dom.nodeTypes.Plane(ctx);this.level=0;this.quadrant=4;this.cell="";},{nodeChanged:function()
+{var root=this._cf.root.node;if(root==null||root._cf.geometry.node!=null)
+return;this.rootGeometry._vf.size.setValues(this._vf.size);this.rootGeometry._vf.subdivision.setValues(this._vf.subdivision);this.rootGeometry._vf.center.setValues(this._vf.center);this.rootGeometry.fieldChanged("subdivision");this._cf.root.node.addChild(this.rootGeometry);this.rootGeometry.nodeChanged();this._cf.root.node.nodeChanged();this._nameSpace.doc.needRender=true;},visitChildren:function(transform,drawableCollection,singlePath,invalidateCache,planeMask)
+{var root=this._cf.root.node;if(root==null)
+return;var mat_view=drawableCollection.viewMatrix;var center=new x3dom.fields.SFVec3f(0,0,0);center=mat_view.inverse().multMatrixPnt(center);this._eye=transform.inverse().multMatrixPnt(center);var l,len=this._vf.center.subtract(this._eye).length();if(len>x3dom.fields.Eps&&len*this._vf.subScale<=this._vf.size.length()){if(this._childNodes.length<=1){var offset=new Array(new x3dom.fields.SFVec3f(-0.25*this._vf.size.x,0.25*this._vf.size.y,0),new x3dom.fields.SFVec3f(0.25*this._vf.size.x,0.25*this._vf.size.y,0),new x3dom.fields.SFVec3f(-0.25*this._vf.size.x,-0.25*this._vf.size.y,0),new x3dom.fields.SFVec3f(0.25*this._vf.size.x,-0.25*this._vf.size.y,0));for(l=0;l<4;l++){var node=new x3dom.nodeTypes.DynamicLOD();node._nameSpace=this._nameSpace;node._eye.setValues(this._eye);node.level=this.level+1;node.quadrant=l;node.cell=this.cell+l;node._vf.urlHead=this._vf.urlHead;node._vf.urlCenter=this._vf.urlCenter;node._vf.urlTail=this._vf.urlTail;node._vf.center=this._vf.center.add(offset[l]);node._vf.size=this._vf.size.multiply(0.5);node._vf.subdivision.setValues(this._vf.subdivision);var app=new x3dom.nodeTypes.Appearance();var tex=new x3dom.nodeTypes.ImageTexture();tex._nameSpace=this._nameSpace;tex._vf.url[0]=this._vf.urlHead+node.quadrant+this._vf.urlCenter+node.cell+this._vf.urlTail;app.addChild(tex);tex.nodeChanged();var shape=new x3dom.nodeTypes.Shape();shape._nameSpace=this._nameSpace;shape.addChild(app);app.nodeChanged();node.addChild(shape,"root");shape.nodeChanged();this.addChild(node);node.nodeChanged();}}
+else{for(l=1;l<this._childNodes.length;l++){this._childNodes[l].collectDrawableObjects(transform,drawableCollection,singlePath,invalidateCache,planeMask);}}}
+else{root.collectDrawableObjects(transform,drawableCollection,singlePath,invalidateCache,planeMask);}},getVolume:function(){var vol=this._graph.volume;if(!vol.isValid()){vol.min.setValues(this._vf.center);vol.min.x-=0.5*this._vf.size.x;vol.min.y-=0.5*this._vf.size.y;vol.min.z-=x3dom.fields.Eps;vol.max.setValues(this._vf.center);vol.max.x+=0.5*this._vf.size.x;vol.max.y+=0.5*this._vf.size.y;vol.max.z+=x3dom.fields.Eps;}
+return vol;}}));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);},{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("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);this._mesh._positions[0]=[];this._mesh._normals[0]=[0,0,1,0,0,1,0,0,1,0,0,1];this._mesh._texCoords[0]=[0,0,1,0,1,1,0,1];this._mesh._colors[0]=[];this._mesh._indices[0]=[0,1,2,2,3,0];this._mesh._invalidate=true;this._mesh._numFaces=2;this._mesh._numCoords=4;},{nodeChanged:function(){if(!this._cf.fontStyle.node){this.addChild(x3dom.nodeTypes.FontStyle.defaultNode());}
+this.invalidateVolume();},fieldChanged:function(fieldName){if(fieldName=='string'||fieldName=='length'||fieldName=='maxExtent'){this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node.setAllDirty();});}}}));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...");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.debug.logException(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._preventAutoPlay=true;this._audio=null;},{nodeChanged:function()
+{this._audio=document.createElement('audio');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()
+{if(that._vf.enabled===true)
+{that._audio.play();}};var audioDone=function()
+{if(that._vf.enabled===true&&that._vf.loop===true)
+{that._audio.play();}};var preventAutoPlay=function()
+{if(that._preventAutoPlay)
+{that._audio.pause();that._preventAutoPlay=false;}};this._audio.addEventListener("canplaythrough",startAudio,true);this._audio.addEventListener("ended",audioDone,true);this._audio.addEventListener("play",preventAutoPlay,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.enabled===true&&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);}}},shutdown:function(){if(this._audio){this._audio.pause();while(this._audio.hasChildNodes()){this._audio.removeChild(this._audio.firstChild);}
+document.body.removeChild(this._audio);this._audio=null;}}}));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){if(fieldName=='center'||fieldName=='rotation'||fieldName=='scale'||fieldName=='translation'){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);},{fieldChanged:function(fieldName)
+{if(this._vf.hasOwnProperty(fieldName)){Array.forEach(this._parentNodes,function(texture){Array.forEach(texture._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.texture=true;});});});this._nameSpace.doc.needRender=true;}}}));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_SFBool(ctx,'scale',true);this.addField_SFBool(ctx,'withCredentials',false);this.addField_SFNode('textureProperties',x3dom.nodeTypes.TextureProperties);this._needPerFrameUpdate=false;this._isCanvas=false;this._type="diffuseMap";this._blending=(this._vf.origChannelCount==1||this._vf.origChannelCount==2);},{invalidateGLObject:function()
+{Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){if(x3dom.isa(shape,x3dom.nodeTypes.X3DShapeNode)){shape._dirty.texture=true;}
+else{Array.forEach(shape._parentNodes,function(realShape){if(x3dom.isa(realShape,x3dom.nodeTypes.X3DShapeNode)){realShape._dirty.texture=true;}else{Array.forEach(realShape._parentNodes,function(realShape2){if(x3dom.isa(realShape2,x3dom.nodeTypes.X3DShapeNode)){realShape2._dirty.texture=true;}});}});}});});this._nameSpace.doc.needRender=true;},parentAdded:function(parent)
+{Array.forEach(parent._parentNodes,function(shape){if(x3dom.isa(shape,x3dom.nodeTypes.Shape)){shape._dirty.texture=true;}
+else{Array.forEach(shape._parentNodes,function(realShape){realShape._dirty.texture=true;});}});},parentRemoved:function(parent)
+{Array.forEach(parent._parentNodes,function(shape){if(x3dom.isa(shape,x3dom.nodeTypes.Shape)){shape._dirty.texture=true;}
+else{Array.forEach(shape._parentNodes,function(realShape){realShape._dirty.texture=true;});}});},fieldChanged:function(fieldName)
+{if(fieldName=="url"||fieldName=="origChannelCount"||fieldName=="repeatS"||fieldName=="repeatT"||fieldName=="scale"||fieldName=="withCredentials")
+{var that=this;Array.forEach(this._parentNodes,function(app){if(x3dom.isa(app,x3dom.nodeTypes.X3DAppearanceNode)){app.nodeChanged();Array.forEach(app._parentNodes,function(shape){shape._dirty.texture=true;});}
+else if(x3dom.isa(app,x3dom.nodeTypes.ImageGeometry)){var cf=null;if(that._xmlNode&&that._xmlNode.hasAttribute('containerField')){cf=that._xmlNode.getAttribute('containerField');app._dirty[cf]=true;}}
+else if(x3dom.nodeTypes.X3DVolumeDataNode!==undefined){if(x3dom.isa(app,x3dom.nodeTypes.X3DVolumeRenderStyleNode)){if(that._xmlNode&&that._xmlNode.hasAttribute('containerField')){Array.forEach(app._parentNodes,function(shape){shape._dirty.texture=true;});}}else if(x3dom.isa(app,x3dom.nodeTypes.X3DVolumeDataNode)){if(that._xmlNode&&that._xmlNode.hasAttribute('containerField')){app._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;},getTextures:function(){return this._cf.texture.nodes;},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.toLowerCase()==="video"){that._needPerFrameUpdate=true;that._video=document.createElement('video');that._video.setAttribute('preload','auto');that._video.setAttribute('muted','muted');var p=document.getElementsByTagName('body')[0];p.appendChild(that._video);that._video.style.display="none";that._video.style.visibility="hidden";}}
+else if(childDomNode.localName.toLowerCase()==="canvas"){that._needPerFrameUpdate=true;that._isCanvas=true;that._canvas=childDomNode;}
+if(childDomNode.style&&that._vf.hideChildren){childDomNode.style.display="none";childDomNode.style.visibility="hidden";}
+x3dom.debug.logInfo("### Found &lt;"+childDomNode.nodeName+"&gt; tag.");}});}
+catch(e){x3dom.debug.logException(e);}},shutdown:function(){if(this._video){this._video.pause();while(this._video.hasChildNodes()){this._video.removeChild(this._video.firstChild);}
+document.body.removeChild(this._video);this._video=null;}}}));x3dom.registerNodeType("RenderedTexture","Texturing",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.RenderedTexture.superClass.call(this,ctx);if(ctx)
+ctx.doc._nodeBag.renderTextures.push(this);else
+x3dom.debug.logWarning("RenderedTexture: No runtime context found!");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');this.addField_SFBool(ctx,'showNormals',false);this.addField_SFString(ctx,'stereoMode','NONE');this.addField_SFFloat(ctx,'interpupillaryDistance',0.064);this.hScreenSize=0.14976;this.vScreenSize=0.09356;this.vScreenCenter=this.vScreenSize/2;this.eyeToScreenDistance=0.041;this.lensSeparationDistance=0.0635;this.distortionK=[1.0,0.22,0.24,0.0];this.lensCenter=1-2*this.lensSeparationDistance/this.hScreenSize;x3dom.debug.assert(this._vf.dimensions.length>=3,"RenderedTexture.dimensions requires at least 3 entries.");this._clearParents=true;this._needRenderUpdate=true;},{nodeChanged:function()
+{this._clearParents=true;this._needRenderUpdate=true;},fieldChanged:function(fieldName)
+{switch(fieldName)
+{case"excludeNodes":this._clearParents=true;break;case"update":if(this._vf.update.toUpperCase()=="NEXT_FRAME_ONLY"||this._vf.update.toUpperCase()=="ALWAYS"){this._needRenderUpdate=true;}
+break;default:break;}},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 locScene=this._cf.scene.node;var scene=this._nameSpace.doc._scene;var vbP=scene.getViewpoint();var view=this._cf.viewpoint.node;var ret_mat=null;if(view===null||view===vbP){ret_mat=this._nameSpace.doc._viewarea.getViewMatrix();}
+else if(locScene&&locScene!==scene){ret_mat=view.getViewMatrix()}
+else{var mat_viewpoint=view.getCurrentTransform();ret_mat=view.getViewMatrix().mult(mat_viewpoint.inverse());}
+var stereoMode=this._vf.stereoMode.toUpperCase();if(stereoMode!="NONE"){var d=this._vf.interpupillaryDistance/2;if(stereoMode=="RIGHT_EYE"){d=-d;}
+var modifier=new x3dom.fields.SFMatrix4f(1,0,0,d,0,1,0,0,0,0,1,0,0,0,0,1);ret_mat=modifier.mult(ret_mat);}
+return ret_mat;},getProjectionMatrix:function()
+{var doc=this._nameSpace.doc;var vbP=doc._scene.getViewpoint();var view=this._cf.viewpoint.node;var ret_mat=null;var f,w=this._vf.dimensions[0],h=this._vf.dimensions[1];var stereoMode=this._vf.stereoMode.toUpperCase();var stereo=(stereoMode!="NONE");if(view===null||view===vbP){ret_mat=x3dom.fields.SFMatrix4f.copy(doc._viewarea.getProjectionMatrix());if(stereo){f=2*Math.atan(this.vScreenSize/(2*this.eyeToScreenDistance));f=1/Math.tan(f/2);}
+else{f=1/Math.tan(vbP._vf.fieldOfView/2);}
+ret_mat._00=f/(w/h);ret_mat._11=f;}
+else{ret_mat=view.getProjectionMatrix(w/h);}
+if(stereo){var hp=this.lensCenter;if(stereoMode=="RIGHT_EYE"){hp=-hp;}
+var modifier=new x3dom.fields.SFMatrix4f(1,0,0,hp,0,1,0,0,0,0,1,0,0,0,0,1);ret_mat=modifier.mult(ret_mat);}
+return ret_mat;},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);}},requirePingPong:function()
+{return false;}}));x3dom.registerNodeType("RefinementTexture","Texturing",defineClass(x3dom.nodeTypes.RenderedTexture,function(ctx){x3dom.nodeTypes.RefinementTexture.superClass.call(this,ctx);this.addField_SFString(ctx,'stamp0',"gpuii/stamps/0.gif");this.addField_SFString(ctx,'stamp1',"gpuii/stamps/1.gif");this.addField_SFBool(ctx,'autoRefinement',true);this.addField_SFString(ctx,'format','jpg');this.addField_SFInt32(ctx,'iterations',7);this.addField_SFInt32(ctx,'maxLevel',this._vf.iterations);if(this._vf.iterations%2===0){var temp=this._vf.stamp0;this._vf.stamp0=this._vf.stamp1;this._vf.stamp1=temp;}
+this._vf.iterations=(this._vf.iterations>11)?11:this._vf.iterations;this._vf.iterations=(this._vf.iterations<3)?3:this._vf.iterations;this._vf.maxLevel=(this._vf.maxLevel>11)?11:this._vf.maxLevel;this._vf.maxLevel=(this._vf.maxLevel<3)?3:this._vf.maxLevel;this._vf.maxLevel=(this._vf.maxLevel>this._vf.iterations)?this._vf.iterations:this._vf.maxLevel;var repeatConfig=[{x:4,y:8},{x:8,y:8},{x:8,y:16},{x:16,y:16},{x:16,y:32},{x:32,y:32},{x:32,y:64},{x:64,y:64},{x:64,y:128}];this._repeat=new x3dom.fields.SFVec2f(this._vf.dimensions[0]/repeatConfig[this._vf.iterations-3].x,this._vf.dimensions[1]/repeatConfig[this._vf.iterations-3].y);this._renderedImage=0;this._currLoadLevel=0;this._loadLevel=1;},{nextLevel:function(){if(this._loadLevel<this._vf.maxLevel){this._loadLevel++;this._nameSpace.doc.needRender=true;}},requirePingPong:function(){return(this._currLoadLevel<=this._vf.maxLevel&&this._renderedImage<this._loadLevel);}}));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();}},getWidth:function(){return this._vf.image.width;},getHeight:function(){return this._vf.image.height;},getComponents:function(){return this._vf.image.comp;},setPixel:function(x,y,color){this._vf.image.setPixel(x,y,color);this.invalidateGLObject();},getPixel:function(x,y){return this._vf.image.getPixel(x,y);},setPixels:function(pixels){this._vf.image.setPixels(pixels);this.invalidateGLObject();},getPixels:function(){return this._vf.image.getPixels();}}));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);this.addField_SFTime(ctx,'pauseTime',0);this.addField_SFFloat(ctx,'pitch',1.0);this.addField_SFTime(ctx,'resumeTime',0);this.addField_SFTime(ctx,'startTime',0);this.addField_SFTime(ctx,'stopTime',0);}));x3dom.registerNodeType("X3DTextureCoordinateNode","Texturing",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.X3DTextureCoordinateNode.superClass.call(this,ctx);},{fieldChanged:function(fieldName){if(fieldName==="texCoord"||fieldName==="point"||fieldName==="parameter"||fieldName==="mode")
+{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("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("MultiTextureCoordinate","Texturing",defineClass(x3dom.nodeTypes.X3DTextureCoordinateNode,function(ctx){x3dom.nodeTypes.MultiTextureCoordinate.superClass.call(this,ctx);this.addField_MFNode('texCoord',x3dom.nodeTypes.X3DTextureCoordinateNode);}));x3dom.registerNodeType("ImageTextureAtlas","Texturing",defineClass(x3dom.nodeTypes.Texture,function(ctx){x3dom.nodeTypes.ImageTextureAtlas.superClass.call(this,ctx);this.addField_SFInt32(ctx,'numberOfSlices',0);this.addField_SFInt32(ctx,'slicesOverX',0);this.addField_SFInt32(ctx,'slicesOverY',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);this._type="cubeMap";},{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');this._type="cubeMap";x3dom.debug.logWarning("GeneratedCubeMapTexture NYI");},{getTexSize:function(){return this._vf.size;}}));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);}));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_SFString(ctx,'displacementAxis','y');this.addField_SFFloat(ctx,'displacementFactor',255.0);this.addField_SFInt32(ctx,'displacementTextureId',-1);this.addField_SFInt32(ctx,'displacementTextureCoordinatesId',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_SFNode('displacementTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('diffuseDisplacementTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('multiDiffuseAlphaTexture',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('multiVisibilityTexture',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={};},{getDiffuseMap:function()
+{if(this._cf.diffuseTexture.node){if(x3dom.isa(this._cf.diffuseTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.diffuseTexture.node._cf.texture.node._type="diffuseMap";return this._cf.diffuseTexture.node._cf.texture.node;}else{this._cf.diffuseTexture.node._type="diffuseMap";return this._cf.diffuseTexture.node;}}else{return null;}},getNormalMap:function()
+{if(this._cf.normalTexture.node){if(x3dom.isa(this._cf.normalTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.normalTexture.node._cf.texture.node._type="normalMap";return this._cf.normalTexture.node._cf.texture.node;}else{this._cf.normalTexture.node._type="normalMap";return this._cf.normalTexture.node;}}else{return null;}},getAmbientMap:function()
+{if(this._cf.ambientTexture.node){if(x3dom.isa(this._cf.ambientTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.ambientTexture.node._cf.texture.node._type="ambientMap";return this._cf.ambientTexture.node._cf.texture.node;}else{this._cf.ambientTexture.node._type="ambientMap";return this._cf.ambientTexture.node;}}else{return null;}},getSpecularMap:function()
+{if(this._cf.specularTexture.node){if(x3dom.isa(this._cf.specularTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.specularTexture.node._cf.texture.node._type="specularMap";return this._cf.specularTexture.node._cf.texture.node;}else{this._cf.specularTexture.node._type="specularMap";return this._cf.specularTexture.node;}}else{return null;}},getShininessMap:function()
+{if(this._cf.shininessTexture.node){if(x3dom.isa(this._cf.shininessTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.shininessTexture.node._cf.texture.node._type="shininessMap";return this._cf.shininessTexture.node._cf.texture.node;}else{this._cf.shininessTexture.node._type="shininessMap";return this._cf.shininessTexture.node;}}else{return null;}},getAlphaMap:function()
+{if(this._cf.alphaTexture.node){if(x3dom.isa(this._cf.alphaTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.alphaTexture.node._cf.texture.node._type="alphaMap";return this._cf.alphaTexture.node._cf.texture.node;}else{this._cf.alphaTexture.node._type="alphaMap";return this._cf.alphaTexture.node;}}else{return null;}},getDisplacementMap:function()
+{if(this._cf.displacementTexture.node){if(x3dom.isa(this._cf.displacementTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.displacementTexture.node._cf.texture.node._type="displacementMap";return this._cf.displacementTexture.node._cf.texture.node;}else{this._cf.displacementTexture.node._type="displacementMap";return this._cf.displacementTexture.node;}}else{return null;}},getDiffuseDisplacementMap:function()
+{if(this._cf.diffuseDisplacementTexture.node){if(x3dom.isa(this._cf.diffuseDisplacementTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.diffuseDisplacementTexture.node._cf.texture.node._type="diffuseDisplacementMap";return this._cf.diffuseDisplacementTexture.node._cf.texture.node;}else{this._cf.diffuseDisplacementTexture.node._type="diffuseDisplacementMap";return this._cf.diffuseDisplacementTexture.node;}}else{return null;}},getMultiDiffuseAlphaMap:function()
+{if(this._cf.multiDiffuseAlphaTexture.node){if(x3dom.isa(this._cf.multiDiffuseAlphaTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.multiDiffuseAlphaTexture.node._cf.texture.node._type="multiDiffuseAlphaMap";return this._cf.multiDiffuseAlphaTexture.node._cf.texture.node;}else{this._cf.multiDiffuseAlphaTexture.node._type="multiDiffuseAlphaMap";return this._cf.multiDiffuseAlphaTexture.node;}}else{return null;}},getMultiVisibilityMap:function()
+{if(this._cf.multiVisibilityTexture.node){if(x3dom.isa(this._cf.multiVisibilityTexture.node,x3dom.nodeTypes.SurfaceShaderTexture)){this._cf.multiVisibilityTexture.node._cf.texture.node._type="multiVisibilityMap";return this._cf.multiVisibilityTexture.node._cf.texture.node;}else{this._cf.multiVisibilityTexture.node._type="multiVisibilityMap";return this._cf.multiVisibilityTexture.node;}}else{return null;}},getTextures:function()
+{var textures=[];var diff=this.getDiffuseMap();if(diff)textures.push(diff);var norm=this.getNormalMap();if(norm)textures.push(norm);var spec=this.getSpecularMap();if(spec)textures.push(spec);var shin=this.getShininessMap();if(shin)textures.push(shin);var displacement=this.getDisplacementMap();if(displacement)textures.push(displacement);var diffuseDisplacement=this.getDiffuseDisplacementMap();if(diffuseDisplacement)textures.push(diffuseDisplacement);var multiDiffuseAlpha=this.getMultiDiffuseAlphaMap();if(multiDiffuseAlpha)textures.push(multiDiffuseAlpha);var multiVisibility=this.getMultiVisibilityMap();if(multiVisibility)textures.push(multiVisibility);return textures;}}));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;this._id=null;if(!x3dom.nodeTypes.ComposedShader.ShaderInfoMsgShown){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"+"(see also <a href='http://x3dom.org/x3dom/doc/help/composedShader.html'>"+"http://x3dom.org/x3dom/doc/help/composedShader.html</a>)\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");x3dom.nodeTypes.ComposedShader.ShaderInfoMsgShown=true;}},{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];this._id=this._cf.parts.nodes[i]._id;}
+else if(this._cf.parts.nodes[i]._vf.type.toLowerCase()=='fragment'){this._fragment=this._cf.parts.nodes[i];this._id+=" - "+this._cf.parts.nodes[i]._id;}}
+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;var needNode=false;if(ctx.xmlNode===undefined||ctx.xmlNode===null){ctx.xmlNode=document.createElement("field");needNode=true;}
+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);if(needNode){ctx.xmlNode=null;}}
+Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){if(shape._cleanupGLObjects)
+shape._cleanupGLObjects();shape.setAllDirty();});});},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;}}
+if(field==='url')
+{Array.forEach(this._parentNodes,function(app){Array.forEach(app._parentNodes,function(shape){shape._dirty.shader=true;});});}},parentAdded:function(parent)
+{parent.nodeChanged();}}));x3dom.nodeTypes.ComposedShader.ShaderInfoMsgShown=false;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");this._id=(ctx&&ctx.xmlNode&&ctx.xmlNode.id!="")?ctx.xmlNode.id:++x3dom.nodeTypes.Shape.shaderPartID;x3dom.debug.assert(this._vf.type.toLowerCase()=='vertex'||this._vf.type.toLowerCase()=='fragment');},{nodeChanged:function()
+{var ctx={};ctx.xmlNode=this._xmlNode;if(ctx.xmlNode!==undefined&&ctx.xmlNode!==null)
+{var that=this;if(that._vf.url.length&&that._vf.url[0].indexOf('\n')==-1)
+{var xhr=new XMLHttpRequest();xhr.open("GET",encodeURI(that._nameSpace.getURL(that._vf.url[0])),false);xhr.onload=function(){that._vf.url=new x3dom.fields.MFString([]);that._vf.url.push(xhr.response);};xhr.onerror=function(){x3dom.debug.logError("Could not load file '"+that._vf.url[0]+"'.");};xhr.send(null);}
+else
+{if(that._vf.url.length){that._vf.url=new x3dom.fields.MFString([]);}
+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===3){that._vf.url.push(childDomNode.nodeValue);}
+else if(childDomNode.nodeType===4){that._vf.url.push(childDomNode.data);}
+childDomNode.parentNode.removeChild(childDomNode);});}}}
+Array.forEach(this._parentNodes,function(shader){shader.nodeChanged();});},fieldChanged:function(fieldName)
+{if(fieldName==="url"){Array.forEach(this._parentNodes,function(shader){shader.fieldChanged("url");});}},parentAdded:function(parent)
+{parent.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',[]);}));x3dom.registerNodeType("X3DSpatialGeometryNode","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometryNode,function(ctx){x3dom.nodeTypes.X3DSpatialGeometryNode.superClass.call(this,ctx);}));x3dom.registerNodeType("Plane","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.Plane.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'size',2,2);this.addField_SFVec2f(ctx,'subdivision',1,1);this.addField_SFVec3f(ctx,'center',0,0,0);this.addField_MFString(ctx,'primType',['TRIANGLES']);if(this._vf.primType.length)
+this._mesh._primType=this._vf.primType[0];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+'-'+
+this._vf.center.x+'-'+this._vf.center.y+'-'+this._vf.center.z;if(ctx&&this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined){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(this._vf.center.x+x*xstep-sx);this._mesh._positions[0].push(this._vf.center.y+y*ystep-sy);this._mesh._positions[0].push(this._vf.center.z);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;}},{fieldChanged:function(fieldName){if(fieldName=="size"||fieldName=="center"){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(this._vf.center.x+x*xstep-sx);this._mesh._positions[0].push(this._vf.center.y+y*ystep-sy);this._mesh._positions[0].push(this._vf.center.z);}}
+this.invalidateVolume();this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+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(this._vf.center.x+x*xstep-sx);this._mesh._positions[0].push(this._vf.center.y+y*ystep-sy);this._mesh._positions[0].push(this._vf.center.z);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.invalidateVolume();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();node.invalidateVolume();});}}}));x3dom.registerNodeType("Box","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.Box.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'size',2,2,2);this.addField_SFBool(ctx,'hasHelperColors',false);var sx=this._vf.size.x,sy=this._vf.size.y,sz=this._vf.size.z;var geoCacheID='Box_'+sx+'-'+sy+'-'+sz;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined)
+{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];if(this._vf.hasHelperColors){this._mesh._colors[0]=[0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,1,0,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];this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName==="hasHelperColors"){if(this._vf.hasHelperColors){this._mesh._colors[0]=[0,0,0,0,1,0,1,1,0,1,0,0,0,0,1,0,1,1,1,1,1,1,0,1,0,0,0,0,0,1,0,1,1,0,1,0,1,0,0,1,0,1,1,1,1,1,1,0,0,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,1,1,0,1,1,0,0];}
+else{this._mesh._colors[0]=[];}
+Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}}}));x3dom.registerNodeType("Sphere","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,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+'-'+subx+'-'+suby;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined){this._mesh=x3dom.geoCache[geoCacheID];}
+else{if(ctx){qfactor=ctx.doc.properties.getProperty("PrimitiveQuality","Medium");}
+if(!x3dom.Utils.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-(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]=[];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.invalidateVolume();this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+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-(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.invalidateVolume();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();node.invalidateVolume();});}}}));x3dom.registerNodeType("Torus","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.Torus.superClass.call(this,ctx);var twoPi=2.0*Math.PI;this.addField_SFFloat(ctx,'innerRadius',0.5);this.addField_SFFloat(ctx,'outerRadius',1.0);this.addField_SFFloat(ctx,'angle',twoPi);this.addField_SFBool(ctx,'caps',true);this.addField_SFVec2f(ctx,'subdivision',24,24);this.addField_SFBool(ctx,'insideOutsideRadius',false);if(this._vf.angle<0)
+this._vf.angle=0;else if(this._vf.angle>twoPi)
+this._vf.angle=twoPi;this._origCCW=this._vf.ccw;var innerRadius=this._vf.innerRadius;var outerRadius=this._vf.outerRadius;if(this._vf.insideOutsideRadius==true)
+{if(innerRadius>outerRadius){var tmp=innerRadius;innerRadius=outerRadius;outerRadius=tmp;}
+var rad=(outerRadius-innerRadius)/2;outerRadius=innerRadius+rad;innerRadius=rad;this._vf.ccw=!this._origCCW;}
+var rings=this._vf.subdivision.x,sides=this._vf.subdivision.y;rings=Math.max(3,Math.round((this._vf.angle/twoPi)*rings));var geoCacheID='Torus_'+innerRadius+'_'+outerRadius+'_'+this._vf.angle+'_'+
+this._vf.subdivision+'-'+this._vf.caps;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined)
+{this._mesh=x3dom.geoCache[geoCacheID];}
+else
+{var ringDelta=this._vf.angle/rings;var sideDelta=twoPi/sides;var a,b,theta,phi;var cosTheta,sinTheta,cosPhi,sinPhi,dist;for(a=0,theta=0;a<=rings;a++,theta+=ringDelta)
+{cosTheta=Math.cos(theta);sinTheta=Math.sin(theta);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*dist,innerRadius*sinPhi,-sinTheta*dist);this._mesh._normals[0].push(cosTheta*cosPhi,sinPhi,-sinTheta*cosPhi);}
+else{this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,innerRadius*sinPhi);this._mesh._normals[0].push(cosTheta*cosPhi,-sinTheta*cosPhi,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);}}
+if(this._vf.angle<twoPi&&this._vf.caps==true)
+{var origPos=this._mesh._positions[0].length/3;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(outerRadius,0,0);this._mesh._normals[0].push(0,0,1);}
+else{this._mesh._positions[0].push(outerRadius,0,0);this._mesh._normals[0].push(0,1,0);}
+this._mesh._texCoords[0].push(0.5,0.5);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(dist,sinPhi*innerRadius,0);this._mesh._normals[0].push(0,0,1);}
+else{this._mesh._positions[0].push(dist,0,sinPhi*innerRadius);this._mesh._normals[0].push(0,1,0);}
+this._mesh._texCoords[0].push((1+cosPhi)*0.5,(1-sinPhi)*0.5);if(b>0){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b);this._mesh._indices[0].push(origPos+b-1);}
+if(b==sides){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+1);this._mesh._indices[0].push(origPos+b);}}
+cosTheta=Math.cos(this._vf.angle);sinTheta=Math.sin(this._vf.angle);origPos=this._mesh._positions[0].length/3;var nx=-sinTheta,ny=-cosTheta;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*outerRadius,0,-sinTheta*outerRadius);this._mesh._normals[0].push(nx,0,ny);}
+else{this._mesh._positions[0].push(cosTheta*outerRadius,-sinTheta*outerRadius,0);this._mesh._normals[0].push(nx,ny,0);}
+this._mesh._texCoords[0].push(0.5,0.5);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*dist,sinPhi*innerRadius,-sinTheta*dist);this._mesh._normals[0].push(nx,0,ny);}
+else{this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,sinPhi*innerRadius);this._mesh._normals[0].push(nx,ny,0);}
+this._mesh._texCoords[0].push(1-(1+cosPhi)*0.5,(1-sinPhi)*0.5);if(b>0){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b-1);this._mesh._indices[0].push(origPos+b);}
+if(b==sides){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b);this._mesh._indices[0].push(origPos+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=="innerRadius"||fieldName=="outerRadius"||fieldName=="subdivision"||fieldName=="angle"||fieldName=="insideOutsideRadius"||fieldName=="caps")
+{var twoPi=2.0*Math.PI;if(this._vf.angle<0)
+this._vf.angle=0;else if(this._vf.angle>twoPi)
+this._vf.angle=twoPi;var innerRadius=this._vf.innerRadius;var outerRadius=this._vf.outerRadius;if(this._vf.insideOutsideRadius==true)
+{if(innerRadius>outerRadius){var tmp=innerRadius;innerRadius=outerRadius;outerRadius=tmp;}
+var rad=(outerRadius-innerRadius)/2;outerRadius=innerRadius+rad;innerRadius=rad;this._vf.ccw=!this._origCCW;}
+else
+this._vf.ccw=this._origCCW;var rings=this._vf.subdivision.x,sides=this._vf.subdivision.y;rings=Math.max(3,Math.round((this._vf.angle/twoPi)*rings));var ringDelta=this._vf.angle/rings;var sideDelta=twoPi/sides;var a,b,theta,phi;var cosTheta,sinTheta,cosPhi,sinPhi,dist;this._mesh._positions[0]=[];this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._indices[0]=[];for(a=0,theta=0;a<=rings;a++,theta+=ringDelta)
+{cosTheta=Math.cos(theta);sinTheta=Math.sin(theta);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*dist,innerRadius*sinPhi,-sinTheta*dist);this._mesh._normals[0].push(cosTheta*cosPhi,sinPhi,-sinTheta*cosPhi);}
+else{this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,innerRadius*sinPhi);this._mesh._normals[0].push(cosTheta*cosPhi,-sinTheta*cosPhi,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);}}
+if(this._vf.angle<twoPi&&this._vf.caps==true)
+{var origPos=this._mesh._positions[0].length/3;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(outerRadius,0,0);this._mesh._normals[0].push(0,0,1);}
+else{this._mesh._positions[0].push(outerRadius,0,0);this._mesh._normals[0].push(0,1,0);}
+this._mesh._texCoords[0].push(0.5,0.5);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(dist,sinPhi*innerRadius,0);this._mesh._normals[0].push(0,0,1);}
+else{this._mesh._positions[0].push(dist,0,sinPhi*innerRadius);this._mesh._normals[0].push(0,1,0);}
+this._mesh._texCoords[0].push((1+cosPhi)*0.5,(1-sinPhi)*0.5);if(b>0){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b);this._mesh._indices[0].push(origPos+b-1);}
+if(b==sides){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+1);this._mesh._indices[0].push(origPos+b);}}
+cosTheta=Math.cos(this._vf.angle);sinTheta=Math.sin(this._vf.angle);origPos=this._mesh._positions[0].length/3;var nx=-sinTheta,ny=-cosTheta;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*outerRadius,0,-sinTheta*outerRadius);this._mesh._normals[0].push(nx,0,ny);}
+else{this._mesh._positions[0].push(cosTheta*outerRadius,-sinTheta*outerRadius,0);this._mesh._normals[0].push(nx,ny,0);}
+this._mesh._texCoords[0].push(0.5,0.5);for(b=0,phi=0;b<=sides;b++,phi+=sideDelta)
+{cosPhi=Math.cos(phi);sinPhi=Math.sin(phi);dist=outerRadius+innerRadius*cosPhi;if(this._vf.insideOutsideRadius){this._mesh._positions[0].push(cosTheta*dist,sinPhi*innerRadius,-sinTheta*dist);this._mesh._normals[0].push(nx,0,ny);}
+else{this._mesh._positions[0].push(cosTheta*dist,-sinTheta*dist,sinPhi*innerRadius);this._mesh._normals[0].push(nx,ny,0);}
+this._mesh._texCoords[0].push(1-(1+cosPhi)*0.5,(1-sinPhi)*0.5);if(b>0){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b-1);this._mesh._indices[0].push(origPos+b);}
+if(b==sides){this._mesh._indices[0].push(origPos);this._mesh._indices[0].push(origPos+b);this._mesh._indices[0].push(origPos+1);}}}
+this.invalidateVolume();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();node.invalidateVolume();});}}}));x3dom.registerNodeType("Cone","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.Cone.superClass.call(this,ctx);this.addField_SFFloat(ctx,'bottomRadius',1.0);this.addField_SFFloat(ctx,'topRadius',0);this.addField_SFFloat(ctx,'height',2.0);this.addField_SFBool(ctx,'bottom',true);this.addField_SFBool(ctx,'side',true);this.addField_SFBool(ctx,'top',true);this.addField_SFFloat(ctx,'subdivision',32);var geoCacheID='Cone_'+this._vf.bottomRadius+'_'+this._vf.height+'_'+this._vf.top+'_'+
+this._vf.bottom+'_'+this._vf.side+'_'+this._vf.topRadius+'_'+this._vf.subdivision;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined){this._mesh=x3dom.geoCache[geoCacheID];}
+else{var bottomRadius=this._vf.bottomRadius,height=this._vf.height;var topRadius=this._vf.topRadius,sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var incl=(bottomRadius-topRadius)/height;var nlen=1.0/Math.sqrt(1.0+incl*incl);var j=0,k=0;var h,base;if(this._vf.side&&height>0){var px=0,pz=0;for(j=0,k=0;j<=sides;j++){beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);if(topRadius>x3dom.fields.Eps){px=x*topRadius;pz=z*topRadius;}
+this._mesh._positions[0].push(px,height/2,pz);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);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){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);}
+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);}}
+if(this._vf.top&&topRadius>x3dom.fields.Eps){base=this._mesh._positions[0].length/3;for(j=sides-1;j>=0;j--){beta=j*delta;x=topRadius*Math.sin(beta);z=-topRadius*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/topRadius/2+0.5,1.0-z/topRadius/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);}}
+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=="topRadius"||fieldName=="height"||fieldName=="subdivision"||fieldName=="bottom"||fieldName=="top"||fieldName=="side")
+{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 topRadius=this._vf.topRadius,sides=this._vf.subdivision;var beta,x,z;var delta=2.0*Math.PI/sides;var incl=(bottomRadius-topRadius)/height;var nlen=1.0/Math.sqrt(1.0+incl*incl);var j=0,k=0;var h,base;if(this._vf.side&&height>0)
+{var px=0,pz=0;for(j=0,k=0;j<=sides;j++){beta=j*delta;x=Math.sin(beta);z=-Math.cos(beta);if(topRadius>x3dom.fields.Eps){px=x*topRadius;pz=z*topRadius;}
+this._mesh._positions[0].push(px,height/2,pz);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);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)
+{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);}
+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);}}
+if(this._vf.top&&topRadius>x3dom.fields.Eps)
+{base=this._mesh._positions[0].length/3;for(j=sides-1;j>=0;j--){beta=j*delta;x=topRadius*Math.sin(beta);z=-topRadius*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/topRadius/2+0.5,1.0-z/topRadius/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);}}
+this.invalidateVolume();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();node.invalidateVolume();});}}}));x3dom.registerNodeType("Cylinder","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,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+'_'+this._vf.subdivision;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined)
+{this._mesh=x3dom.geoCache[geoCacheID];}
+else
+{var radius=this._vf.radius;var height=this._vf.height/2;var beta,x,z;var delta=2.0*Math.PI/sides;var j,k;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,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,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);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,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,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/2;var sides=this._vf.subdivision;var beta,x,z,j;var delta=2.0*Math.PI/sides;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,z*radius);this._mesh._positions[0].push(x*radius,height,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,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,z);}}
+this.invalidateVolume();this._mesh._numCoords=this._mesh._positions[0].length/3;Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node.invalidateVolume();});}
+else if(fieldName==="subdivision"||fieldName==="bottom"||fieldName==="top"||fieldName==="side")
+{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/2;var sides=this._vf.subdivision;var beta,x,z,j;var delta=2.0*Math.PI/sides;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,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,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,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,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.invalidateVolume();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();node.invalidateVolume();});}}}));x3dom.registerNodeType("ExternalGeometry","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.ExternalGeometry.superClass.call(this,ctx);this.addField_SFString(ctx,'url',"");this._mesh._invalidate=false;this._mesh._numCoords=0;this._mesh._numFaces=0;},{updateRenderData:function(shape,shaderProgram,gl,viewarea,context){var that=this;var xhr;if(this._vf['url']==""){return;}
+if(x3dom.BinaryContainerLoader.outOfMemory){return;}
+shape._webgl.internalDownloadCount=1;shape._nameSpace.doc.downloadCount=1;xhr=new XMLHttpRequest();xhr.open("GET",encodeURI(this._vf['url']),true);xhr.responseType="arraybuffer";xhr.send(null);xhr.onerror=function(){x3dom.debug.logError("Unable to load SRC data from URL \""+encodeURI(that._vf['url'])+"\"");};xhr.onload=function(){shape._webgl.internalDownloadCount=0;shape._nameSpace.doc.downloadCount=0;var responseBeginUint32=new Uint32Array(xhr.response,0,12);var srcHeaderSize,srcBodySize,srcBodyOffset;var srcHeaderView,srcBodyView;var srcHeaderObj;if(xhr.status==200&&responseBeginUint32.length>=3){srcHeaderSize=responseBeginUint32[2];srcBodyOffset=srcHeaderSize+12;srcBodySize=xhr.response.byteLength-srcBodyOffset;if(srcHeaderSize>0&&srcBodySize>=0)
+{srcHeaderView=new Uint8Array(xhr.response,12,srcHeaderSize);srcBodyView=new Uint8Array(xhr.response,srcBodyOffset,srcBodySize);try
+{srcHeaderObj=JSON.parse(String.fromCharCode.apply(null,srcHeaderView));}
+catch(exc)
+{x3dom.debug.logError("Unable to parse SRC header: "+exc);return;}
+that._updateRenderDataFromSRC(shape,shaderProgram,gl,srcHeaderObj,srcBodyView);}
+else
+{x3dom.debug.logError("Invalid SRC data, loaded from URL \""+
+encodeURI(that._vf['url'])+"\"");return;}}
+else
+{x3dom.debug.logError("Unable to load SRC data from URL \""+encodeURI(that._vf['url'])+"\"");}};},_updateRenderDataFromSRC:function(shape,shaderProgram,gl,srcHeaderObj,srcBodyView)
+{var INDEX_BUFFER_IDX=0;var POSITION_BUFFER_IDX=1;var NORMAL_BUFFER_IDX=2;var TEXCOORD_BUFFER_IDX=3;var COLOR_BUFFER_IDX=4;var ID_BUFFER_IDX=5;var MAX_NUM_BUFFERS_PER_DRAW=6;var indexViews=srcHeaderObj["accessors"]["indexViews"];var indexViewID,indexView;var attributeViews=srcHeaderObj["accessors"]["attributeViews"];var attributes;var attributeID,attributeView;var x3domTypeID,x3domShortTypeID,numComponents;var meshes=srcHeaderObj["meshes"];var mesh,meshID;var meshIdx,bufferOffset;var viewIDsToGLBufferIDs={};var indexViewBufferIDs={};for(indexViewID in indexViews)
+{indexView=indexViews[indexViewID];indexViewBufferIDs[indexView["bufferView"]]=true;}
+this._createGLBuffersFromSRCChunks(gl,srcHeaderObj["bufferChunks"],srcHeaderObj["bufferViews"],srcBodyView,indexViewBufferIDs,viewIDsToGLBufferIDs);for(indexViewID in indexViews)
+{indexView=indexViews[indexViewID];if(indexView["componentType"]!=gl.UNSIGNED_SHORT)
+{x3dom.debug.logWarning("SRC index componentType "+indexView["componentType"]+" is not UNSIGNED_SHORT. "+"Ignoring given value and assuming UNSIGNED_SHORT indices.");}
+shape._webgl.indexType=gl.UNSIGNED_SHORT;}
+meshIdx=0;bufferOffset=0;shape._webgl.primType=[];shape._webgl.indexOffset=[];shape._webgl.drawCount=[];this._mesh._numCoords=0;this._mesh._numFaces=0;for(meshID in meshes)
+{mesh=meshes[meshID];indexViewID=mesh["indices"];if(indexViewID!="")
+{shape._webgl.externalGeometry=1;indexView=indexViews[indexViewID];shape._webgl.indexOffset[meshIdx]=indexView["byteOffset"];shape._webgl.drawCount[meshIdx]=indexView["count"];shape._webgl.buffers[INDEX_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[indexView["bufferView"]];this._mesh._numFaces+=indexView["count"]/3;}
+else
+{shape._webgl.externalGeometry=-1;}
+shape._webgl.primType[meshIdx]=mesh["primitive"];attributes=mesh["attributes"];for(attributeID in attributes)
+{attributeView=attributeViews[attributes[attributeID]];switch(attributeID)
+{case"position":x3domTypeID="coord";x3domShortTypeID="Pos";shape._webgl.buffers[POSITION_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[attributeView["bufferView"]];if(mesh["indices"]=="")
+{shape._webgl.drawCount=attributeView["count"];this._mesh._numFaces+=attributeView["count"]/3;}
+this._mesh._numCoords+=attributeView["count"];break;case"normal":x3domTypeID="normal";x3domShortTypeID="Norm";shape._webgl.buffers[NORMAL_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[attributeView["bufferView"]];break;case"texcoord":x3domTypeID="texCoord";x3domShortTypeID="Tex";shape._webgl.buffers[TEXCOORD_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[attributeView["bufferView"]];break;case"color":x3domTypeID="color";x3domShortTypeID="Col";shape._webgl.buffers[COLOR_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[attributeView["bufferView"]];break;case"id":x3domTypeID="id";x3domShortTypeID="Id";shape._webgl.buffers[ID_BUFFER_IDX+bufferOffset]=viewIDsToGLBufferIDs[attributeView["bufferView"]];break;};shape["_"+x3domTypeID+"StrideOffset"][0]=attributeView["byteStride"];shape["_"+x3domTypeID+"StrideOffset"][1]=attributeView["byteOffset"];shape._webgl[x3domTypeID+"Type"]=attributeView["componentType"];numComponents=x3dom.nodeTypes.ExternalGeometry._findNumComponentsForSRCAccessorType(attributeView["type"]);this._mesh["_num"+x3domShortTypeID+"Components"]=numComponents;}
+++meshIdx;bufferOffset+=MAX_NUM_BUFFERS_PER_DRAW;}
+shape._nameSpace.doc.needRender=true;x3dom.BinaryContainerLoader.checkError(gl);},_createGLBuffersFromSRCChunks:function(gl,bufferChunksObj,bufferViewsObj,srcBodyView,indexViewBufferIDs,viewIDsToGLBufferIDs)
+{var i;var bufferView;var chunkIDList;var bufferType;var chunk;var newBuffer;var chunkDataView;var currentChunkDataOffset;for(var bufferViewID in bufferViewsObj)
+{bufferType=(typeof indexViewBufferIDs[bufferViewID]!=='undefined')?gl.ELEMENT_ARRAY_BUFFER:gl.ARRAY_BUFFER;bufferView=bufferViewsObj[bufferViewID];chunkIDList=bufferView["chunks"];if(chunkIDList.length==1)
+{chunk=bufferChunksObj[chunkIDList[0]];chunkDataView=new Uint8Array(srcBodyView.buffer,srcBodyView.byteOffset+chunk["byteOffset"],chunk["byteLength"]);newBuffer=gl.createBuffer();gl.bindBuffer(bufferType,newBuffer);gl.bufferData(bufferType,chunkDataView,gl.STATIC_DRAW);viewIDsToGLBufferIDs[bufferViewID]=newBuffer;}
+else
+{newBuffer=gl.createBuffer();gl.bindBuffer(bufferType,newBuffer);gl.bufferData(bufferType,bufferView["byteLength"],gl.STATIC_DRAW);currentChunkDataOffset=0;for(i=0;i<chunkIDList.length;++i)
+{chunk=bufferChunksObj[chunkIDList[i]];chunkDataView=new Uint8Array(srcBodyView.buffer,srcBodyView.byteOffset+chunk["byteOffset"],chunk["byteLength"]);gl.bufferSubData(bufferType,currentChunkDataOffset,chunkDataView);currentChunkDataOffset+=chunk["byteLength"];}
+viewIDsToGLBufferIDs[bufferViewID]=newBuffer;}}},getVolume:function()
+{var vol=this._mesh._vol;var shapeNode;if(!vol.isValid())
+{shapeNode=this._parentNodes[0];if(typeof shapeNode._vf["bboxCenter"]!='undefined'&&typeof shapeNode._vf["bboxSize"]!='undefined')
+{vol.setBoundsByCenterSize(shapeNode._vf["bboxCenter"],shapeNode._vf["bboxSize"]);}
+else
+{}}
+return vol;}}));x3dom.nodeTypes.ExternalGeometry._findNumComponentsForSRCAccessorType=function(type)
+{switch(type)
+{case"SCALAR":return 1;case"VEC2":return 2;case"VEC3":return 3;case"VEC4":return 4;default:return 0;}}
+x3dom.registerNodeType("X3DBinaryContainerGeometryNode","Geometry3D",defineClass(x3dom.nodeTypes.X3DSpatialGeometryNode,function(ctx){x3dom.nodeTypes.X3DBinaryContainerGeometryNode.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'position',0,0,0);this.addField_SFVec3f(ctx,'size',1,1,1);this.addField_MFInt32(ctx,'vertexCount',[0]);this.addField_MFString(ctx,'primType',['TRIANGLES']);this._mesh._invalidate=false;this._mesh._numCoords=0;this._mesh._numFaces=0;this._diameter=this._vf.size.length();},{getMin:function(){var vol=this._mesh._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol.min;},getMax:function(){var vol=this._mesh._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol.max;},getVolume:function(){var vol=this._mesh._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol;},invalidateVolume:function(){},getCenter:function(){return this._vf.position;},getDiameter:function(){return this._diameter;},needLighting:function(){var hasTris=(this._vf.primType.length&&this._vf.primType[0].indexOf("TRIANGLE")>=0);return(this._vf.lit&&hasTris);}}));x3dom.registerNodeType("BinaryGeometry","Geometry3D",defineClass(x3dom.nodeTypes.X3DBinaryContainerGeometryNode,function(ctx){x3dom.nodeTypes.BinaryGeometry.superClass.call(this,ctx);this.addField_SFString(ctx,'index',"");this.addField_SFString(ctx,'coord',"");this.addField_SFString(ctx,'normal',"");this.addField_SFString(ctx,'texCoord',"");this.addField_SFString(ctx,'color',"");this.addField_SFString(ctx,'tangent',"");this.addField_SFString(ctx,'binormal',"");this.addField_SFString(ctx,'indexType',"Uint16");this.addField_SFString(ctx,'coordType',"Float32");this.addField_SFString(ctx,'normalType',"Float32");this.addField_SFString(ctx,'texCoordType',"Float32");this.addField_SFString(ctx,'colorType',"Float32");this.addField_SFString(ctx,'tangentType',"Float32");this.addField_SFString(ctx,'binormalType',"Float32");this.addField_SFBool(ctx,'normalAsSphericalCoordinates',false);this.addField_SFBool(ctx,'rgbaColors',false);this.addField_SFInt32(ctx,'numTexCoordComponents',2);this.addField_SFBool(ctx,'normalPerVertex',true);this.addField_SFBool(ctx,'idsPerVertex',false);this._hasStrideOffset=false;this._mesh._numPosComponents=this._vf.normalAsSphericalCoordinates?4:3;this._mesh._numTexComponents=this._vf.numTexCoordComponents;this._mesh._numColComponents=this._vf.rgbaColors?4:3;this._mesh._numNormComponents=this._vf.normalAsSphericalCoordinates?2:3;this._vertexCountSum=0;for(var i=0;i<this._vf.vertexCount.length;++i){this._vertexCountSum+=this._vf.vertexCount[i];}},{parentAdded:function(parent)
+{var offsetInd,strideInd,offset,stride;offsetInd=this._vf.coord.lastIndexOf('#');strideInd=this._vf.coord.lastIndexOf('+');if(offsetInd>=0&&strideInd>=0){offset=+this._vf.coord.substring(++offsetInd,strideInd);stride=+this._vf.coord.substring(strideInd);parent._coordStrideOffset=[stride,offset];this._hasStrideOffset=true;if((offset/8)-Math.floor(offset/8)==0){this._mesh._numPosComponents=4;}}
+else if(strideInd>=0){stride=+this._vf.coord.substring(strideInd);parent._coordStrideOffset=[stride,0];if((stride/8)-Math.floor(stride/8)==0){this._mesh._numPosComponents=4;}}
+offsetInd=this._vf.normal.lastIndexOf('#');strideInd=this._vf.normal.lastIndexOf('+');if(offsetInd>=0&&strideInd>=0){offset=+this._vf.normal.substring(++offsetInd,strideInd);stride=+this._vf.normal.substring(strideInd);parent._normalStrideOffset=[stride,offset];}
+else if(strideInd>=0){stride=+this._vf.normal.substring(strideInd);parent._normalStrideOffset=[stride,0];}
+offsetInd=this._vf.texCoord.lastIndexOf('#');strideInd=this._vf.texCoord.lastIndexOf('+');if(offsetInd>=0&&strideInd>=0){offset=+this._vf.texCoord.substring(++offsetInd,strideInd);stride=+this._vf.texCoord.substring(strideInd);parent._texCoordStrideOffset=[stride,offset];}
+else if(strideInd>=0){stride=+this._vf.texCoord.substring(strideInd);parent._texCoordStrideOffset=[stride,0];}
+offsetInd=this._vf.color.lastIndexOf('#');strideInd=this._vf.color.lastIndexOf('+');if(offsetInd>=0&&strideInd>=0){offset=+this._vf.color.substring(++offsetInd,strideInd);stride=+this._vf.color.substring(strideInd);parent._colorStrideOffset=[stride,offset];}
+else if(strideInd>=0){stride=+this._vf.color.substring(strideInd);parent._colorStrideOffset=[stride,0];}
+if(this._vf.indexType!="Uint16"&&!x3dom.caps.INDEX_UINT)
+x3dom.debug.logWarning("Index type "+this._vf.indexType+" problematic");},doIntersect:function(line)
+{var min=this.getMin();var max=this.getMax();var isect=line.intersect(min,max);if(isect&&line.enter<line.dist){line.dist=line.enter;line.hitObject=this;line.hitPoint=line.pos.add(line.dir.multiply(line.enter));return true;}
+else{return false;}},getPrecisionMax:function(type)
+{switch(this._vf[type])
+{case"Int8":return 127.0;case"Uint8":return 255.0;case"Int16":return 32767.0;case"Uint16":return 65535.0;case"Int32":return 2147483647.0;case"Uint32":return 4294967295.0;case"Float32":case"Float64":default:return 1.0;}}}));x3dom.registerNodeType("PopGeometryLevel","Geometry3D",defineClass(x3dom.nodeTypes.X3DGeometricPropertyNode,function(ctx){x3dom.nodeTypes.PopGeometryLevel.superClass.call(this,ctx);this.addField_SFString(ctx,'src',"");this.addField_SFInt32(ctx,'numIndices',0);this.addField_SFInt32(ctx,'vertexDataBufferOffset',0);},{getSrc:function(){return this._vf.src;},getNumIndices:function(){return this._vf.numIndices;},getVertexDataBufferOffset:function(){return this._vf.vertexDataBufferOffset;}}));x3dom.registerNodeType("PopGeometry","Geometry3D",defineClass(x3dom.nodeTypes.X3DBinaryContainerGeometryNode,function(ctx){x3dom.nodeTypes.PopGeometry.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'tightSize',1,1,1);this.addField_SFVec3f(ctx,'maxBBSize',1,1,1);this.addField_SFVec3f(ctx,'bbMinModF',0,0,0);this.addField_SFVec3f(ctx,'bbMaxModF',1,1,1);this.addField_SFVec3f(ctx,'bbMin',0,0,0);this.addField_SFVec3f(ctx,'bbShiftVec',0,0,0);if(this._vf.bbMinModF.x>this._vf.bbMaxModF.x)
+this._vf.bbShiftVec.x=1.0;if(this._vf.bbMinModF.y>this._vf.bbMaxModF.y)
+this._vf.bbShiftVec.y=1.0;if(this._vf.bbMinModF.z>this._vf.bbMaxModF.z)
+this._vf.bbShiftVec.z=1.0;this.addField_MFNode('levels',x3dom.nodeTypes.PopGeometryLevel);this.addField_SFInt32(ctx,'attributeStride',0);this.addField_SFInt32(ctx,'positionOffset',0);this.addField_SFInt32(ctx,'normalOffset',0);this.addField_SFInt32(ctx,'texcoordOffset',0);this.addField_SFInt32(ctx,'colorOffset',0);this.addField_SFInt32(ctx,'numAnchorVertices',0);this.addField_SFInt32(ctx,'positionPrecision',2);this.addField_SFInt32(ctx,'normalPrecision',1);this.addField_SFInt32(ctx,'texcoordPrecision',2);this.addField_SFInt32(ctx,'colorPrecision',1);this.addField_SFInt32(ctx,'minPrecisionLevel',-1);this.addField_SFInt32(ctx,'maxPrecisionLevel',-1);this.addField_SFFloat(ctx,'precisionFactor',1.0);this.addField_SFString(ctx,'coordType',"Uint16");this.addField_SFString(ctx,'normalType',"Uint8");this.addField_SFString(ctx,'texCoordType',"Uint16");this.addField_SFString(ctx,'colorType',"Uint8");this.addField_SFInt32(ctx,'vertexBufferSize',0);this.addField_SFBool(ctx,'indexedRendering',true);this.addField_SFBool(ctx,'sphericalNormals',false);this.addField_MFInt32(ctx,'originalVertexCount',[0]);for(var i=0;i<this._vf.vertexCount.length;++i){this._vf.originalVertexCount[i]=this._vf.vertexCount[i];}
+this._vf.maxBBSize=x3dom.fields.SFVec3f.copy(this._vf.size);this._vf.size=this._vf.tightSize;this._diameter=this._vf.size.length();this._bbMinBySize=[Math.floor(this._vf.bbMin.x/this._vf.maxBBSize.x),Math.floor(this._vf.bbMin.y/this._vf.maxBBSize.y),Math.floor(this._vf.bbMin.z/this._vf.maxBBSize.z)];this._volRadius=this._vf.size.length()/2;this._volLargestRadius=this._vf.maxBBSize.length()/2;this._mesh._numPosComponents=this._vf.sphericalNormals?4:3;this._mesh._numNormComponents=this._vf.sphericalNormals?2:3;this._mesh._numTexComponents=2;this._mesh._numColComponents=3;x3dom.nodeTypes.PopGeometry.numTotalVerts+=this.getVertexCount();x3dom.nodeTypes.PopGeometry.numTotalTris+=(this.hasIndex()?this.getTotalNumberOfIndices():this.getVertexCount())/3;},{forceUpdateCoverage:function(){return true;},getBBoxShiftVec:function(){return this._vf.bbShiftVec;},getBBoxSize:function(){return this._vf.size;},hasIndex:function(){return this._vf.indexedRendering;},getTotalNumberOfIndices:function(){if(this._vf.indexedRendering){var sum=0;for(var i=0;i<this._vf.originalVertexCount.length;++i){sum+=this._vf.originalVertexCount[i];}
+return sum;}
+else{return 0;}},getVertexCount:function(){var sum=0;for(var i=0;i<this._vf.originalVertexCount.length;++i){sum+=this._vf.originalVertexCount[i];}
+return sum;},adaptVertexCount:function(numVerts){var verts=0;for(var i=0;i<this._vf.originalVertexCount.length;++i){if((this._vf.originalVertexCount[i]+verts)<=numVerts){this._vf.vertexCount[i]=this._vf.originalVertexCount[i];verts+=this._vf.originalVertexCount[i];}
+else{this._vf.vertexCount[i]=numVerts-verts;break;}}},hasNormal:function(){return(this._vf.normalOffset!=0)&&!this._vf.sphericalNormals;},hasTexCoord:function(){return(this._vf.texcoordOffset!=0);},hasColor:function(){return(this._vf.colorOffset!=0);},getPositionPrecision:function(){return this._vf.positionPrecision;},getNormalPrecision:function(){return this._vf.normalPrecision;},getTexCoordPrecision:function(){return this._vf.texcoordPrecision;},getColorPrecision:function(){return this._vf.colorPrecision;},getAttributeStride:function(){return this._vf.attributeStride;},getPositionOffset:function(){return this._vf.positionOffset;},getNormalOffset:function(){return this._vf.normalOffset;},getTexCoordOffset:function(){return this._vf.texcoordOffset;},getColorOffset:function(){return this._vf.colorOffset;},getBufferTypeStringFromByteCount:function(bytes){switch(bytes)
+{case 1:return"Uint8";case 2:return"Uint16";default:return 0;}},getDataURLs:function(){var urls=[];for(var i=0;i<this._cf.levels.nodes.length;++i){urls.push(this._cf.levels.nodes[i].getSrc());}
+return urls;},getNumIndicesByLevel:function(lvl){return this._cf.levels.nodes[lvl].getNumIndices();},getNumLevels:function(lvl){return this._cf.levels.nodes.length;},getVertexDataBufferOffset:function(lvl){return this._cf.levels.nodes[lvl].getVertexDataBufferOffset();},getPrecisionMax:function(type){switch(this._vf[type])
+{case"Uint8":return 255.0;case"Uint16":return 65535.0;default:return 1.0;}}}));x3dom.nodeTypes.PopGeometry.ErrorToleranceFactor=1;x3dom.nodeTypes.PopGeometry.PrecisionFactorOnMove=1;x3dom.nodeTypes.PopGeometry.numRenderedVerts=0;x3dom.nodeTypes.PopGeometry.numRenderedTris=0;x3dom.nodeTypes.PopGeometry.numTotalVerts=0;x3dom.nodeTypes.PopGeometry.numTotalTris=0;x3dom.nodeTypes.PopGeometry.powLUT=[32768,16384,8192,4096,2048,1024,512,256,128,64,32,16,8,4,2,1];x3dom.registerNodeType("ImageGeometry","Geometry3D",defineClass(x3dom.nodeTypes.X3DBinaryContainerGeometryNode,function(ctx){x3dom.nodeTypes.ImageGeometry.superClass.call(this,ctx);this.addField_SFVec2f(ctx,'implicitMeshSize',256,256);this.addField_SFInt32(ctx,'numColorComponents',3);this.addField_SFInt32(ctx,'numTexCoordComponents',2);this.addField_SFNode('index',x3dom.nodeTypes.X3DTextureNode);this.addField_MFNode('coord',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('normal',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('texCoord',x3dom.nodeTypes.X3DTextureNode);this.addField_SFNode('color',x3dom.nodeTypes.X3DTextureNode);this._mesh._numColComponents=this._vf.numColorComponents;this._mesh._numTexComponents=this._vf.numTexCoordComponents;if(this._vf.implicitMeshSize.y==0)
+this._vf.implicitMeshSize.y=this._vf.implicitMeshSize.x;if(x3dom.caps.BACKEND=='webgl'&&x3dom.caps.MAX_VERTEX_TEXTURE_IMAGE_UNITS>0){var geoCacheID='ImageGeometry_'+this._vf.implicitMeshSize.x+'_'+this._vf.implicitMeshSize.y;if(this._vf.useGeoCache&&x3dom.geoCache[geoCacheID]!==undefined)
+{this._mesh=x3dom.geoCache[geoCacheID];}
+else
+{for(var y=0;y<this._vf.implicitMeshSize.y;y++)
+{for(var x=0;x<this._vf.implicitMeshSize.x;x++)
+{this._mesh._positions[0].push(x/this._vf.implicitMeshSize.x,y/this._vf.implicitMeshSize.y,0);}}
+this._mesh._numFaces=this._mesh._indices[0].length/3;this._mesh._numCoords=this._mesh._positions[0].length/3;x3dom.geoCache[geoCacheID]=this._mesh;}}
+this._vol=new x3dom.fields.BoxVolume();this._dirty={coord:true,normal:true,texCoord:true,color:true,index:true};},{setGeoDirty:function(){this._dirty.coord=true;this._dirty.normal=true;this._dirty.texCoords=true;this._dirty.color=true;this._dirty.index=true;},unsetGeoDirty:function(){this._dirty.coord=false;this._dirty.normal=false;this._dirty.texCoords=false;this._dirty.color=false;this._dirty.index=false;},nodeChanged:function()
+{Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;node._dirty.normals=true;node._dirty.texcoords=true;node._dirty.colors=true;});this._vol.invalidate();},fieldChanged:function(fieldName)
+{if(fieldName=="index"||fieldName=="coord"||fieldName=="normal"||fieldName=="texCoord"||fieldName=="color"){this._dirty[fieldName]=true;this._vol.invalidate();}
+else if(fieldName=="implicitMeshSize"){this._vol.invalidate();}},getMin:function(){var vol=this._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol.min;},getMax:function(){var vol=this._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol.max;},getVolume:function(){var vol=this._vol;if(!vol.isValid()){vol.setBoundsByCenterSize(this._vf.position,this._vf.size);}
+return vol;},numCoordinateTextures:function()
+{return this._cf.coord.nodes.length;},getIndexTexture:function()
+{if(this._cf.index.node){this._cf.index.node._type="IG_index";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]){this._cf.coord.nodes[pos]._type="IG_coords"+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;}},getCoordinateTextureURLs:function()
+{var urls=[];for(var i=0;i<this._cf.coord.nodes.length;i++)
+{urls.push(this._cf.coord.nodes[i]._vf.url);}
+return urls;},getNormalTexture:function()
+{if(this._cf.normal.node){this._cf.normal.node._type="IG_normals";return this._cf.normal.node;}else{return null;}},getNormalTextureURL:function()
+{if(this._cf.normal.node){return this._cf.normal.node._vf.url;}else{return null;}},getTexCoordTexture:function()
+{if(this._cf.texCoord.node){this._cf.texCoord.node._type="IG_texCoords";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){this._cf.color.node._type="IG_colors";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;}},getTextures:function()
+{var textures=[];var index=this.getIndexTexture();if(index)textures.push(index);for(i=0;i<this.numCoordinateTextures();i++){var coord=this.getCoordinateTexture(i);if(coord)textures.push(coord);}
+var normal=this.getNormalTexture();if(normal)textures.push(normal);var texCoord=this.getTexCoordTexture();if(texCoord)textures.push(texCoord);var color=this.getColorTexture();if(color)textures.push(color);return textures;}}));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_SFBool(ctx,'convex',true);this.addField_MFInt32(ctx,'coordIndex',[]);this.addField_MFInt32(ctx,'normalIndex',[]);this.addField_MFInt32(ctx,'colorIndex',[]);this.addField_MFInt32(ctx,'texCoordIndex',[]);},{nodeChanged:function()
+{var time0=new Date().getTime();this.handleAttribs();var indexes=this._vf.coordIndex;if(indexes.length&&indexes[indexes.length-1]!=-1)
+{indexes.push(-1);x3dom.debug.logWarning('Last index value should be -1.');}
+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(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+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,j,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>x3dom.Utils.maxIndexableCoords)||(hasNormal&&hasNormalInd)||(hasTexCoord&&hasTexCoordInd)||(hasColor&&hasColorInd))
+{if(this._vf.creaseAngle<=x3dom.fields.Eps)
+x3dom.debug.logWarning('Fallback to inefficient multi-index mode since creaseAngle=0.');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 if(normPerVert){n0=p0;}
+else{n0=faceCnt;}
+if(hasTexCoordInd){t0=+texCoordInd[i];}
+else{t0=p0;}
+if(hasColorInd&&colPerVert){c0=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c0=+colorInd[faceCnt];}
+else if(colPerVert){c0=p0;}
+else{c0=faceCnt;}
+t=1;break;case 1:p1=+indexes[i];if(hasNormalInd&&normPerVert){n1=+normalInd[i];}
+else if(hasNormalInd&&!normPerVert){n1=+normalInd[faceCnt];}
+else if(normPerVert){n1=p1;}
+else{n1=faceCnt;}
+if(hasTexCoordInd){t1=+texCoordInd[i];}
+else{t1=p1;}
+if(hasColorInd&&colPerVert){c1=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c1=+colorInd[faceCnt];}
+else if(colPerVert){c1=p1;}
+else{c1=faceCnt;}
+t=2;break;case 2:p2=+indexes[i];if(hasNormalInd&&normPerVert){n2=+normalInd[i];}
+else if(hasNormalInd&&!normPerVert){n2=+normalInd[faceCnt];}
+else if(normPerVert){n2=p2;}
+else{n2=faceCnt;}
+if(hasTexCoordInd){t2=+texCoordInd[i];}
+else{t2=p2;}
+if(hasColorInd&&colPerVert){c2=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c2=+colorInd[faceCnt];}
+else if(colPerVert){c2=p2;}
+else{c2=faceCnt;}
+t=3;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);}
+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 if(normPerVert){n2=p2;}else{n2=faceCnt;}
+if(hasTexCoordInd){t2=+texCoordInd[i];}else{t2=p2;}
+if(hasColorInd&&colPerVert){c2=+colorInd[i];}else if(hasColorInd&&!colPerVert){}else if(colPerVert){c2=p2;}else{c2=faceCnt;}
+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);}
+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={};cnt=0;faceCnt=0;for(i=0;i<indexes.length;++i)
+{if(indexes[i]==-1){var multi_index_data=x3dom.EarClipping.getMultiIndexes(linklist);for(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 if(colPerVert){data.colors=colors[indexes[i]];}else{data.colors=colors[faceCnt];}}
+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));}
+this._mesh.splitMesh();}
+if(!hasNormal){this._mesh.calcNormals(this._vf.creaseAngle,this._vf.ccw);}
+if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}}
+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{linklist=new x3dom.DoublyLinkedList();for(i=0;i<indexes.length;++i)
+{if(indexes[i]==-1){var linklist_indices=x3dom.EarClipping.getIndexes(linklist);for(j=0;j<linklist_indices.length;j++){this._mesh._indices[0].push(linklist_indices[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,this._vf.ccw);}
+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.invalidateVolume();this._mesh._numFaces=0;this._mesh._numCoords=0;for(i=0;i<this._mesh._positions.length;i++){var indexLength=this._mesh._indices[i].length;var numCoords=this._mesh._positions[i].length/3;this._mesh._numCoords+=numCoords;if(indexLength>0)
+this._mesh._numFaces+=indexLength/3;else
+this._mesh._numFaces+=numCoords/3;}},fieldChanged:function(fieldName)
+{if(fieldName!="coord"&&fieldName!="normal"&&fieldName!="texCoord"&&fieldName!="color"&&fieldName!="coordIndex")
+{x3dom.debug.logWarning("IndexedFaceSet: fieldChanged for "+
+fieldName+" not yet implemented!");return;}
+var pnts=this._cf.coord.node._vf.point;var n=pnts.length;var texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+if(((this._vf.creaseAngle<=x3dom.fields.Eps)||(n>x3dom.Utils.maxIndexableCoords)||(this._vf.normalIndex.length>0&&this._cf.normal.node)||(this._vf.texCoordIndex.length>0&&texCoordNode)||(this._vf.colorIndex.length>0&&this._cf.color.node))&&this._mesh._multiIndIndices)
+{var needNormals=!this._cf.normal.node&&this._vf.normalUpdateMode.toLowerCase()!='none';n=this._mesh._multiIndIndices.length;this._mesh._positions[0]=[];this._mesh._indices[0]=[];if(fieldName=="coord"&&n)
+{if(needNormals){this._mesh._normals[0]=[];}
+for(i=0;i<n;i+=3){var ind0=this._mesh._multiIndIndices[i];var ind1=this._mesh._multiIndIndices[i+1];var ind2=this._mesh._multiIndIndices[i+2];var pos0=pnts[ind0];var pos1=pnts[ind1];var pos2=pnts[ind2];this._mesh._positions[0].push(pos0.x,pos0.y,pos0.z);this._mesh._positions[0].push(pos1.x,pos1.y,pos1.z);this._mesh._positions[0].push(pos2.x,pos2.y,pos2.z);if(needNormals){var a=pos0.subtract(pos1);var b=pos1.subtract(pos2);var norm=a.cross(b).normalize();if(!this._vf.ccw)
+norm=norm.negate();this._mesh._normals[0].push(norm.x,norm.y,norm.z);this._mesh._normals[0].push(norm.x,norm.y,norm.z);this._mesh._normals[0].push(norm.x,norm.y,norm.z);}}
+this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;if(needNormals)
+node._dirty.normals=true;});return;}
+this._mesh._normals[0]=[];this._mesh._texCoords[0]=[];this._mesh._colors[0]=[];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;texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+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;var i,j,t,cnt,faceCnt;var p0,p1,p2,n0,n1,n2,t0,t1,t2,c0,c1,c2;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 if(normPerVert){n0=p0;}
+else{n0=faceCnt;}
+if(hasTexCoordInd){t0=+texCoordInd[i];}
+else{t0=p0;}
+if(hasColorInd&&colPerVert){c0=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c0=+colorInd[faceCnt];}
+else if(colPerVert){c0=p0;}
+else{c0=faceCnt;}
+t=1;break;case 1:p1=+indexes[i];if(hasNormalInd&&normPerVert){n1=+normalInd[i];}
+else if(hasNormalInd&&!normPerVert){n1=+normalInd[faceCnt];}
+else if(normPerVert){n1=p1;}
+else{n1=faceCnt;}
+if(hasTexCoordInd){t1=+texCoordInd[i];}
+else{t1=p1;}
+if(hasColorInd&&colPerVert){c1=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c1=+colorInd[faceCnt];}
+else if(colPerVert){c1=p1;}
+else{c1=faceCnt;}
+t=2;break;case 2:p2=+indexes[i];if(hasNormalInd&&normPerVert){n2=+normalInd[i];}
+else if(hasNormalInd&&!normPerVert){n2=+normalInd[faceCnt];}
+else if(normPerVert){n2=p2;}
+else{n2=faceCnt;}
+if(hasTexCoordInd){t2=+texCoordInd[i];}
+else{t2=p2;}
+if(hasColorInd&&colPerVert){c2=+colorInd[i];}
+else if(hasColorInd&&!colPerVert){c2=+colorInd[faceCnt];}
+else if(colPerVert){c2=p2;}
+else{c2=faceCnt;}
+t=3;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);}
+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 if(normPerVert){n2=p2;}else{n2=faceCnt;}
+if(hasTexCoordInd){t2=+texCoordInd[i];}else{t2=p2;}
+if(hasColorInd&&colPerVert){c2=+colorInd[i];}else if(hasColorInd&&!colPerVert){}else if(colPerVert){c2=p2;}else{c2=faceCnt;}
+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);}
+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={};cnt=0;faceCnt=0;for(i=0;i<indexes.length;++i)
+{if(indexes[i]==-1){var multi_index_data=x3dom.EarClipping.getMultiIndexes(linklist);for(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));}
+this._mesh.splitMesh();}
+if(!hasNormal){this._mesh.calcNormals(this._vf.creaseAngle,this._vf.ccw);}
+if(!hasTexCoord){this._mesh.calcTexCoords(texMode);}
+this.invalidateVolume();this._mesh._numFaces=0;this._mesh._numCoords=0;for(i=0;i<this._mesh._positions.length;i++){var indexLength=this._mesh._indices[i].length;var numCoords=this._mesh._positions[i].length/3;this._mesh._numCoords+=numCoords;if(indexLength>0)
+this._mesh._numFaces+=indexLength/3;else
+this._mesh._numFaces+=numCoords/3;}
+Array.forEach(this._parentNodes,function(node){node.setGeoDirty();});}
+else{if(fieldName=="coord")
+{var needNormals=!this._cf.normal.node&&this._vf.normalUpdateMode.toLowerCase()!='none';this._mesh._positions[0]=pnts.toGL();if(needNormals){this._mesh.calcNormals(this._vf.creaseAngle,this._vf.ccw);}
+this.invalidateVolume();Array.forEach(this._parentNodes,function(node){node._dirty.positions=true;if(needNormals)
+node._dirty.normals=true;node.invalidateVolume();});}
+else if(fieldName=="color")
+{pnts=this._cf.color.node._vf.color;this._mesh._colors[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.colors=true;});}
+else if(fieldName=="normal")
+{pnts=this._cf.normal.node._vf.vector;this._mesh._normals[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.normals=true;});}
+else if(fieldName=="texCoord")
+{texCoordNode=this._cf.texCoord.node;if(x3dom.isa(texCoordNode,x3dom.nodeTypes.MultiTextureCoordinate)){if(texCoordNode._cf.texCoord.nodes.length)
+texCoordNode=texCoordNode._cf.texCoord.nodes[0];}
+pnts=texCoordNode._vf.point;this._mesh._texCoords[0]=pnts.toGL();Array.forEach(this._parentNodes,function(node){node._dirty.texcoords=true;});}
+else if(fieldName=="coordIndex")
+{needNormals=!this._cf.normal.node&&this._vf.normalUpdateMode.toLowerCase()!='none';indexes=this._vf.coordIndex;t=0;n=indexes.length;this._mesh._indices[0]=[];for(i=0;i<n;++i){if(indexes[i]==-1){t=0;}
+else{switch(t){case 0:p0=+indexes[i];t=1;break;case 1:p1=+indexes[i];t=2;break;case 2:p2=+indexes[i];t=3;this._mesh._indices[0].push(p0,p1,p2);break;case 3:p1=p2;p2=+indexes[i];this._mesh._indices[0].push(p0,p1,p2);break;}}}
+if(needNormals){this._mesh.calcNormals(this._vf.creaseAngle,this._vf.ccw);}
+Array.forEach(this._parentNodes,function(node){node._dirty.indexes=true;if(needNormals)
+node._dirty.normals=true;});}}}}));x3dom.registerNodeType("X3DTexture3DNode","Texturing3D",defineClass(x3dom.nodeTypes.X3DTextureNode,function(ctx){x3dom.nodeTypes.X3DTexture3DNode.superClass.call(this,ctx);}));x3dom.registerNodeType("ComposedTexture3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTexture3DNode,function(ctx){x3dom.nodeTypes.ComposedTexture3D.superClass.call(this,ctx);this.addField_MFNode('texture',x3dom.nodeTypes.X3DTexture3DNode);}));x3dom.registerNodeType("ImageTexture3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTexture3DNode,function(ctx){x3dom.nodeTypes.ImageTexture3D.superClass.call(this,ctx);}));x3dom.registerNodeType("PixelTexture3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTexture3DNode,function(ctx){x3dom.nodeTypes.PixelTexture3D.superClass.call(this,ctx);}));x3dom.registerNodeType("TextureCoordinate3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTextureCoordinateNode,function(ctx){x3dom.nodeTypes.TextureCoordinate3D.superClass.call(this,ctx);this.addField_MFVec3f(ctx,'point',[]);}));x3dom.registerNodeType("TextureTransform3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTextureTransformNode,function(ctx){x3dom.nodeTypes.TextureTransform3D.superClass.call(this,ctx);this.addField_SFVec3f(ctx,'center',0,0,0);this.addField_SFRotation(ctx,'rotation',0,0,1,0);this.addField_SFVec3f(ctx,'scale',1,1,1);this.addField_SFVec3f(ctx,'translation',0,0,0);this.addField_SFRotation(ctx,'scaleOrientation',0,0,1,0);}));x3dom.registerNodeType("TextureTransformMatrix3D","Texturing3D",defineClass(x3dom.nodeTypes.X3DTextureTransformNode,function(ctx){x3dom.nodeTypes.TextureTransformMatrix3D.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);}));x3dom.registerNodeType("X3DPointingDeviceSensorNode","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DSensorNode,function(ctx)
+{x3dom.nodeTypes.X3DPointingDeviceSensorNode.superClass.call(this,ctx);},{pointerPressedOverSibling:function(event)
+{if(this._vf["enabled"])
+{this._vf["isActive"]=true;this.postMessage('isActive',true);}},pointerMoved:function(event)
+{},pointerMovedOver:function(event)
+{if(this._vf["enabled"])
+{this.postMessage('isOver',true);}},pointerMovedOut:function(event)
+{if(this._vf["enabled"])
+{this.postMessage('isOver',false);}},pointerReleased:function()
+{if(this._vf["enabled"])
+{this._vf["isActive"]=false;this.postMessage('isActive',false);}}}));x3dom.registerNodeType("X3DDragSensorNode","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DPointingDeviceSensorNode,function(ctx)
+{x3dom.nodeTypes.X3DDragSensorNode.superClass.call(this,ctx);this.addField_SFBool(ctx,'autoOffset',false);this._lastX=-1;this._lastY=-1;},{pointerPressedOverSibling:function(event)
+{x3dom.nodeTypes.X3DPointingDeviceSensorNode.prototype.pointerPressedOverSibling.call(this,event);this._lastX=event.layerX;this._lastY=event.layerY;this._startDragging(event.viewarea,event.layerX,event.layerX,event.worldX,event.worldY,event.worldZ);},pointerMoved:function(event)
+{x3dom.nodeTypes.X3DPointingDeviceSensorNode.prototype.pointerMoved.call(this,event);if(this._vf["isActive"]&&this._vf["enabled"])
+{this._process2DDrag(event.layerX,event.layerY,event.layerX-this._lastX,event.layerY-this._lastY);}},pointerReleased:function()
+{x3dom.nodeTypes.X3DPointingDeviceSensorNode.prototype.pointerReleased.call(this);this._stopDragging();},_startDragging:function(viewarea,x,y,wx,wy,wz)
+{},_process2DDrag:function(x,y,dx,dy)
+{},_stopDragging:function()
+{}}));x3dom.registerNodeType("X3DTouchSensorNode","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DPointingDeviceSensorNode,function(ctx)
+{x3dom.nodeTypes.X3DTouchSensorNode.superClass.call(this,ctx);},{}));x3dom.registerNodeType("TouchSensor","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DTouchSensorNode,function(ctx)
+{x3dom.nodeTypes.TouchSensor.superClass.call(this,ctx);},{}));x3dom.registerNodeType("PlaneSensor","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DDragSensorNode,function(ctx)
+{x3dom.nodeTypes.PlaneSensor.superClass.call(this,ctx);this.addField_SFRotation(ctx,'axisRotation',0,0,1,0);this.addField_SFVec2f(ctx,'minPosition',0,0);this.addField_SFVec2f(ctx,'maxPosition',-1,-1);this.addField_SFVec3f(ctx,'offset',0,0,0);this._rotationMatrix=this._vf['axisRotation'].toMatrix();this._worldToLocalMatrix=null;this._initialPlaneIntersection=null;this._planeNormal=null;this._viewArea=null;this._currentTranslation=new x3dom.fields.SFVec3f(0.0,0.0,0.0);},{getCurrentTransform:function()
+{var parentTransform=x3dom.nodeTypes.X3DDragSensorNode.prototype.getCurrentTransform.call(this);return parentTransform.mult(this._rotationMatrix);},_startDragging:function(viewarea,x,y,wx,wy,wz)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._startDragging.call(this,viewarea,x,y,wx,wy,wz);this._viewArea=viewarea;this._currentTranslation=new x3dom.fields.SFVec3f(0.0,0.0,0.0);this._worldToLocalMatrix=this.getCurrentTransform().inverse();this._initialPlaneIntersection=this._worldToLocalMatrix.multMatrixPnt(new x3dom.fields.SFVec3f(wx,wy,wz));this._planeNormal=new x3dom.fields.SFVec3f(0.0,0.0,1.0);},_process2DDrag:function(x,y,dx,dy)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._process2DDrag.call(this,x,y,dx,dy);var intersectionPoint;var minPos,maxPos;if(this._initialPlaneIntersection)
+{var viewRay=this._viewArea.calcViewRay(x,y);viewRay.pos=this._worldToLocalMatrix.multMatrixPnt(viewRay.pos);viewRay.dir=this._worldToLocalMatrix.multMatrixVec(viewRay.dir.normalize());intersectionPoint=viewRay.intersectPlane(this._initialPlaneIntersection,this._planeNormal);if(!intersectionPoint)
+{intersectionPoint=viewRay.intersectPlane(this._initialPlaneIntersection,this._planeNormal.negate());}
+if(intersectionPoint)
+{this._currentTranslation=intersectionPoint.subtract(this._initialPlaneIntersection);this._currentTranslation=this._currentTranslation.add(this._vf["offset"]);minPos=this._vf["minPosition"];maxPos=this._vf["maxPosition"];if(minPos.x<=maxPos.x)
+{this._currentTranslation.x=Math.min(this._currentTranslation.x,maxPos.x);this._currentTranslation.x=Math.max(this._currentTranslation.x,minPos.x);}
+if(minPos.y<=maxPos.y)
+{this._currentTranslation.y=Math.min(this._currentTranslation.y,maxPos.y);this._currentTranslation.y=Math.max(this._currentTranslation.y,minPos.y);}
+this.postMessage('translation_changed',x3dom.fields.SFVec3f.copy(this._currentTranslation));}}},_stopDragging:function()
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._stopDragging.call(this);if(this._vf["autoOffset"])
+{this._vf["offset"]=x3dom.fields.SFVec3f.copy(this._currentTranslation);this.postMessage('offset_changed',this._vf["offset"]);}}}));x3dom.registerNodeType("SphereSensor","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DDragSensorNode,function(ctx)
+{x3dom.nodeTypes.SphereSensor.superClass.call(this,ctx);this.addField_SFRotation(ctx,'offset',0,1,0,0);this._currentRotation=new x3dom.fields.Quaternion();},{_startDragging:function(viewarea,x,y,z)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._startDragging.call(this,viewarea,x,y,z);},_process2DDrag:function(x,y,dx,dy)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._process2DDrag.call(this,x,y,dx,dy);},_stopDragging:function()
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._stopDragging.call(this);if(this._vf["autoOffset"])
+{}
+this._currentRotation=new x3dom.fields.Quaternion();}}));x3dom.registerNodeType("CylinderSensor","PointingDeviceSensor",defineClass(x3dom.nodeTypes.X3DDragSensorNode,function(ctx)
+{x3dom.nodeTypes.CylinderSensor.superClass.call(this,ctx);this.addField_SFFloat(ctx,'offset',0);this.addField_SFRotation(ctx,'axisRotation',0,1,0,0);this.addField_SFFloat(ctx,'diskAngle',0.262);this.addField_SFFloat(ctx,'minAngle',0);this.addField_SFFloat(ctx,'maxAngle',-1);this._rotationMatrix=this._vf['axisRotation'].toMatrix();this._inverseToWorldMatrix=null;this._initialCylinderIntersectionVector=null;this._viewArea=null;this._cylinderRadius=0.0;this._yAxisLine=null;this._cylinderMode=true;this._currentRotationAngle=0.0;},{getCurrentTransform:function()
+{var parentTransform=x3dom.nodeTypes.X3DDragSensorNode.prototype.getCurrentTransform.call(this);return parentTransform.mult(this._rotationMatrix);},_startDragging:function(viewarea,x,y,wx,wy,wz)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._startDragging.call(this,viewarea,x,y,wx,wy,wz);this._currentRotation=new x3dom.fields.Quaternion();this._viewArea=viewarea;this._yAxisLine=new x3dom.fields.Line(new x3dom.fields.SFVec3f(0.0,0.0,0.0),new x3dom.fields.SFVec3f(0.0,1.0,0.0));this._inverseToWorldMatrix=this.getCurrentTransform().inverse();var firstIntersection=this._inverseToWorldMatrix.multMatrixPnt(new x3dom.fields.SFVec3f(wx,wy,wz));var closestPointOnYAxis=this._yAxisLine.closestPoint(firstIntersection);this._initialCylinderIntersectionVector=firstIntersection.subtract(closestPointOnYAxis);this._cylinderRadius=this._initialCylinderIntersectionVector.length();this._initialCylinderIntersectionVector=this._initialCylinderIntersectionVector.normalize();},_process2DDrag:function(x,y,dx,dy)
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._process2DDrag.call(this,x,y,dx,dy);if(this._cylinderMode)
+{var viewRay=this._viewArea.calcViewRay(x,y);viewRay.pos=this._inverseToWorldMatrix.multMatrixPnt(viewRay.pos);viewRay.dir=this._inverseToWorldMatrix.multMatrixVec(viewRay.dir);var A=viewRay.dir.subtract(this._yAxisLine.dir.multiply(viewRay.dir.dot(this._yAxisLine.dir)));var B=viewRay.pos.subtract(this._yAxisLine.pos).add(this._yAxisLine.dir.multiply(this._yAxisLine.dir.dot(this._yAxisLine.pos.subtract(viewRay.pos))));var p=2*A.dot(B)/A.dot(A);var q=(B.dot(B)-this._cylinderRadius*this._cylinderRadius)/A.dot(A);var sqrt_part=p*p*0.25-q;var alpha_1;var alpha_2;if(sqrt_part>=0)
+{sqrt_part=Math.sqrt(sqrt_part);alpha_1=-p*0.5+sqrt_part;alpha_2=-p*0.5-sqrt_part;alpha_1=Math.min(alpha_1,alpha_2);if(alpha_1>0.0)
+{var hitPoint=viewRay.pos.add(viewRay.dir.multiply(alpha_1));var closestPointOnYAxis=this._yAxisLine.closestPoint(hitPoint);var vecToHitPoint=hitPoint.subtract(closestPointOnYAxis).normalize();this._currentRotation=x3dom.fields.Quaternion.rotateFromTo(this._initialCylinderIntersectionVector,vecToHitPoint);var offsetQuat=x3dom.fields.Quaternion.axisAngle(this._yAxisLine.dir,this._vf["offset"]);this._currentRotation=this._currentRotation.multiply(offsetQuat);this.postMessage('rotation_changed',this._currentRotation);}}}
+else
+{}},_stopDragging:function()
+{x3dom.nodeTypes.X3DDragSensorNode.prototype._stopDragging.call(this);if(this._vf["autoOffset"])
+{this._vf["offset"]=this._currentRotation.angle();this.postMessage('offset_changed',this._vf["offset"]);}}}));x3dom.versionInfo={version:'1.6.0',revision:'5e8c0441fe2cbe9970ffd14f1546100672a95185',date:'Thu May 8 20:51:15 2014 +0200'};
\ No newline at end of file
diff --git a/public/index.html b/public/index.html
index 923a9a79aa8f69ee38931aaab5c266aca19bd9b0..9db183fa19d0607022fd1ed856c34e06757b0fcf 100644
--- a/public/index.html
+++ b/public/index.html
@@ -1,11 +1,47 @@
-<!DOCTYPE html>
 <html lang="en">
+
 <head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
-  <title>Visualization</title>
+  <title>X3DOM Tutorials</title>
+  <style>
+    ul {
+      list-style-type: none;
+      padding: 0;
+      margin: 0;
+    }
+
+    .button {
+      text-decoration: none;
+      display: block;
+      width: 500px;
+      height: 25px;
+      color: black;
+      background: lightgray;
+      padding: 10px;
+      text-align: center;
+      border-radius: 5px;
+      line-height: 25px;
+      margin-bottom: 10px;
+      font-family: sans-serif;
+    }
+
+    .button:hover {
+      background-color: #4CAF50;
+      color: white;
+    }
+
+    .center {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+    }
+  </style>
 </head>
+
 <body>
-  <a href="X3DOMTutorial/">X3DOM Tutorial</a>
+  <ul class="center">
+    <li><a class="button" href="X3DOMTutorial/">X3DOM Tutorial</a></li>
 </body>
-</html>
+
+</html>
\ No newline at end of file