提交 1e466921 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #10290 from bartmcleod/dev

New VRMLLoader based on the VrmlParser project
var $jscomp={scope:{},checkStringArgs:function(a,g,e){if(null==a)throw new TypeError("The 'this' value for String.prototype."+e+" must not be null or undefined");if(g instanceof RegExp)throw new TypeError("First argument to String.prototype."+e+" must not be a regular expression");return a+""}};
$jscomp.defineProperty="function"==typeof Object.defineProperties?Object.defineProperty:function(a,g,e){if(e.get||e.set)throw new TypeError("ES3 does not support getters and setters.");a!=Array.prototype&&a!=Object.prototype&&(a[g]=e.value)};$jscomp.getGlobal=function(a){return"undefined"!=typeof window&&window===a?a:"undefined"!=typeof global&&null!=global?global:a};$jscomp.global=$jscomp.getGlobal(this);
$jscomp.polyfill=function(a,g,e,l){if(g){e=$jscomp.global;a=a.split(".");for(l=0;l<a.length-1;l++){var k=a[l];k in e||(e[k]={});e=e[k]}a=a[a.length-1];l=e[a];g=g(l);g!=l&&null!=g&&$jscomp.defineProperty(e,a,{configurable:!0,writable:!0,value:g})}};
$jscomp.polyfill("String.prototype.repeat",function(a){return a?a:function(a){var g=$jscomp.checkStringArgs(this,null,"repeat");if(0>a||1342177279<a)throw new RangeError("Invalid count value");a|=0;for(var l="";a;)if(a&1&&(l+=g),a>>>=1)g+=g;return l}},"es6-impl","es3");
vrmlParser=function(){function a(g,e,l,k){this.message=g;this.expected=e;this.found=l;this.location=k;this.name="SyntaxError";"function"===typeof Error.captureStackTrace&&Error.captureStackTrace(this,a)}(function(a,e){function g(){this.constructor=a}g.prototype=e.prototype;a.prototype=new g})(a,Error);return{SyntaxError:a,parse:function(g){function e(b){var d=Q[b],c,a;if(!d){for(c=b-1;!Q[c];)c--;d=Q[c];for(d={line:d.line,column:d.column,seenCR:d.seenCR};c<b;)a=g.charAt(c),"\n"===a?(d.seenCR||d.line++,
d.column=1,d.seenCR=!1):"\r"===a||"\u2028"===a||"\u2029"===a?(d.line++,d.column=1,d.seenCR=!0):(d.column++,d.seenCR=!1),c++;Q[b]=d}return d}function l(b,B){var d=e(b),c=e(B);return{start:{offset:b,line:d.line,column:d.column},end:{offset:B,line:c.line,column:c.column}}}function k(b){c<I||(c>I&&(I=c,ba=[]),ba.push(b))}function y(){var d,B,a;d=c;g.substr(c,15)===ga?(B=ga,c+=15):(B=b,0===n&&k(Qa));if(B!==b){B=[];a=A();a===b&&(a=C(),a===b&&(a=q(),a===b&&(a=z(),a===b&&(a=w()))));for(;a!==b;)B.push(a),
a=A(),a===b&&(a=C(),a===b&&(a=q(),a===b&&(a=z(),a===b&&(a=w()))));B!==b?(x=d,B.nodeDefinitions=R,B.routes=M,d=B):(c=d,d=b)}else c=d,d=b;return d}function A(){var d,B,a,h;B=d=c;a=ha();a!==b?(a=t(),a!==b?(x=B,B=a):(c=B,B=b)):(c=B,B=b);if(B!==b)if(g.substr(c,23)===ia?(a=ia,c+=23):(a=b,0===n&&k(Ra)),a!==b)if(a=E(),a!==b){a=[];h=D();h===b&&(h=p());if(h!==b)for(;h!==b;)a.push(h),h=D(),h===b&&(h=p());else a=b;if(a!==b)if(h=ja(),h!==b){x=d;d=B;B=a;a={name:d,node:"OrientationInterpolator",isDefinition:!0};
for(h=0;h<B.length;h++)a[B[h].name]=B[h].value;d=R[d]=a}else c=d,d=b;else c=d,d=b}else c=d,d=b;else c=d,d=b;else c=d,d=b;return d}function D(){var d,a,f,h,e,q;d=c;a=v();a===b&&(a=null);if(a!==b)if(g.substr(c,8)===ka?(a=ka,c+=8):(a=b,0===n&&k(Sa)),a!==b)if(a=J(),a!==b){f=c;h=[];a=c;e=H();e!==b?(q=S(),q!==b?(x=a,a=e):(c=a,a=b)):(c=a,a=b);for(;a!==b;)h.push(a),a=c,e=H(),e!==b?(q=S(),q!==b?(x=a,a=e):(c=a,a=b)):(c=a,a=b);h!==b?(a=H(),a!==b?(x=f,f=h,f.push(a)):(c=f,f=b)):(c=f,f=b);f!==b?(h=G(),h!==b?(x=
d,d=a={name:"keyValue",value:f}):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b;else c=d,d=b;return d}function C(){var d,a,f,g;d=c;a=v();a!==b?(a=c,f=ha(),f!==b?(f=v(),f!==b?(f=t(),f!==b?(g=v(),g!==b?(x=a,a=f):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b),a!==b?(f=q(),f!==b?(x=d,d=a,a=f,a.name=d,a.isDefinition=!0,d=R[d]=a):(c=d,d=b)):(c=d,d=b)):(c=d,d=b);return d}function q(){var d,a,f,g;d=c;a=v();if(a!==b)if(f=t(),f!==b)if(a=E(),a!==b){a=[];g=C();g===b&&(g=w(),g===b&&(g=p(),g===b&&(g=q(),g===b&&(g=
z()))));for(;g!==b;)a.push(g),g=C(),g===b&&(g=w(),g===b&&(g=p(),g===b&&(g=q(),g===b&&(g=z()))));if(a!==b)if(g=ja(),g!==b)for(x=d,d={node:f},f=0;f<a.length;f++)g=a[f],void 0!==g.node?"Switch"===d.node?(void 0===d.choice&&(d.choice=[]),d.choice.push(g)):(void 0===d.children&&(d.children=[]),d.children.push(g)):void 0!==g.name?(d[g.name]=g.value,void 0!==g.comment&&(void 0===d.comments&&(d.comments={}),void 0===d.comments[g.name]&&(d.comments[g.name]=[]),d.comments[g.name].push(g.comment))):void 0!==
g.src?M.push(g):(void 0===d.nodeComments&&(d.nodeComments=[]),d.nodeComments.push(g));else c=d,d=b;else c=d,d=b}else c=d,d=b;else c=d,d=b;else c=d,d=b;return d}function p(){var d,a,f;d=c;a=v();a===b&&(a=null);a!==b?(g.substr(c,11)===la?(a=la,c+=11):(a=b,0===n&&k(Ta)),a===b&&(g.substr(c,8)===ma?(a=ma,c+=8):(a=b,0===n&&k(Ua)),a===b&&(g.substr(c,16)===na?(a=na,c+=16):(a=b,0===n&&k(Va)))),a!==b?(f=H(),f!==b?(x=d,d=a={name:a,value:f}):(c=d,d=b)):(c=d,d=b)):(c=d,d=b);if(d===b){d=c;g.substr(c,10)===oa?(a=
oa,c+=10):(a=b,0===n&&k(Wa));if(a!==b)if(a=v(),a===b&&(a=null),a!==b)if(a=J(),a!==b)if(a=z(),a===b&&(a=null),a!==b)if(a=v(),a===b&&(a=null),a!==b){a=[];f=ca();if(f!==b)for(;f!==b;)a.push(f),f=ca();else a=b;a!==b?(f=v(),f===b&&(f=null),f!==b?(f=z(),f===b&&(f=null),f!==b?(f=G(),f!==b?(f=v(),f===b&&(f=null),f!==b?(x=d,d=a={name:"coordIndex",value:a}):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b;else c=d,d=b;else c=d,d=b;else c=d,d=b;if(d===b&&(d=m(),d===b)){var h;d=
c;a=v();a===b&&(a=null);a!==b?(a=t(),a!==b?(f=v(),f!==b?(f=r(),f!==b?(h=v(),h!==b?(h=z(),h===b&&(h=null),h!==b?(x=d,d={name:a,value:f},null!==h&&(d.comment=h)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)}}return d}function H(){var d,a,f,h,e,q;d=c;a=v();a===b&&(a=null);if(a!==b)if(a=F(),a!==b){f=[];32===g.charCodeAt(c)?(h=K,c++):(h=b,0===n&&k(L));if(h!==b)for(;h!==b;)f.push(h),32===g.charCodeAt(c)?(h=K,c++):(h=b,0===n&&k(L));else f=b;if(f!==b)if(h=F(),h!==b){e=[];32===g.charCodeAt(c)?
(f=K,c++):(f=b,0===n&&k(L));if(f!==b)for(;f!==b;)e.push(f),32===g.charCodeAt(c)?(f=K,c++):(f=b,0===n&&k(L));else e=b;if(e!==b)if(f=F(),f!==b){q=[];32===g.charCodeAt(c)?(e=K,c++):(e=b,0===n&&k(L));if(e!==b)for(;e!==b;)q.push(e),32===g.charCodeAt(c)?(e=K,c++):(e=b,0===n&&k(L));else q=b;q!==b?(e=F(),e!==b?(q=v(),q===b&&(q=null),q!==b?(x=d,d=a={x:a,y:h,z:f,radians:e}):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b}else c=d,d=b;else c=d,d=b}else c=d,d=b;else c=d,d=b;return d}function m(){var d,
a,f,h;d=c;g.substr(c,5)===pa?(a=pa,c+=5):(a=b,0===n&&k(Xa));a===b&&(g.substr(c,6)===qa?(a=qa,c+=6):(a=b,0===n&&k(Ya)));if(a!==b)if(f=v(),f===b&&(f=null),f!==b)if(f=J(),f!==b)if(f=z(),f===b&&(f=null),f!==b)if(f=v(),f===b&&(f=null),f!==b){f=[];h=da();if(h!==b)for(;h!==b;)f.push(h),h=da();else f=b;f!==b?(h=z(),h===b&&(h=null),h!==b?(h=G(),h!==b?(h=v(),h===b&&(h=null),h!==b?(x=d,d=a={name:a,value:f}):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b;else c=d,d=b;else c=d,d=b;else c=
d,d=b;return d}function t(){var d,a,f;n++;d=c;a=v();a===b&&(a=null);if(a!==b){a=[];ra.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(sa));if(f!==b)for(;f!==b;)a.push(f),ra.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(sa));else a=b;a!==b?(f=v(),f===b&&(f=null),f!==b?(x=d,d=a=a.join("")):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;n--;d===b&&0===n&&k(Za);return d}function r(){var d;n++;var a;g.substr(c,5)===ta?(d=ta,c+=5):(d=b,0===n&&k($a));d===b&&(d=c,g.substr(c,5)===ua?(a=ua,c+=5):(a=b,0===n&&k(ab)),
a!==b&&(x=d,a=!1),d=a);if(d===b&&(d=A(),d===b&&(d=ca(),d===b&&(g.substr(c,4)===va?(d=va,c+=4):(d=b,0===n&&k(bb)),d===b&&(d=c,g.substr(c,4)===wa?(a=wa,c+=4):(a=b,0===n&&k(cb)),a!==b&&(x=d,a=null),d=a),d===b&&(g.substr(c,4)===xa?(d=xa,c+=4):(d=b,0===n&&k(db)),d===b&&(d=c,g.substr(c,4)===ya?(a=ya,c+=4):(a=b,0===n&&k(eb)),a!==b&&(x=d,a=!0),d=a),d===b&&(d=C(),d===b&&(d=q(),d===b&&(d=da(),d===b&&(d=m(),d===b&&(d=za(),d===b)))))))))){var f,h;d=c;a=v();a!==b?(a=F(),a!==b?(f=v(),f!==b?(f=F(),f!==b?(h=v(),
h!==b?(h=z(),h===b&&(h=null),h!==b?(x=d,d=a={x:a,y:f}):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b);if(d===b&&(d=c,a=v(),a!==b?(a=c,g.substr(c,3)===Aa?(f=Aa,c+=3):(f=b,0===n&&k(fb)),f!==b&&(x=a,f=!0),f!==b?(a=v(),a!==b?(a=t(),a!==b?(x=d,d=R[a],void 0===d?(console.log(a+" not found in nodeDefinitions"),a=d):a="function"===typeof d.clone?d.clone():d,d=a):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b),d===b)){var e;n++;a=c;d=J();if(d!==b){d=[];f=z();f===b&&(f=w(),f===b&&(f=c,h=r(),h!==
b?(e=v(),e!==b?(e=S(),e===b&&(e=null),e!==b?(x=f,f=h):(c=f,f=b)):(c=f,f=b)):(c=f,f=b)));for(;f!==b;)d.push(f),f=z(),f===b&&(f=w(),f===b&&(f=c,h=r(),h!==b?(e=v(),e!==b?(e=S(),e===b&&(e=null),e!==b?(x=f,f=h):(c=f,f=b)):(c=f,f=b)):(c=f,f=b)));if(d!==b)if(f=G(),f!==b)for(x=a,a=[],f=0;f<d.length;f++)h=d[f],void 0!==h.src?M.push(h):void 0!==h.comment?(void 0===a.comments&&(a.comments=[]),a.comments.push(h)):a.push(h);else c=a,a=b;else c=a,a=b}else c=a,a=b;n--;a===b&&0===n&&k(gb);d=a;if(d===b&&(d=F(),d===
b&&(d=t(),d===b))){d=c;a=v();if(a!==b)if(a=J(),a!==b)if(a=v(),a!==b)if(a=T(),a!==b){a=c;f=[];U.test(g.charAt(c))?(h=g.charAt(c),c++):(h=b,0===n&&k(V));for(;h!==b;)f.push(h),U.test(g.charAt(c))?(h=g.charAt(c),c++):(h=b,0===n&&k(V));f!==b?(46===g.charCodeAt(c)?(h=ea,c++):(h=b,0===n&&k(fa)),h!==b?(g.substr(c,3)===Ba?(e=Ba,c+=3):(e=b,0===n&&k(hb)),e===b&&(g.substr(c,4)===Ca?(e=Ca,c+=4):(e=b,0===n&&k(ib)),e===b&&(g.substr(c,3)===Da?(e=Da,c+=3):(e=b,0===n&&k(jb)),e===b&&(g.substr(c,3)===Ea?(e=Ea,c+=3):
(e=b,0===n&&k(kb))))),e!==b?(x=a,a=f+h+e):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);a!==b?(f=T(),f!==b?(f=v(),f!==b?(f=G(),f!==b?(f=v(),f!==b?(x=d,d=a):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b;else c=d,d=b;else c=d,d=b;if(d===b)if(d=c,a=v(),a!==b)if(a=T(),a!==b){a=[];U.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(V));for(;f!==b;)a.push(f),U.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(V));a!==b?(f=T(),f!==b?(f=v(),f!==b?(x=d,d=a=a.join("")):(c=d,d=b)):(c=
d,d=b)):(c=d,d=b)}else c=d,d=b;else c=d,d=b}}}n--;d===b&&0===n&&k(lb);return d}function F(){var a,e,f,h;n++;a=c;e=N();e===b&&(e=null);if(e!==b)if(e=c,f=u(),f!==b?(h=O(),h===b&&(h=null),h!==b?e=f=[f,h]:(c=e,e=b)):(c=e,e=b),e===b&&(e=O()),e!==b){var q,l;e=c;mb.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(nb));if(f!==b)if(h=N(),h===b&&(43===g.charCodeAt(c)?(h=ob,c++):(h=b,0===n&&k(pb))),h===b&&(h=null),h!==b){q=[];l=P();if(l!==b)for(;l!==b;)q.push(l),l=P();else q=b;q!==b?e=f=[f,h,q]:(c=e,e=b)}else c=
e,e=b;else c=e,e=b;f=e;f===b&&(f=null);f!==b?(x=a,a=e=parseFloat(g.substring(x,c))):(c=a,a=b)}else c=a,a=b;else c=a,a=b;n--;a===b&&0===n&&k(qb);return a}function O(){var a,e,f,h;a=c;46===g.charCodeAt(c)?(e=ea,c++):(e=b,0===n&&k(fa));if(e!==b){f=[];for(h=P();h!==b;)f.push(h),h=P();f!==b?a=e=[e,f]:(c=a,a=b)}else c=a,a=b;return a}function u(){var a,e,f;a=c;48===g.charCodeAt(c)?(e=rb,c++):(e=b,0===n&&k(sb));e===b&&(tb.test(g.charAt(c))?(e=g.charAt(c),c++):(e=b,0===n&&k(ub)));if(e!==b){var h,q;f=c;h=[];
for(q=P();q!==b;)h.push(q),q=P();h!==b&&(x=f,h=h.join(""));f=h;f!==b?(x=a,a=e+f):(c=a,a=b)}else c=a,a=b;return a}function N(){var a;45===g.charCodeAt(c)?(a=vb,c++):(a=b,0===n&&k(wb));return a}function z(){var a,e,f;a=c;e=v();if(e!==b)if(35===g.charCodeAt(c)?(e=xb,c++):(e=b,0===n&&k(yb)),e!==b){e=[];Fa.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(Ga));for(;f!==b;)e.push(f),Fa.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(Ga));e!==b?(f=v(),f!==b?(x=a,a=e={comment:e.join("").trim()}):(c=
a,a=b)):(c=a,a=b)}else c=a,a=b;else c=a,a=b;return a}function w(){var a,e,f,h;a=c;e=v();e!==b?(g.substr(c,5)===Ha?(e=Ha,c+=5):(e=b,0===n&&k(zb)),e!==b?(e=v(),e!==b?(e=W(),e!==b?(f=v(),f!==b?(g.substr(c,2)===Ia?(f=Ia,c+=2):(f=b,0===n&&k(Ab)),f!==b?(f=v(),f!==b?(f=W(),f!==b?(h=v(),h!==b?(x=a,a=e.name,e={source:e,target:f},"undefined"===typeof M[a]&&(M[a]=[]),M[a].push(e),a=e):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function W(){var a,
e,f;a=c;e=t();e!==b?(46===g.charCodeAt(c)?(f=ea,c++):(f=b,0===n&&k(fa)),f!==b?(f=t(),f!==b?(x=a,a=e={name:e,property:f}):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function J(){var a,e,f,h;a=c;e=v();e===b&&(e=null);e!==b?(91===g.charCodeAt(c)?(f=Bb,c++):(f=b,0===n&&k(Cb)),f!==b?(h=v(),h===b&&(h=null),h!==b?a=e=[e,f,h]:(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function G(){var a,e,f,h;a=c;e=v();e===b&&(e=null);e!==b?(93===g.charCodeAt(c)?(f=Db,c++):(f=b,0===n&&k(Eb)),f!==b?(h=v(),h===b&&(h=null),h!==
b?a=e=[e,f,h]:(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function E(){var a,e,f,h;a=c;e=v();e===b&&(e=null);e!==b?(123===g.charCodeAt(c)?(f=Fb,c++):(f=b,0===n&&k(Gb)),f!==b?(h=v(),h===b&&(h=null),h!==b?a=e=[e,f,h]:(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function ja(){var a,e,f,h;a=c;e=v();e===b&&(e=null);e!==b?(125===g.charCodeAt(c)?(f=Hb,c++):(f=b,0===n&&k(Ib)),f!==b?(h=v(),h===b&&(h=null),h!==b?a=e=[e,f,h]:(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function S(){var a,e,f,h;a=c;e=v();e===b&&(e=null);
e!==b?(44===g.charCodeAt(c)?(f=X,c++):(f=b,0===n&&k(Y)),f!==b?(h=v(),h===b&&(h=null),h!==b?a=e=[e,f,h]:(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function v(){var a,e,f;n++;a=c;e=[];Ja.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(Ka));for(;f!==b;)e.push(f),Ja.test(g.charAt(c))?(f=g.charAt(c),c++):(f=b,0===n&&k(Ka));e!==b&&(x=a,e=e.join(""));a=e;n--;a===b&&0===n&&k(Jb);return a}function da(){var a,e,f;a=c;e=za();e!==b?(44===g.charCodeAt(c)?(f=X,c++):(f=b,0===n&&k(Y)),f===b&&(f=null),f!==b?(f=
v(),f!==b?(f=z(),f===b&&(f=null),f!==b?(x=a,a=e):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function za(){var a,e,f,g,k;a=c;e=v();e===b&&(e=null);e!==b?(e=F(),e!==b?(f=v(),f!==b?(f=F(),f!==b?(g=v(),g!==b?(g=F(),g!==b?(k=v(),k!==b?(k=z(),k===b&&(k=null),k!==b?(x=a,a=e={x:e,y:f,z:g}):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function ha(){var a,e;a=c;e=v();e===b&&(e=null);e!==b?(g.substr(c,3)===La?(e=La,c+=3):(e=b,0===n&&k(Kb)),e!==b?(e=
v(),e===b&&(e=null),e!==b?(x=a,a=!0):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function ca(){var a,e,f;a=c;e=[];f=Ma();if(f!==b)for(;f!==b;)e.push(f),f=Ma();else e=b;e!==b?(g.substr(c,2)===Na?(f=Na,c+=2):(f=b,0===n&&k(Lb)),f!==b?(44===g.charCodeAt(c)?(f=X,c++):(f=b,0===n&&k(Y)),f===b&&(f=null),f!==b?(f=v(),f!==b?(x=a,a=e):(c=a,a=b)):(c=a,a=b)):(c=a,a=b)):(c=a,a=b);return a}function Ma(){var a,e,f,h,q,l;a=c;e=u();if(e!==b){f=c;h=v();h!==b?(44===g.charCodeAt(c)?(q=X,c++):(q=b,0===n&&k(Y)),q!==b?(32===
g.charCodeAt(c)?(l=K,c++):(l=b,0===n&&k(L)),l===b&&(l=null),l!==b?f=h=[h,q,l]:(c=f,f=b)):(c=f,f=b)):(c=f,f=b);if(f===b)if(f=[],32===g.charCodeAt(c)?(h=K,c++):(h=b,0===n&&k(L)),h!==b)for(;h!==b;)f.push(h),32===g.charCodeAt(c)?(h=K,c++):(h=b,0===n&&k(L));else f=b;f!==b?(x=a,a=e):(c=a,a=b)}else c=a,a=b;return a}function T(){var a;34===g.charCodeAt(c)?(a=Mb,c++):(a=b,0===n&&k(Nb));return a}function P(){var a;Ob.test(g.charAt(c))?(a=g.charAt(c),c++):(a=b,0===n&&k(Pb));return a}var Z=1<arguments.length?
arguments[1]:{},b={},Oa={vrml:y},Pa=y,ga="#VRML V2.0 utf8",Qa={type:"literal",value:"#VRML V2.0 utf8",description:'"#VRML V2.0 utf8"'},ia="OrientationInterpolator",Ra={type:"literal",value:"OrientationInterpolator",description:'"OrientationInterpolator"'},ka="keyValue",Sa={type:"literal",value:"keyValue",description:'"keyValue"'},la="orientation",Ta={type:"literal",value:"orientation",description:'"orientation"'},ma="rotation",Ua={type:"literal",value:"rotation",description:'"rotation"'},na="scaleOrientation",
Va={type:"literal",value:"scaleOrientation",description:'"scaleOrientation"'},K=" ",L={type:"literal",value:" ",description:'" "'},oa="coordIndex",Wa={type:"literal",value:"coordIndex",description:'"coordIndex"'},pa="point",Xa={type:"literal",value:"point",description:'"point"'},qa="vector",Ya={type:"literal",value:"vector",description:'"vector"'},Za={type:"other",description:"identifier"},ra=/^[A-Za-z0-9_]/,sa={type:"class",value:"[A-Za-z0-9_]",description:"[A-Za-z0-9_]"},gb={type:"other",description:"array"},
lb={type:"other",description:"value"},ta="false",$a={type:"literal",value:"false",description:'"false"'},ua="FALSE",ab={type:"literal",value:"FALSE",description:'"FALSE"'},va="null",bb={type:"literal",value:"null",description:'"null"'},wa="NULL",cb={type:"literal",value:"NULL",description:'"NULL"'},xa="true",db={type:"literal",value:"true",description:'"true"'},ya="TRUE",eb={type:"literal",value:"TRUE",description:'"TRUE"'},qb={type:"other",description:"number"},ea=".",fa={type:"literal",value:".",
description:'"."'},tb=/^[1-9]/,ub={type:"class",value:"[1-9]",description:"[1-9]"},mb=/^[eE]/,nb={type:"class",value:"[eE]",description:"[eE]"},vb="-",wb={type:"literal",value:"-",description:'"-"'},ob="+",pb={type:"literal",value:"+",description:'"+"'},rb="0",sb={type:"literal",value:"0",description:'"0"'},xb="#",yb={type:"literal",value:"#",description:'"#"'},Fa=/^[^\n]/,Ga={type:"class",value:"[^\\n]",description:"[^\\n]"},Ha="ROUTE",zb={type:"literal",value:"ROUTE",description:'"ROUTE"'},Ia="TO",
Ab={type:"literal",value:"TO",description:'"TO"'},Bb="[",Cb={type:"literal",value:"[",description:'"["'},Db="]",Eb={type:"literal",value:"]",description:'"]"'},Fb="{",Gb={type:"literal",value:"{",description:'"{"'},Hb="}",Ib={type:"literal",value:"}",description:'"}"'},X=",",Y={type:"literal",value:",",description:'","'},Jb={type:"other",description:"whitespace"},Ja=/^[ \t\n\r]/,Ka={type:"class",value:"[ \\t\\n\\r]",description:"[ \\t\\n\\r]"},La="DEF",Kb={type:"literal",value:"DEF",description:'"DEF"'},
Aa="USE",fb={type:"literal",value:"USE",description:'"USE"'},Na="-1",Lb={type:"literal",value:"-1",description:'"-1"'},U=/^[^"]/,V={type:"class",value:'[^"]',description:'[^"]'},Ba="jpg",hb={type:"literal",value:"jpg",description:'"jpg"'},Ca="jpeg",ib={type:"literal",value:"jpeg",description:'"jpeg"'},Da="gif",jb={type:"literal",value:"gif",description:'"gif"'},Ea="wrl",kb={type:"literal",value:"wrl",description:'"wrl"'},Mb='"',Nb={type:"literal",value:'"',description:'"\\""'},Ob=/^[0-9]/,Pb={type:"class",
value:"[0-9]",description:"[0-9]"},c=0,x=0,Q=[{line:1,column:1,seenCR:!1}],I=0,ba=[],n=0,aa;if("startRule"in Z){if(!(Z.startRule in Oa))throw Error("Can't start parsing from rule \""+Z.startRule+'".');Pa=Oa[Z.startRule]}var R={},M={};aa=Pa();if(aa!==b&&c===g.length)return aa;aa!==b&&c<g.length&&k({type:"end",description:"end of input"});throw function(b,c,e,g){function d(a){var b=1;for(a.sort(function(a,b){return a.description<b.description?-1:a.description>b.description?1:0});b<a.length;)a[b-1]===
a[b]?a.splice(b,1):b++}function f(a,b){function c(a){function b(a){return a.charCodeAt(0).toString(16).toUpperCase()}return a.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\x08/g,"\\b").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\f/g,"\\f").replace(/\r/g,"\\r").replace(/[\x00-\x07\x0B\x0E\x0F]/g,function(a){return"\\x0"+b(a)}).replace(/[\x10-\x1F\x80-\xFF]/g,function(a){return"\\x"+b(a)}).replace(/[\u0100-\u0FFF]/g,function(a){return"\\u0"+b(a)}).replace(/[\u1000-\uFFFF]/g,function(a){return"\\u"+
b(a)})}var d=Array(a.length),e;for(e=0;e<a.length;e++)d[e]=a[e].description;d=1<a.length?d.slice(0,-1).join(", ")+" or "+d[a.length-1]:d[0];e=b?'"'+c(b)+'"':"end of input";return"Expected "+d+" but "+e+" found."}null!==c&&d(c);return new a(null!==b?b:f(c,e),c,e,g)}(null,ba,I<g.length?g.charAt(I):null,I<g.length?l(I,I+1):l(I,I));}}}();var TWEEN=TWEEN||function(){var a=[];return{getAll:function(){return a},removeAll:function(){a=[]},add:function(g){a.push(g)},remove:function(g){g=a.indexOf(g);-1!==g&&a.splice(g,1)},update:function(g,e){if(0===a.length)return!1;var l=0;for(g=void 0!==g?g:TWEEN.now();l<a.length;)a[l].update(g)||e?l++:a.splice(l,1);return!0}}}();
(function(){TWEEN.now=void 0===this.window&&void 0!==this.process?function(){var a=process.hrtime();return 1E3*a[0]+a[1]/1E3}:void 0!==this.window&&void 0!==window.performance&&void 0!==window.performance.now?window.performance.now.bind(window.performance):void 0!==Date.now?Date.now:function(){return(new Date).getTime()}})();
TWEEN.Tween=function(a){var g={},e={},l={},k=1E3,y=0,A=!1,D=!1,C=0,q=null,p=TWEEN.Easing.Linear.None,H=TWEEN.Interpolation.Linear,m=[],t=null,r=!1,F=null,O=null,u=null,N;for(N in a)g[N]=parseFloat(a[N],10);this.to=function(a,g){void 0!==g&&(k=g);e=a;return this};this.start=function(k){TWEEN.add(this);D=!0;r=!1;q=void 0!==k?k:TWEEN.now();q+=C;for(var m in e){if(e[m]instanceof Array){if(0===e[m].length)continue;e[m]=[a[m]].concat(e[m])}void 0!==g[m]&&(g[m]=a[m],!1===g[m]instanceof Array&&(g[m]*=1),
l[m]=g[m]||0)}return this};this.stop=function(){if(!D)return this;TWEEN.remove(this);D=!1;null!==u&&u.call(a);this.stopChainedTweens();return this};this.stopChainedTweens=function(){for(var a=0,e=m.length;a<e;a++)m[a].stop()};this.delay=function(a){C=a;return this};this.repeat=function(a){y=a;return this};this.yoyo=function(a){A=a;return this};this.easing=function(a){p=a;return this};this.interpolation=function(a){H=a;return this};this.chain=function(){m=arguments;return this};this.onStart=function(a){t=
a;return this};this.onUpdate=function(a){F=a;return this};this.onComplete=function(a){O=a;return this};this.onStop=function(a){u=a;return this};this.update=function(u){var w,z,J;if(u<q)return!0;!1===r&&(null!==t&&t.call(a),r=!0);z=(u-q)/k;z=1<z?1:z;J=p(z);for(w in e)if(void 0!==g[w]){var G=g[w]||0,E=e[w];E instanceof Array?a[w]=H(E,J):("string"===typeof E&&(E="+"===E.charAt(0)||"-"===E.charAt(0)?G+parseFloat(E,10):parseFloat(E,10)),"number"===typeof E&&(a[w]=G+(E-G)*J))}null!==F&&F.call(a,J);if(1===
z)if(0<y){isFinite(y)&&y--;for(w in l)"string"===typeof e[w]&&(l[w]+=parseFloat(e[w],10)),A&&(z=l[w],l[w]=e[w],e[w]=z),g[w]=l[w];q=u+C}else{null!==O&&O.call(a);u=0;for(w=m.length;u<w;u++)m[u].start(q+k);return!1}return!0}};
TWEEN.Easing={Linear:{None:function(a){return a}},Quadratic:{In:function(a){return a*a},Out:function(a){return a*(2-a)},InOut:function(a){return 1>(a*=2)?.5*a*a:-.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return 1>(a*=2)?.5*a*a*a:.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return 1>(a*=2)?.5*a*a*a*a:-.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a*a*a},Out:function(a){return--a*
a*a*a*a+1},InOut:function(a){return 1>(a*=2)?.5*a*a*a*a*a:.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:1>(a*=2)?.5*Math.pow(1024,a-1):.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1-Math.sqrt(1-
a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return 1>(a*=2)?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){return 0===a?0:1===a?1:-Math.pow(2,10*(a-1))*Math.sin(5*(a-1.1)*Math.PI)},Out:function(a){return 0===a?0:1===a?1:Math.pow(2,-10*a)*Math.sin(5*(a-.1)*Math.PI)+1},InOut:function(a){if(0===a)return 0;if(1===a)return 1;a*=2;return 1>a?-.5*Math.pow(2,10*(a-1))*Math.sin(5*(a-1.1)*Math.PI):.5*Math.pow(2,-10*(a-1))*Math.sin(5*(a-1.1)*Math.PI)+
1}},Back:{In:function(a){return a*a*(2.70158*a-1.70158)},Out:function(a){return--a*a*(2.70158*a+1.70158)+1},InOut:function(a){return 1>(a*=2)?.5*a*a*(3.5949095*a-2.5949095):.5*((a-=2)*a*(3.5949095*a+2.5949095)+2)}},Bounce:{In:function(a){return 1-TWEEN.Easing.Bounce.Out(1-a)},Out:function(a){return a<1/2.75?7.5625*a*a:a<2/2.75?7.5625*(a-=1.5/2.75)*a+.75:a<2.5/2.75?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},InOut:function(a){return.5>a?.5*TWEEN.Easing.Bounce.In(2*a):.5*TWEEN.Easing.Bounce.Out(2*
a-1)+.5}}};
TWEEN.Interpolation={Linear:function(a,g){var e=a.length-1,l=e*g,k=Math.floor(l),y=TWEEN.Interpolation.Utils.Linear;return 0>g?y(a[0],a[1],l):1<g?y(a[e],a[e-1],e-l):y(a[k],a[k+1>e?e:k+1],l-k)},Bezier:function(a,g){for(var e=0,l=a.length-1,k=Math.pow,y=TWEEN.Interpolation.Utils.Bernstein,A=0;A<=l;A++)e+=k(1-g,l-A)*k(g,A)*a[A]*y(l,A);return e},CatmullRom:function(a,g){var e=a.length-1,l=e*g,k=Math.floor(l),y=TWEEN.Interpolation.Utils.CatmullRom;return a[0]===a[e]?(0>g&&(k=Math.floor(l=e*(1+g))),y(a[(k-
1+e)%e],a[k],a[(k+1)%e],a[(k+2)%e],l-k)):0>g?a[0]-(y(a[0],a[0],a[1],a[1],-l)-a[0]):1<g?a[e]-(y(a[e],a[e],a[e-1],a[e-1],l-e)-a[e]):y(a[k?k-1:0],a[k],a[e<k+1?e:k+1],a[e<k+2?e:k+2],l-k)},Utils:{Linear:function(a,g,e){return(g-a)*e+a},Bernstein:function(a,g){var e=TWEEN.Interpolation.Utils.Factorial;return e(a)/e(g)/e(a-g)},Factorial:function(){var a=[1];return function(g){var e=1;if(a[g])return a[g];for(var l=g;1<l;l--)e*=l;return a[g]=e}}(),CatmullRom:function(a,g,e,l,k){a=.5*(e-a);l=.5*(l-g);var y=
k*k;return(2*g-2*e+a+l)*k*y+(-3*g+3*e-2*a-l)*y+a*k+g}}};(function(a){"function"===typeof define&&define.amd?define([],function(){return TWEEN}):"undefined"!==typeof module&&"object"===typeof exports?module.exports=TWEEN:void 0!==a&&(a.TWEEN=TWEEN)})(this);/*
Bart McLeod 2016, mcleod@spaceweb.nl
@author Bart McLeod / http://spaceweb.nl/
*/
window.VrmlParser={};VrmlParser.Renderer={};VrmlParser.Renderer.ThreeJs=function(a){this.debug=a?!0:!1};
VrmlParser.Renderer.ThreeJs.prototype={debug:!1,REVISION:1,constructor:VrmlParser.Renderer.ThreeJs,log:function(){console.log.apply(console,arguments)},warn:function(){console.warn.apply(console,arguments)},error:function(){console.error.apply(console,arguments)},render:function(a,g){var e=this;console.log("VrmlParser.Renderer.ThreeJsRenderer "+this.REVISION);for(var l=function(a){return{r:a.x,g:a.y,b:a.z}},k=function(a,e,g,k,t){var q,m,p;q=t?1:-1;for(var u=["a","b","c","d"],y=[],z,w,H,A=0;A<g.length;A++){var G=
{};G.y=q*Math.cos(g[A])*e;G.x=q*Math.sin(g[A])*e;y.push(G)}for(A=0;A<a.faces.length;A++)for(g=a.faces[A],q=g instanceof THREE.Face3?3:4,G=0;G<q;G++){m=g[u[G]];m=a.vertices[m];for(var E=0;E<k.length;E++)if(w=0===E?t?e:-1*e:y[E-1].y,H=y[E],void 0!==H){if(p=t?m.y<=w&&m.y>H.y:m.y>=w&&m.y<H.y){z=k[E+1];p=k[E];w=Math.abs(m.y-w)/(w-H.y);var C=z;z=w;p=l(p);C=l(C);w=p.r-C.r;H=p.g-C.g;var C=p.b-C.b,D=new THREE.Color;D.r=p.r-z*w;D.g=p.g-z*H;D.b=p.b-z*C;p=D;g.vertexColors[G]=p}}else void 0===g.vertexColors[G]&&
(p=t?k.length-1:0,g.vertexColors[G]=l(k[p]))}},y=function(a){return"undefined"!==typeof this[a]&&null!==this[a]},A=function(a){if(void 0===a.node)return!1;a.has=y;var p=new THREE.Object3D,q=!1;switch(a.node){case "NavigationInfo":p=!1;(new VrmlParser.Renderer.ThreeJs.VrmlNode.NavigationInfo(a,e.debug)).parse(g);break;case "Viewpoint":q=(new VrmlParser.Renderer.ThreeJs.VrmlNode.Viewpoint(a,e.debug)).parse(g);p=q.getCamera();e.viewpoints[p.name]=q;break;case "OrientationInterpolator":case "PositionInterpolator":break;
case "Switch":p=0<=a.whichChoice&&a.whichChoice<a.choice.length?A(a.choice[a.whichChoice]):!1;break;case "Group":case "Transform":p=new THREE.Group;if(a.has("children"))if(a.children.has=y,a.children.has("node"))q=A(a.children),!1!==q&&p.add(q);else if(a.children.has("length"))for(var m=0;m<a.children.length;m++)q=a.children[m],q.has=y,q=A(q),!1!==q&&p.add(q);m={x:0,y:0,z:0};a.has("translation")&&(m=a.translation,p.position.set(m.x,m.y,m.z));var t={x:0,y:0,z:0,radians:0};a.has("rotation")&&(t=a.rotation);
if(a.has("scale")){var r=a.scale;p.scale.set(r.x,r.y,r.z)}q=new THREE.Group;a.has("center")||(a.center={x:0,y:0,z:0});r=a.center;q.position.set(m.x+r.x,m.y+r.y,m.z+r.z);p.position.set(0-r.x,0-r.y,0-r.z);q.quaternion.setFromAxisAngle(new THREE.Vector3(t.x,t.y,t.z),t.radians);q.add(p);break;case "Shape":var F=a.has("geometry")&&"IndexedLineSet"===a.geometry.node,C=a.has("geometry")&&"PointSet"===a.geometry.node,p=F?new THREE.Line:C?new THREE.Points({size:.01}):new THREE.Mesh;a.has("geometry")&&(p.geometry=
A(a.geometry));if(a.has("appearance")){t=a.appearance;t.has=y;if(t.has("material")){var u=t.material;u.has=y;F?(m=new THREE.LineBasicMaterial,u.has("color")&&(r=l(u.color),m.color.setRGB(r.r,r.g,r.b))):C?(u.has("diffuseColor")&&(r=l(u.diffuseColor)),u.has("emissiveColor")&&(r=l(u.emissiveColor)),m=new THREE.ShaderMaterial({vertexShader:"void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n\n\tgl_PointSize = 3.0;\n}",fragmentShader:"void main() {\n\tgl_FragColor = vec4( "+
r.r+", "+r.g+", "+r.b+", 1.0 );\n}"})):(m=new THREE.MeshPhongMaterial,u.has("diffuseColor")&&(r=l(u.diffuseColor),m.color.setRGB(r.r,r.g,r.b)),u.has("emissiveColor")&&(r=l(u.emissiveColor),m.emissive.setRGB(r.r,r.g,r.b)),u.has("specularColor")&&(r=l(u.specularColor),m.specular.setRGB(r.r,r.g,r.b)),u.has("transparency")&&(m.opacity=Math.abs(1-u.transparency),m.transparent=!0),t.has("texture")&&void 0!==t.texture.node&&"ImageTexture"===t.texture.node&&(t=t.texture.url[0],void 0!=t&&t&&(e.log("Loading image: "+
t),t=(new THREE.TextureLoader).load(t,function(a){void 0!==a.image&&a.repeat.set(a.image.height/a.image.width*2,2)}),t.wrapS=THREE.ClampToEdgeWrapping,t.wrapT=THREE.ClampToEdgeWrapping,e.log(t),m.map=t)))}p.material=m;"IndexedFaceSet"===a.geometry.node&&(p.material.side=THREE.DoubleSide)}break;case "Background":p=!1;m=2E4;t=new THREE.SphereGeometry(m,20,20);r=new THREE.MeshBasicMaterial({fog:!1,side:THREE.BackSide});1<a.skyColor.length?(k(t,m,a.skyAngle,a.skyColor,!0),r.vertexColors=THREE.VertexColors):
(m=l(a.skyColor[0]),r.color.setRGB(m.r,m.g,m.b));m=new THREE.Mesh(t,r);m.userData.originalVrmlNode=a;g.add(m);a.has("groundColor")&&(m=12E3,t=new THREE.SphereGeometry(m,20,20,0,2*Math.PI,.5*Math.PI,1.5*Math.PI),r=new THREE.MeshBasicMaterial({fog:!1,side:THREE.BackSide,vertexColors:THREE.VertexColors}),k(t,m,a.groundAngle,a.groundColor,!1),m=new THREE.Mesh(t,r),m.userData.originalVrmlNode=a,m.receiveShadow=!0,g.add(m));break;case "Box":r=a.size;p=new THREE.BoxGeometry(r.x,r.y,r.z);p.shading=THREE.SmoothShading;
break;case "Cylinder":p=new THREE.CylinderGeometry(a.radius,a.radius,a.height);break;case "Cone":p=new THREE.CylinderGeometry(a.topRadius,a.bottomRadius,a.height);break;case "Sphere":p=new THREE.SphereGeometry(a.radius);break;case "IndexedFaceSet":p=new THREE.Geometry;p.shading=THREE.SmoothShading;var D;a.has("texCoord")&&(t=a.texCoord.point);if(a.has("coord"))for(t||(t=a.coord.point),m=0,r=a.coord.point.length;m<r;m++)u=a.coord.point[m],u=new THREE.Vector3(u.x,u.y,u.z),p.vertices.push(u);var z=0;
if(a.has("coordIndex"))for(m=0,F=a.coordIndex.length;m<F;m++)for(u=a.coordIndex[m],D=a.has("texCoordIndex")?a.texCoordIndex[m]:u,z=0;3<=u.length&&z<u.length-2;){var w=u[0],W=u[z+(a.ccw?1:2)],r=u[z+(a.ccw?2:1)],r=new THREE.Face3(w,W,r,null);t&&D&&p.faceVertexUvs[0].push([new THREE.Vector2(t[D[0]].x,t[D[0]].y),new THREE.Vector2(t[D[z+(a.ccw?1:2)]].x,t[D[z+(a.ccw?1:2)]].y),new THREE.Vector2(t[D[z+(a.ccw?2:1)]].x,t[D[z+(a.ccw?2:1)]].y)]);z++;p.faces.push(r)}p.computeFaceNormals();p.computeBoundingSphere();
break;case "IndexedLineSet":p=new THREE.Geometry;t=[];if(a.has("coord"))for(m=0,r=a.coord.point.length;m<r;m++)u=a.coord.point[m],u=new THREE.Vector3(u.x,u.y,u.z),t.push(u);if(a.has("coordIndex")){m=0;for(F=a.coordIndex.length;m<F;m++)for(u=a.coordIndex[m],r=0;r<u.length;r++)w=u[r],w=t[w],p.vertices.push(new THREE.Vector3(w.x,w.y,w.z));p.computeBoundingSphere()}break;case "PointSet":p=new THREE.Geometry;if(a.has("coord"))for(m=0,r=a.coord.point.length;m<r;m++)u=a.coord.point[m],u=new THREE.Vector3(u.x,
u.y,u.z),p.vertices.push(u);p.computeBoundingSphere();break;case "TouchSensor":e.debug&&(p=new THREE.Mesh,p.geometry=new THREE.CubeGeometry(.1,.1,.1),p.material=new THREE.MeshNormalMaterial,p.material.color=new THREE.Color(.5,.5,.5));break;default:p=!1}!1!==p&&(void 0!==p.userData&&(p.userData.originalVrmlNode=a),""===p.name&&(a.has("name")?p.name=a.name:a.has("node")&&(p.name=a.node)),p.castShadow=!C,p.receiveShadow=!C);return!1!==q?(q.name="surrounding_"+p.name,q):p},D=0;D<a.length;D++){var C=A(a[D]);
!1!==C&&g.add(C)}g.userData.routes=a.routes;console.log(g)}};VrmlParser.Renderer.ThreeJs.Animation=function(a){this.debug=a?!0:!1;this.animations={}};
VrmlParser.Renderer.ThreeJs.Animation.prototype={update:function(a){for(var g in this.animations)if(this.animations.hasOwnProperty(g))(0,this.animations[g])(a)},addAnimation:function(a,g){this.animations[a]=g},removeAnimation:function(a){delete this.animations[a]},getRoutesForEvent:function(a){a=scene.userData.routes[a];for(var g=0;g<a.length;g++);return a},findTargetRoutes:function(a){var g=[];if("undefined"===typeof a)return g;var e=scene.userData.routes;if("undefined"===typeof e[a.target.name])return a;
a=e[a.target.name];for(e=0;e<a.length;e++){var l=this.findTargetRoutes(a[e]);g.push(l)}return g},log:function(a){this.debug&&console.log(a)},findSensor:function(a,g){if(null===a)return this.log("Cannot find a sensor of type "+g+" in null"),!1;var e;a:{if(void 0!==a.children)for(e=0;e<a.children.length;e++){var l=a.children[e];if(void 0!==l&&"undefined"!==typeof l.userData.originalVrmlNode&&g===l.userData.originalVrmlNode.node){e=l.name;this.log(g+": "+e);break a}}e=!1}if(e)return e;this.log("No "+
g+" found amongst the children of the following node:");this.log(a);if("undefined"===typeof a.parent||null===a.parent)return this.log("We cannot go up the tree any further"),!1;this.log("Searching up the tree");return this.findSensor(a.parent,g)},addClickSupport:function(a,g){projector=new THREE.Projector;var e=this;g.domElement.addEventListener("mousedown",function(l){var k=void 0==l.offsetX?l.layerX:l.offsetX;l=void 0==l.offsetY?l.layerY:l.offsetY;var y=new THREE.Vector3;y.set(k/g.domElement.width*
2-1,2*-(l/g.domElement.height)+1,.5);y.unproject(a);k=(new THREE.Raycaster(a.position,y.sub(a.position).normalize())).intersectObjects(scene.children,!0);if(k.length){var A=e.findSensor(k[0].object,"TouchSensor");if(!1!==A){k=e.getRoutesForEvent(A).slice(0);for(k=e.findTargetRoutes(k.pop());"function"===typeof k.pop;)if(k=k.pop(),"undefined"===typeof k){e.log("no target route found for "+A);return}e.log(k);l=scene.getObjectByName(k.source.name).userData.originalVrmlNode;void 0===VrmlParser.Renderer.ThreeJs.Animation[l.node]?
e.log(l.node+" is not yet supported"):(l=new VrmlParser.Renderer.ThreeJs.Animation[l.node](l,e.debug),k=scene.getObjectByName("surrounding_"+k.target.name),k=l.getCallback(k,function(){e.removeAnimation(A)}),e.addAnimation(A,k))}}},!1)}};VrmlParser.Renderer.ThreeJs.VrmlNode=VrmlParser.Renderer.ThreeJs.VrmlNode||{};VrmlParser.Renderer.ThreeJs.Animation.OrientationInterpolator=function(a,g){this.key=a.key;this.keyValue=a.keyValue;this.debug=g?!0:!1;this.index=1;this.tweenObj=this.target=this.finish=null};
VrmlParser.Renderer.ThreeJs.Animation.OrientationInterpolator.prototype={log:function(a){this.debug&&console.log(a)},complete:function(){this.index++;this.index>=this.keyValue.length?(this.log("finish at index "+this.index),this.finish()):this.tween()},tween:function(){var a=this,g=this.keyValue[this.index],e=g.radians;this.log("Animating from "+this.target.rotation.y+" to "+e);var l=new THREE.Quaternion,g=new THREE.Vector3(g.x,g.y,g.z);l.setFromAxisAngle(g,e);this.tweenObj=(new TWEEN.Tween(this.target.quaternion)).to(l).start(+new Date).onComplete(function(){a.complete()})},
getCallback:function(a,g){var e=this;this.target=a;this.finish=g;this.tween();return function(a){e.tweenObj.update(+new Date)}}};VrmlParser.Renderer.ThreeJs.Animation.PositionInterpolator=function(a,g){this.key=a.key;this.keyValue=a.keyValue;this.debug=g?!0:!1};
VrmlParser.Renderer.ThreeJs.Animation.PositionInterpolator.prototype={log:function(a){this.debug&&console.log(a)},tween:function(a,g){return(new TWEEN.Tween(a.position)).to(g).start(+new Date)},getCallback:function(a,g){var e=this,l=1,k=this.getPosition(l);this.log(k);this.log(a);var y=this.tween(a,k);y.onComplete(function(){l++;l>=e.keyValue.length?(console.log("finish"),a.position=k,g()):(k=e.getPosition(l),e.log(k),y=e.tween(a,k),y.onComplete=this)});return function(a){y.update(+new Date)}},getPosition:function(a){a=
this.keyValue[a];return new THREE.Vector3(a.x,a.y,a.z)}};VrmlParser.Renderer.ThreeJs.VrmlNode.NavigationInfo=function(a,g){this.debug=g;this.node=a;this.node.has=function(a){return"undefined"!==typeof this[a]&&null!==this[a]};this.controls=null};
VrmlParser.Renderer.ThreeJs.VrmlNode.NavigationInfo.prototype={log:function(a){this.debug&&console.log(a)},parse:function(a){this.log("From NavigationInfo");a=void 0!==this.node.speed?this.node.speed:1;if(void 0!==this.node.type)switch(this.node.type.toLowerCase()){case "fly":this.log("fly!"),controls=new THREE.FlyControls(camera),controls.movementSpeed=a}else this.log("fly!"),controls=new THREE.FlyControls(camera),controls.movementSpeed=a}};VrmlParser.Renderer.ThreeJs.VrmlNode.Viewpoint=function(a,g){this.debug=g;this.node=a;this.node.has=function(a){return"undefined"!==typeof this[a]&&null!==this[a]}};
VrmlParser.Renderer.ThreeJs.VrmlNode.Viewpoint.prototype={log:function(a){this.debug&&console.log(a)},parse:function(a){var g=new THREE.PerspectiveCamera(Math.round(180/Math.PI*this.node.fieldOfView),window.innerWidth/window.innerHeight,.01,1E5);a=new THREE.Group;a.add(g);this.node.has("name")?g.name=this.node.name:g.name=this.node.description;a.getCamera=function(){return this.children[0]};g=this.node.position;a.position.set(g.x,g.y,g.z);var g=this.node.orientation,e=new THREE.Vector3(g.x,g.y,g.z);
a.quaternion.setFromAxisAngle(e,g.radians);return a}};
/**
* @author mrdoob / http://mrdoob.com/
* @author Bart McLeod / http://spaceweb.nl/
*/
THREE.VRMLLoader = function ( manager ) {
/**
*
* @param manager
* @param parser VRMLparser based on PEG.js grammar
* @param VrmlParser.Renderer.ThreeJs renderer
* @constructor
*/
THREE.VRMLLoader = function (parser, manager, debug) {
this.manager = ( manager !== undefined ) ? manager : THREE.DefaultLoadingManager;
this.parser = parser;
this.debug = debug;
};
THREE.VRMLLoader.prototype = {
constructor: THREE.VRMLLoader,
// for IndexedFaceSet support
isRecordingPoints: false,
isRecordingFaces: false,
points: [],
indexes : [],
// for Background support
isRecordingAngles: false,
isRecordingColors: false,
angles: [],
colors: [],
recordingFieldname: null,
load: function ( url, onLoad, onProgress, onError ) {
var scope = this;
var loader = new THREE.FileLoader( this.manager );
loader.load( url, function ( text ) {
onLoad( scope.parse( text ) );
}, onProgress, onError );
},
setCrossOrigin: function ( value ) {
this.crossOrigin = value;
log: function (obj) {
if ( this.debug ) {
console.log(obj);
}
},
parse: function ( data ) {
var texturePath = this.texturePath || '';
var textureLoader = new THREE.TextureLoader( this.manager );
textureLoader.setCrossOrigin( this.crossOrigin );
var parseV1 = function ( lines, scene ) {
console.warn( 'VRML V1.0 not supported yet' );
};
var parseV2 = function ( lines, scene ) {
var defines = {};
var float_pattern = /(\b|\-|\+)([\d\.e]+)/;
var float2_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
var float3_pattern = /([\d\.\+\-e]+)\s+([\d\.\+\-e]+)\s+([\d\.\+\-e]+)/g;
/**
* Interpolates colors a and b following their relative distance
* expressed by t.
*
* @param float a
* @param float b
* @param float t
* @returns {Color}
*/
var interpolateColors = function( a, b, t ) {
var deltaR = a.r - b.r;
var deltaG = a.g - b.g;
var deltaB = a.b - b.b;
var c = new THREE.Color();
c.r = a.r - t * deltaR;
c.g = a.g - t * deltaG;
c.b = a.b - t * deltaB;
return c;
};
/**
* Vertically paints the faces interpolating between the
* specified colors at the specified angels. This is used for the Background
* node, but could be applied to other nodes with multiple faces as well.
*
* When used with the Background node, default is directionIsDown is true if
* interpolating the skyColor down from the Zenith. When interpolationg up from
* the Nadir i.e. interpolating the groundColor, the directionIsDown is false.
*
* The first angle is never specified, it is the Zenith (0 rad). Angles are specified
* in radians. The geometry is thought a sphere, but could be anything. The color interpolation
* is linear along the Y axis in any case.
*
* You must specify one more color than you have angles at the beginning of the colors array.
* This is the color of the Zenith (the top of the shape).
*
* @param geometry
* @param radius
* @param angles
* @param colors
* @param boolean directionIsDown Whether to work bottom up or top down.
*/
var paintFaces = function ( geometry, radius, angles, colors, directionIsDown ) {
var f, n, p, vertexIndex, color;
var direction = directionIsDown ? 1 : - 1;
var faceIndices = [ 'a', 'b', 'c', 'd' ];
var coord = [ ], aColor, bColor, t = 1, A = {}, B = {}, applyColor = false, colorIndex;
for ( var k = 0; k < angles.length; k ++ ) {
var vec = { };
// push the vector at which the color changes
vec.y = direction * ( Math.cos( angles[ k ] ) * radius );
vec.x = direction * ( Math.sin( angles[ k ] ) * radius );
coord.push( vec );
}
// painting the colors on the faces
for ( var i = 0; i < geometry.faces.length ; i ++ ) {
f = geometry.faces[ i ];
n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for ( var j = 0; j < n; j ++ ) {
vertexIndex = f[ faceIndices[ j ] ];
p = geometry.vertices[ vertexIndex ];
for ( var index = 0; index < colors.length; index ++ ) {
// linear interpolation between aColor and bColor, calculate proportion
// A is previous point (angle)
if ( index === 0 ) {
A.x = 0;
A.y = directionIsDown ? radius : - 1 * radius;
} else {
A.x = coord[ index - 1 ].x;
A.y = coord[ index - 1 ].y;
}
// B is current point (angle)
B = coord[ index ];
if ( undefined !== B ) {
// p has to be between the points A and B which we interpolate
applyColor = directionIsDown ? p.y <= A.y && p.y > B.y : p.y >= A.y && p.y < B.y;
if ( applyColor ) {
bColor = colors[ index + 1 ];
aColor = colors[ index ];
// below is simple linear interpolation
t = Math.abs( p.y - A.y ) / ( A.y - B.y );
// to make it faster, you can only calculate this if the y coord changes, the color is the same for points with the same y
color = interpolateColors( aColor, bColor, t );
f.vertexColors[ j ] = color;
}
} else if ( undefined === f.vertexColors[ j ] ) {
colorIndex = directionIsDown ? colors.length - 1 : 0;
f.vertexColors[ j ] = colors[ colorIndex ];
}
}
}
}
};
var index = [];
var parseProperty = function ( node, line ) {
var parts = [], part, property = {}, fieldName;
/**
* Expression for matching relevant information, such as a name or value, but not the separators
* @type {RegExp}
*/
var regex = /[^\s,\[\]]+/g;
var point, angles, colors;
while ( null != ( part = regex.exec( line ) ) ) {
parts.push( part[ 0 ] );
}
fieldName = parts[ 0 ];
// trigger several recorders
switch ( fieldName ) {
case 'skyAngle':
case 'groundAngle':
this.recordingFieldname = fieldName;
this.isRecordingAngles = true;
this.angles = [];
break;
case 'skyColor':
case 'groundColor':
this.recordingFieldname = fieldName;
this.isRecordingColors = true;
this.colors = [];
break;
case 'point':
this.recordingFieldname = fieldName;
this.isRecordingPoints = true;
this.points = [];
break;
case 'coordIndex':
case 'texCoordIndex':
this.recordingFieldname = fieldName;
this.isRecordingFaces = true;
this.indexes = [];
}
if ( this.isRecordingFaces ) {
// the parts hold the indexes as strings
if ( parts.length > 0 ) {
for ( var ind = 0; ind < parts.length; ind ++ ) {
// the part should either be positive integer or -1
if ( ! /(-?\d+)/.test( parts[ ind ] ) ) {
continue;
}
// end of current face
if ( parts[ ind ] === "-1" ) {
if ( index.length > 0 ) {
this.indexes.push( index );
}
// start new one
index = [];
} else {
index.push( parseInt( parts[ ind ] ) );
}
}
}
// end
if ( /]/.exec( line ) ) {
if ( index.length > 0 ) {
this.indexes.push( index );
}
// start new one
index = [];
this.isRecordingFaces = false;
node[this.recordingFieldname] = this.indexes;
}
} else if ( this.isRecordingPoints ) {
if ( node.nodeType == 'Coordinate' )
while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
point = {
x: parseFloat( parts[ 1 ] ),
y: parseFloat( parts[ 2 ] ),
z: parseFloat( parts[ 3 ] )
};
this.points.push( point );
}
if ( node.nodeType == 'TextureCoordinate' )
while ( null !== ( parts = float2_pattern.exec( line ) ) ) {
point = {
x: parseFloat( parts[ 1 ] ),
y: parseFloat( parts[ 2 ] )
};
this.points.push( point );
}
// end
if ( /]/.exec( line ) ) {
this.isRecordingPoints = false;
node.points = this.points;
}
} else if ( this.isRecordingAngles ) {
// the parts hold the angles as strings
if ( parts.length > 0 ) {
for ( var ind = 0; ind < parts.length; ind ++ ) {
// the part should be a float
if ( ! float_pattern.test( parts[ ind ] ) ) {
continue;
}
this.angles.push( parseFloat( parts[ ind ] ) );
}
}
// end
if ( /]/.exec( line ) ) {
this.isRecordingAngles = false;
node[ this.recordingFieldname ] = this.angles;
}
} else if ( this.isRecordingColors ) {
while ( null !== ( parts = float3_pattern.exec( line ) ) ) {
color = {
r: parseFloat( parts[ 1 ] ),
g: parseFloat( parts[ 2 ] ),
b: parseFloat( parts[ 3 ] )
};
this.colors.push( color );
}
// end
if ( /]/.exec( line ) ) {
this.isRecordingColors = false;
node[ this.recordingFieldname ] = this.colors;
}
} else if ( parts[ parts.length - 1 ] !== 'NULL' && fieldName !== 'children' ) {
switch ( fieldName ) {
case 'diffuseColor':
case 'emissiveColor':
case 'specularColor':
case 'color':
if ( parts.length != 4 ) {
console.warn( 'Invalid color format detected for ' + fieldName );
break;
}
property = {
r: parseFloat( parts[ 1 ] ),
g: parseFloat( parts[ 2 ] ),
b: parseFloat( parts[ 3 ] )
};
break;
case 'location':
case 'direction':
case 'translation':
case 'scale':
case 'size':
if ( parts.length != 4 ) {
console.warn( 'Invalid vector format detected for ' + fieldName );
break;
}
property = {
x: parseFloat( parts[ 1 ] ),
y: parseFloat( parts[ 2 ] ),
z: parseFloat( parts[ 3 ] )
};
break;
case 'intensity':
case 'cutOffAngle':
case 'radius':
case 'topRadius':
case 'bottomRadius':
case 'height':
case 'transparency':
case 'shininess':
case 'ambientIntensity':
if ( parts.length != 2 ) {
console.warn( 'Invalid single float value specification detected for ' + fieldName );
break;
}
property = parseFloat( parts[ 1 ] );
break;
case 'rotation':
if ( parts.length != 5 ) {
console.warn( 'Invalid quaternion format detected for ' + fieldName );
break;
}
property = {
x: parseFloat( parts[ 1 ] ),
y: parseFloat( parts[ 2 ] ),
z: parseFloat( parts[ 3 ] ),
w: parseFloat( parts[ 4 ] )
};
break;
case 'on':
case 'ccw':
case 'solid':
case 'colorPerVertex':
case 'convex':
if ( parts.length != 2 ) {
console.warn( 'Invalid format detected for ' + fieldName );
break;
}
property = parts[ 1 ] === 'TRUE' ? true : false;
break;
}
node[ fieldName ] = property;
}
return property;
};
var getTree = function ( lines ) {
var tree = { 'string': 'Scene', children: [] };
var current = tree;
var matches;
var specification;
for ( var i = 0; i < lines.length; i ++ ) {
var comment = '';
var line = lines[ i ];
// omit whitespace only lines
if ( null !== ( result = /^\s+?$/g.exec( line ) ) ) {
continue;
}
line = line.trim();
// skip empty lines
if ( line === '' ) {
continue;
}
if ( /#/.exec( line ) ) {
var parts = line.split( '#' );
// discard everything after the #, it is a comment
line = parts[ 0 ];
// well, let's also keep the comment
comment = parts[ 1 ];
}
if ( matches = /([^\s]*){1}(?:\s+)?{/.exec( line ) ) {
// first subpattern should match the Node name
var block = { 'nodeType' : matches[ 1 ], 'string': line, 'parent': current, 'children': [], 'comment' : comment };
current.children.push( block );
current = block;
if ( /}/.exec( line ) ) {
// example: geometry Box { size 1 1 1 } # all on the same line
specification = /{(.*)}/.exec( line )[ 1 ];
// todo: remove once new parsing is complete?
block.children.push( specification );
parseProperty( current, specification );
current = current.parent;
}
} else if ( /}/.exec( line ) ) {
parse: function (data) {
try {
var tree = this.parser.parse(data);
current = current.parent;
this.log(tree);
return tree;
} catch ( e ) {
this.log('Exception with message ' + e.message);
} else if ( line !== '' ) {
parseProperty( current, line );
// todo: remove once new parsing is complete? we still do not parse geometry and appearance the new way
current.children.push( line );
}
}
return tree;
};
var parseNode = function ( data, parent ) {
// console.log( data );
if ( typeof data === 'string' ) {
if ( /USE/.exec( data ) ) {
var defineKey = /USE\s+?([^\s]+)/.exec( data )[ 1 ];
if ( undefined == defines[ defineKey ] ) {
console.warn( defineKey + ' is not defined.' );
} else {
if ( /appearance/.exec( data ) && defineKey ) {
parent.material = defines[ defineKey ].clone();
} else if ( /geometry/.exec( data ) && defineKey ) {
parent.geometry = defines[ defineKey ].clone();
// the solid property is not cloned with clone(), is only needed for VRML loading, so we need to transfer it
if ( undefined !== defines[ defineKey ].solid && defines[ defineKey ].solid === false ) {
parent.geometry.solid = false;
parent.material.side = THREE.DoubleSide;
}
} else if ( defineKey ) {
var object = defines[ defineKey ].clone();
parent.add( object );
}
}
}
return;
}
var object = parent;
if(data.string.indexOf("AmbientLight")>-1 && data.nodeType=='PointLight'){
//wenn im Namen "AmbientLight" vorkommt und es ein PointLight ist,
//diesen Typ in 'AmbientLight' ändern
data.nodeType='AmbientLight';
}
l_visible=data.on;
if(l_visible==undefined)l_visible=true;
l_intensity=data.intensity;
if(l_intensity==undefined)l_intensity=true;
if(data.color!=undefined)
l_color= new THREE.Color(data.color.r, data.color.g,data.color.b );
else
l_color= new THREE.Color(0, 0,0);
if('AmbientLight' === data.nodeType){
object=new THREE.AmbientLight(
l_color.getHex(),
l_intensity
);
object.visible=l_visible;
parent.add( object );
}
else
if('PointLight' === data.nodeType){
l_distance =0; //0="unendlich" ...1000
l_decay=0; //-1.. ?
if(data.radius!=undefined && data.radius<1000){
//l_radius=data.radius;
l_distance=data.radius;
l_decay=1;
}
object=new THREE.PointLight(
l_color.getHex(),
l_intensity,
l_distance);
object.visible=l_visible;
parent.add( object );
}
else
if('SpotLight' === data.nodeType){
l_intensity=1;
l_distance =0;//0="unendlich"=1000
l_angle=Math.PI/3;
l_penumbra=0.0;//0..1
l_decay=0;//-1.. ?
l_visible=true;
if(data.radius!=undefined && data.radius<1000){
//l_radius=data.radius;
l_distance=data.radius;
l_decay=1;
}
if(data.cutOffAngle!=undefined)l_angle=data.cutOffAngle;
object = new THREE.SpotLight(
l_color.getHex(),
l_intensity,
l_distance,
l_angle,
l_penumbra,
l_decay
);
object.visible=l_visible;
parent.add( object );
/*
var lightHelper = new THREE.SpotLightHelper( object );
parent.parent.add( lightHelper );
lightHelper.update();
*/
}
else
if ( 'Transform' === data.nodeType || 'Group' === data.nodeType ) {
object = new THREE.Object3D();
if ( /DEF/.exec( data.string ) ) {
object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
defines[ object.name ] = object;
}
if ( undefined !== data[ 'translation' ] ) {
var t = data.translation;
object.position.set( t.x, t.y, t.z );
}
if ( undefined !== data.rotation ) {
var r = data.rotation;
object.quaternion.setFromAxisAngle( new THREE.Vector3( r.x, r.y, r.z ), r.w );
}
if ( undefined !== data.scale ) {
var s = data.scale;
object.scale.set( s.x, s.y, s.z );
}
parent.add( object );
} else if ( 'Shape' === data.nodeType ) {
object = new THREE.Mesh();
if ( /DEF/.exec( data.string ) ) {
object.name = /DEF\s+([^\s]+)/.exec( data.string )[ 1 ];
defines[ object.name ] = object;
}
parent.add( object );
} else if ( 'Background' === data.nodeType ) {
var segments = 20;
// sky (full sphere):
var radius = 2e4;
var skyGeometry = new THREE.SphereGeometry( radius, segments, segments );
var skyMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide } );
if ( data.skyColor.length > 1 ) {
paintFaces( skyGeometry, radius, data.skyAngle, data.skyColor, true );
skyMaterial.vertexColors = THREE.VertexColors
} else {
var color = data.skyColor[ 0 ];
skyMaterial.color.setRGB( color.r, color.b, color.g );
}
scene.add( new THREE.Mesh( skyGeometry, skyMaterial ) );
// ground (half sphere):
if ( data.groundColor !== undefined ) {
radius = 1.2e4;
var groundGeometry = new THREE.SphereGeometry( radius, segments, segments, 0, 2 * Math.PI, 0.5 * Math.PI, 1.5 * Math.PI );
var groundMaterial = new THREE.MeshBasicMaterial( { fog: false, side: THREE.BackSide, vertexColors: THREE.VertexColors } );
paintFaces( groundGeometry, radius, data.groundAngle, data.groundColor, false );
scene.add( new THREE.Mesh( groundGeometry, groundMaterial ) );
}
} else if ( /geometry/.exec( data.string ) ) {
if ( 'Box' === data.nodeType ) {
var s = data.size;
parent.geometry = new THREE.BoxGeometry( s.x, s.y, s.z );
} else if ( 'Cylinder' === data.nodeType ) {
parent.geometry = new THREE.CylinderGeometry( data.radius, data.radius, data.height );
} else if ( 'Cone' === data.nodeType ) {
parent.geometry = new THREE.CylinderGeometry( data.topRadius, data.bottomRadius, data.height );
} else if ( 'Sphere' === data.nodeType ) {
parent.geometry = new THREE.SphereGeometry( data.radius );
} else if ( 'IndexedFaceSet' === data.nodeType ) {
var geometry = new THREE.Geometry();
var indexes, uvIndexes, uvs;
for ( var i = 0, j = data.children.length; i < j; i ++ ) {
var child = data.children[ i ];
var vec;
if ( 'TextureCoordinate' === child.nodeType ) {
uvs = child.points;
}
if ( 'Coordinate' === child.nodeType ) {
if ( child.points ) {
for ( var k = 0, l = child.points.length; k < l; k ++ ) {
var point = child.points[ k ];
vec = new THREE.Vector3( point.x, point.y, point.z );
geometry.vertices.push( vec );
}
}
if ( child.string.indexOf ( 'DEF' ) > -1 ) {
var name = /DEF\s+([^\s]+)/.exec( child.string )[ 1 ];
defines[ name ] = geometry.vertices;
}
if ( child.string.indexOf ( 'USE' ) > -1 ) {
var defineKey = /USE\s+([^\s]+)/.exec( child.string )[ 1 ];
geometry.vertices = defines[ defineKey ];
}
}
}
var skip = 0;
// some shapes only have vertices for use in other shapes
if ( data.coordIndex ) {
// read this: http://math.hws.edu/eck/cs424/notes2013/16_Threejs_Advanced.html
for ( var i = 0, j = data.coordIndex.length; i < j; i ++ ) {
indexes = data.coordIndex[ i ]; if ( data.texCoordIndex ) uvIndexes = data.texCoordIndex[ i ];
// vrml support multipoint indexed face sets (more then 3 vertices). You must calculate the composing triangles here
skip = 0;
// Face3 only works with triangles, but IndexedFaceSet allows shapes with more then three vertices, build them of triangles
while ( indexes.length >= 3 && skip < ( indexes.length - 2 ) ) {
var face = new THREE.Face3(
indexes[ 0 ],
indexes[ skip + (data.ccw ? 1 : 2) ],
indexes[ skip + (data.ccw ? 2 : 1) ],
null // normal, will be added later
// todo: pass in the color, if a color index is present
);
if ( uvs && uvIndexes ) {
geometry.faceVertexUvs [0].push( [
new THREE.Vector2 (
uvs[ uvIndexes[ 0 ] ].x ,
uvs[ uvIndexes[ 0 ] ].y
) ,
new THREE.Vector2 (
uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].x ,
uvs[ uvIndexes[ skip + (data.ccw ? 1 : 2) ] ].y
) ,
new THREE.Vector2 (
uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].x ,
uvs[ uvIndexes[ skip + (data.ccw ? 2 : 1) ] ].y
)
] );
}
skip ++;
geometry.faces.push( face );
}
}
} else {
// do not add dummy mesh to the scene
parent.parent.remove( parent );
}
if ( false === data.solid ) {
parent.material.side = THREE.DoubleSide;
}
// we need to store it on the geometry for use with defines
geometry.solid = data.solid;
geometry.computeFaceNormals();
//geometry.computeVertexNormals(); // does not show
geometry.computeBoundingSphere();
// see if it's a define
if ( /DEF/.exec( data.string ) ) {
geometry.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
defines[ geometry.name ] = geometry;
}
parent.geometry = geometry;
}
return;
} else if ( /appearance/.exec( data.string ) ) {
for ( var i = 0; i < data.children.length; i ++ ) {
var child = data.children[ i ];
if ( 'Material' === child.nodeType ) {
var material = new THREE.MeshPhongMaterial();
if ( undefined !== child.diffuseColor ) {
var d = child.diffuseColor;
material.color.setRGB( d.r, d.g, d.b );
}
if ( undefined !== child.emissiveColor ) {
var e = child.emissiveColor;
material.emissive.setRGB( e.r, e.g, e.b );
}
if ( undefined !== child.specularColor ) {
var s = child.specularColor;
material.specular.setRGB( s.r, s.g, s.b );
}
if ( undefined !== child.transparency ) {
var t = child.transparency;
// transparency is opposite of opacity
material.opacity = Math.abs( 1 - t );
material.transparent = true;
}
if ( /DEF/.exec( data.string ) ) {
material.name = /DEF ([^\s]+)/.exec( data.string )[ 1 ];
defines[ material.name ] = material;
}
parent.material = material;
}
if ( 'ImageTexture' === child.nodeType ) {
var textureName = /"([^"]+)"/.exec(child.children[ 0 ]);
if (textureName) {
parent.material.name = textureName[ 1 ];
parent.material.map = textureLoader.load( texturePath + textureName[ 1 ] );
}
}
}
return;
}
for ( var i = 0, l = data.children.length; i < l; i ++ ) {
var child = data.children[ i ];
parseNode( data.children[ i ], object );
}
};
parseNode( getTree( lines ), scene );
};
var scene = new THREE.Scene();
var lines = data.split( '\n' );
// some lines do not have breaks
for (var i = lines.length -1; i > -1; i--) {
// split lines with {..{ or {..[ - some have both
if (/{.*[{\[]/.test (lines[i])) {
var parts = lines[i].split ('{').join ('{\n').split ('\n');
parts.unshift(1);
parts.unshift(i);
lines.splice.apply(lines, parts);
} else
// split lines with ]..}
if (/\].*}/.test (lines[i])) {
var parts = lines[i].split (']').join (']\n').split ('\n');
parts.unshift(1);
parts.unshift(i);
lines.splice.apply(lines, parts);
}
// split lines with }..}
if (/}.*}/.test (lines[i])) {
var parts = lines[i].split ('}').join ('}\n').split ('\n');
parts.unshift(1);
parts.unshift(i);
lines.splice.apply(lines, parts);
if ( undefined !== e.location ) {
this.log('Exception at location start: offset: ' + e.location.start.offset + ' line: ' + e.location.start.line + ' column: ' + e.location.start.column);
this.log('Exception at location end: offset: ' + e.location.end.offset + ' line: ' + e.location.end.line + ' column: ' + e.location.end.column);
}
// force the parser to create Coordinate node for empty coords
// coord USE something -> coord USE something Coordinate {}
if((lines[i].indexOf ('coord') > -1) && (lines[i].indexOf ('[') < 0) && (lines[i].indexOf ('{') < 0)) {
lines[i] += ' Coordinate {}';
}
return;
}
},
var header = lines.shift();
load: function (url, onLoad, onProgress, onError) {
if ( /V1.0/.exec( header ) ) {
var scope = this;
parseV1( lines, scene );
var loader = new THREE.FileLoader(this.manager);
loader.load(url, function (text) {
} else if ( /V2.0/.exec( header ) ) {
onLoad(scope.parse(text));
parseV2( lines, scene );
}, onProgress, onError);
}
},
return scene;
setCrossOrigin: function (value) {
}
this.crossOrigin = value;
},
};
因为 它太大了无法显示 source diff 。你可以改为 查看blob
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js webgl - loaders - vrml loader</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
<head>
<title>VRML loading with ThreeJs and VrmlParser</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #000;
color: #fff;
margin: 0px;
overflow: hidden;
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display: block;
}
#info a, .button {
color: #f00;
font-weight: bold;
text-decoration: underline;
cursor: pointer
}
#viewpoints {
background-color: gray;
z-index: 101;
position: absolute;
width: 140px;
top: 10px;
left: 10px;
padding: 2px;
border: 1px solid white;
}
#viewpoints div {
width: inherit;
}
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js / VrmlParser</a> -
vrml format loader test using VrmlParser -
</div>
<div id="viewpoints">
<h4>Viewpoints from the VRML file</h4>
</div>
<script src="../build/three.min.js"></script>
<script src="js/libs/vrml.min.js"></script>
<script src="js/loaders/VRMLLoader.js"></script>
<script src="js/renderers/Projector.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/controls/FlyControls.js"></script>
<script src="js/controls/FirstPersonControls.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script>
var container;
var camera, controls, scene, renderer, dirLight;
var animation;
// setup a clock
var clock = new THREE.Clock();
init();
animate();
function resetControls() {
controls = new THREE.FlyControls(camera);
controls.rotateSpeed = 1;
controls.zoomSpeed = 0.2;
controls.panSpeed = 0.2;
controls.enableZoom = true;
controls.enablePan = true;
}
function setupLight() {
if ( ! dirLight ) {
dirLight = new THREE.DirectionalLight(0xaaaaaa);
dirLight.position.set(500, 500, 1000).normalize();
dirLight.castShadow = false;
}
camera.add(dirLight);
camera.add(dirLight.target);
}
function selectViewpoint(event, vrmlConverter) {
var viewpoint = event.target.dataset.name;
console.log('clicked ' + viewpoint);
camera = vrmlConverter.viewpoints[ viewpoint ].getCamera();
setupLight();
resetControls();
animation.addClickSupport(camera, renderer);
}
function init() {
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.01, 1e5);
camera.position.z = 4;
camera.position.y = 3;
camera.position.x = 0;
scene = new THREE.Scene();
scene.fog = new THREE.Fog(0xffffff, 1, 5000);
scene.fog.color.setHSL(0.6, 0, 1);
scene.add(camera);
setupLight();
resetControls();
var debug = true;
var vrmlConverter = new VrmlParser.Renderer.ThreeJs(debug);
// renderer
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.shadowMap.enabled = true;
renderer.setClearColor(0x000000, 1);
renderer.setSize(window.innerWidth, window.innerHeight);
// add support for animation and interaction
animation = new VrmlParser.Renderer.ThreeJs.Animation(debug);
animation.addClickSupport(camera, renderer);
// initialize the viewpoinst with the camera from the global scope
vrmlConverter.viewpoints = {
reset: {
getCamera: function () {
return this.camera;
}, name: 'surrounding_reset', camera: camera
}
#info {
color: #fff;
position: absolute;
top: 10px;
width: 100%;
text-align: center;
z-index: 100;
display:block;
}
#info a, .button { color: #f00; font-weight: bold; text-decoration: underline; cursor: pointer }
</style>
</head>
<body>
<div id="info">
<a href="http://threejs.org" target="_blank">three.js</a> -
vrml format loader test -
<!--model from <a href="http://cs.iupui.edu/~aharris/webDesign/vrml/" target="_blank">VRML 2.0 Tutorial</a>,-->
</div>
<script src="../build/three.js"></script>
<script src="js/controls/OrbitControls.js"></script>
<script src="js/loaders/VRMLLoader.js"></script>
<script src="js/Detector.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
if ( ! Detector.webgl ) Detector.addGetWebGLMessage();
var container, stats;
var camera, controls, scene, renderer;
var cross;
init();
animate();
function init() {
camera = new THREE.PerspectiveCamera( 60, window.innerWidth / window.innerHeight, 0.01, 1e10 );
camera.position.z = 6;
}; // key value store of cameras based on VRML viewpoint nodes, stored by their name.
controls = new THREE.OrbitControls( camera );
var vrmlLoader = new THREE.VRMLLoader(vrmlParser, new THREE.LoadingManager(), true);
controls.rotateSpeed = 5.0;
controls.zoomSpeed = 5;
var onLoad = function (vrmlTree) {
vrmlConverter.render(vrmlTree, scene);
scene = new THREE.Scene();
scene.add( camera );
var viewpointSelector = document.getElementById('viewpoints');
// light
var dirLight = new THREE.DirectionalLight( 0xffffff );
dirLight.position.set( 200, 200, 1000 ).normalize();
camera.add( dirLight );
camera.add( dirLight.target );
var loader = new THREE.VRMLLoader();
loader.load( 'models/vrml/house.wrl', function ( object ) {
scene.add( object );
} );
// renderer
renderer = new THREE.WebGLRenderer( { antialias: false } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
stats = new Stats();
container.appendChild( stats.dom );
//
for ( a in vrmlConverter.viewpoints ) {
if ( typeof a === 'string' ) {
var option = document.createElement('div');
option.innerHTML = a;
option.setAttribute('data-name', a);
viewpointSelector.appendChild(option);
option.addEventListener('click', function (event) {
selectViewpoint(event, vrmlConverter);
});
}
}
window.addEventListener( 'resize', onWindowResize, false );
};
var onError = function (error) {
var request = error.target;
if ( 404 === request.status ) {
console.log('VRML Document not found at ' + request.responseURL);
}
console.log(error);
}
function onWindowResize() {
var onProgress = function () {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
renderer.setSize( window.innerWidth, window.innerHeight );
vrmlLoader.load('models/vrml/house.wrl', onLoad, onProgress, onError);
controls.handleResize();
container = document.createElement('div');
document.body.appendChild(container);
container.appendChild(renderer.domElement);
}
function animate() {
//
requestAnimationFrame( animate );
window.addEventListener('resize', onWindowResize, false);
controls.update();
renderer.render( scene, camera );
}
stats.update();
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
}
function animate() {
requestAnimationFrame(animate);
var delta = clock.getDelta();
if ( undefined !== controls ) {
controls.update(delta);
}
animation.update(delta);
renderer.render(scene, camera);
}
</script>
</script>
</body>
</body>
</html>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册