"!==l[1]||kb.test(f)?0:h:h.firstChild,e=f&&f.childNodes.length;while(e--)m.nodeName(j=f.childNodes[e],"tbody")&&!j.childNodes.length&&f.removeChild(j)}m.merge(p,h.childNodes),h.textContent="";while(h.firstChild)h.removeChild(h.firstChild);h=o.lastChild}else p.push(b.createTextNode(f));h&&o.removeChild(h),k.appendChecked||m.grep(ub(p,"input"),vb),q=0;while(f=p[q++])if((!d||-1===m.inArray(f,d))&&(g=m.contains(f.ownerDocument,f),h=ub(o.appendChild(f),"script"),g&&zb(h),c)){e=0;while(f=h[e++])ob.test(f.type||"")&&c.push(f)}return h=null,o},cleanData:function(a,b){for(var d,e,f,g,h=0,i=m.expando,j=m.cache,l=k.deleteExpando,n=m.event.special;null!=(d=a[h]);h++)if((b||m.acceptData(d))&&(f=d[i],g=f&&j[f])){if(g.events)for(e in g.events)n[e]?m.event.remove(d,e):m.removeEvent(d,e,g.handle);j[f]&&(delete j[f],l?delete d[i]:typeof d.removeAttribute!==K?d.removeAttribute(i):d[i]=null,c.push(f))}}}),m.fn.extend({text:function(a){return V(this,function(a){return void 0===a?m.text(this):this.empty().append((this[0]&&this[0].ownerDocument||y).createTextNode(a))},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=wb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?m.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||m.cleanData(ub(c)),c.parentNode&&(b&&m.contains(c.ownerDocument,c)&&zb(ub(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++){1===a.nodeType&&m.cleanData(ub(a,!1));while(a.firstChild)a.removeChild(a.firstChild);a.options&&m.nodeName(a,"select")&&(a.options.length=0)}return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return m.clone(this,a,b)})},html:function(a){return V(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a)return 1===b.nodeType?b.innerHTML.replace(fb,""):void 0;if(!("string"!=typeof a||mb.test(a)||!k.htmlSerialize&&gb.test(a)||!k.leadingWhitespace&&hb.test(a)||rb[(jb.exec(a)||["",""])[1].toLowerCase()])){a=a.replace(ib,"<$1>$2>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(m.cleanData(ub(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,m.cleanData(ub(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,n=this,o=l-1,p=a[0],q=m.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&nb.test(p))return this.each(function(c){var d=n.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(i=m.buildFragment(a,this[0].ownerDocument,!1,this),c=i.firstChild,1===i.childNodes.length&&(i=c),c)){for(g=m.map(ub(i,"script"),xb),f=g.length;l>j;j++)d=i,j!==o&&(d=m.clone(d,!0,!0),f&&m.merge(g,ub(d,"script"))),b.call(this[j],d,j);if(f)for(h=g[g.length-1].ownerDocument,m.map(g,yb),j=0;f>j;j++)d=g[j],ob.test(d.type||"")&&!m._data(d,"globalEval")&&m.contains(h,d)&&(d.src?m._evalUrl&&m._evalUrl(d.src):m.globalEval((d.text||d.textContent||d.innerHTML||"").replace(qb,"")));i=c=null}return this}}),m.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){m.fn[a]=function(a){for(var c,d=0,e=[],g=m(a),h=g.length-1;h>=d;d++)c=d===h?this:this.clone(!0),m(g[d])[b](c),f.apply(e,c.get());return this.pushStack(e)}});var Cb,Db={};function Eb(b,c){var d,e=m(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:m.css(e[0],"display");return e.detach(),f}function Fb(a){var b=y,c=Db[a];return c||(c=Eb(a,b),"none"!==c&&c||(Cb=(Cb||m("")).appendTo(b.documentElement),b=(Cb[0].contentWindow||Cb[0].contentDocument).document,b.write(),b.close(),c=Eb(a,b),Cb.detach()),Db[a]=c),c}!function(){var a;k.shrinkWrapBlocks=function(){if(null!=a)return a;a=!1;var b,c,d;return c=y.getElementsByTagName("body")[0],c&&c.style?(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),typeof b.style.zoom!==K&&(b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:1px;width:1px;zoom:1",b.appendChild(y.createElement("div")).style.width="5px",a=3!==b.offsetWidth),c.removeChild(d),a):void 0}}();var Gb=/^margin/,Hb=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ib,Jb,Kb=/^(top|right|bottom|left)$/;a.getComputedStyle?(Ib=function(a){return a.ownerDocument.defaultView.getComputedStyle(a,null)},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c.getPropertyValue(b)||c[b]:void 0,c&&(""!==g||m.contains(a.ownerDocument,a)||(g=m.style(a,b)),Hb.test(g)&&Gb.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0===g?g:g+""}):y.documentElement.currentStyle&&(Ib=function(a){return a.currentStyle},Jb=function(a,b,c){var d,e,f,g,h=a.style;return c=c||Ib(a),g=c?c[b]:void 0,null==g&&h&&h[b]&&(g=h[b]),Hb.test(g)&&!Kb.test(b)&&(d=h.left,e=a.runtimeStyle,f=e&&e.left,f&&(e.left=a.currentStyle.left),h.left="fontSize"===b?"1em":g,g=h.pixelLeft+"px",h.left=d,f&&(e.left=f)),void 0===g?g:g+""||"auto"});function Lb(a,b){return{get:function(){var c=a();if(null!=c)return c?void delete this.get:(this.get=b).apply(this,arguments)}}}!function(){var b,c,d,e,f,g,h;if(b=y.createElement("div"),b.innerHTML=" a",d=b.getElementsByTagName("a")[0],c=d&&d.style){c.cssText="float:left;opacity:.5",k.opacity="0.5"===c.opacity,k.cssFloat=!!c.cssFloat,b.style.backgroundClip="content-box",b.cloneNode(!0).style.backgroundClip="",k.clearCloneStyle="content-box"===b.style.backgroundClip,k.boxSizing=""===c.boxSizing||""===c.MozBoxSizing||""===c.WebkitBoxSizing,m.extend(k,{reliableHiddenOffsets:function(){return null==g&&i(),g},boxSizingReliable:function(){return null==f&&i(),f},pixelPosition:function(){return null==e&&i(),e},reliableMarginRight:function(){return null==h&&i(),h}});function i(){var b,c,d,i;c=y.getElementsByTagName("body")[0],c&&c.style&&(b=y.createElement("div"),d=y.createElement("div"),d.style.cssText="position:absolute;border:0;width:0;height:0;top:0;left:-9999px",c.appendChild(d).appendChild(b),b.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;display:block;margin-top:1%;top:1%;border:1px;padding:1px;width:4px;position:absolute",e=f=!1,h=!0,a.getComputedStyle&&(e="1%"!==(a.getComputedStyle(b,null)||{}).top,f="4px"===(a.getComputedStyle(b,null)||{width:"4px"}).width,i=b.appendChild(y.createElement("div")),i.style.cssText=b.style.cssText="-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",i.style.marginRight=i.style.width="0",b.style.width="1px",h=!parseFloat((a.getComputedStyle(i,null)||{}).marginRight)),b.innerHTML="",i=b.getElementsByTagName("td"),i[0].style.cssText="margin:0;border:0;padding:0;display:none",g=0===i[0].offsetHeight,g&&(i[0].style.display="",i[1].style.display="none",g=0===i[0].offsetHeight),c.removeChild(d))}}}(),m.swap=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e};var Mb=/alpha\([^)]*\)/i,Nb=/opacity\s*=\s*([^)]*)/,Ob=/^(none|table(?!-c[ea]).+)/,Pb=new RegExp("^("+S+")(.*)$","i"),Qb=new RegExp("^([+-])=("+S+")","i"),Rb={position:"absolute",visibility:"hidden",display:"block"},Sb={letterSpacing:"0",fontWeight:"400"},Tb=["Webkit","O","Moz","ms"];function Ub(a,b){if(b in a)return b;var c=b.charAt(0).toUpperCase()+b.slice(1),d=b,e=Tb.length;while(e--)if(b=Tb[e]+c,b in a)return b;return d}function Vb(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=m._data(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&U(d)&&(f[g]=m._data(d,"olddisplay",Fb(d.nodeName)))):(e=U(d),(c&&"none"!==c||!e)&&m._data(d,"olddisplay",e?c:m.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}function Wb(a,b,c){var d=Pb.exec(b);return d?Math.max(0,d[1]-(c||0))+(d[2]||"px"):b}function Xb(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=m.css(a,c+T[f],!0,e)),d?("content"===c&&(g-=m.css(a,"padding"+T[f],!0,e)),"margin"!==c&&(g-=m.css(a,"border"+T[f]+"Width",!0,e))):(g+=m.css(a,"padding"+T[f],!0,e),"padding"!==c&&(g+=m.css(a,"border"+T[f]+"Width",!0,e)));return g}function Yb(a,b,c){var d=!0,e="width"===b?a.offsetWidth:a.offsetHeight,f=Ib(a),g=k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,f);if(0>=e||null==e){if(e=Jb(a,b,f),(0>e||null==e)&&(e=a.style[b]),Hb.test(e))return e;d=g&&(k.boxSizingReliable()||e===a.style[b]),e=parseFloat(e)||0}return e+Xb(a,b,c||(g?"border":"content"),d,f)+"px"}m.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Jb(a,"opacity");return""===c?"1":c}}}},cssNumber:{columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":k.cssFloat?"cssFloat":"styleFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=m.camelCase(b),i=a.style;if(b=m.cssProps[h]||(m.cssProps[h]=Ub(i,h)),g=m.cssHooks[b]||m.cssHooks[h],void 0===c)return g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b];if(f=typeof c,"string"===f&&(e=Qb.exec(c))&&(c=(e[1]+1)*e[2]+parseFloat(m.css(a,b)),f="number"),null!=c&&c===c&&("number"!==f||m.cssNumber[h]||(c+="px"),k.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),!(g&&"set"in g&&void 0===(c=g.set(a,c,d)))))try{i[b]=c}catch(j){}}},css:function(a,b,c,d){var e,f,g,h=m.camelCase(b);return b=m.cssProps[h]||(m.cssProps[h]=Ub(a.style,h)),g=m.cssHooks[b]||m.cssHooks[h],g&&"get"in g&&(f=g.get(a,!0,c)),void 0===f&&(f=Jb(a,b,d)),"normal"===f&&b in Sb&&(f=Sb[b]),""===c||c?(e=parseFloat(f),c===!0||m.isNumeric(e)?e||0:f):f}}),m.each(["height","width"],function(a,b){m.cssHooks[b]={get:function(a,c,d){return c?Ob.test(m.css(a,"display"))&&0===a.offsetWidth?m.swap(a,Rb,function(){return Yb(a,b,d)}):Yb(a,b,d):void 0},set:function(a,c,d){var e=d&&Ib(a);return Wb(a,c,d?Xb(a,b,d,k.boxSizing&&"border-box"===m.css(a,"boxSizing",!1,e),e):0)}}}),k.opacity||(m.cssHooks.opacity={get:function(a,b){return Nb.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle,e=m.isNumeric(b)?"alpha(opacity="+100*b+")":"",f=d&&d.filter||c.filter||"";c.zoom=1,(b>=1||""===b)&&""===m.trim(f.replace(Mb,""))&&c.removeAttribute&&(c.removeAttribute("filter"),""===b||d&&!d.filter)||(c.filter=Mb.test(f)?f.replace(Mb,e):f+" "+e)}}),m.cssHooks.marginRight=Lb(k.reliableMarginRight,function(a,b){return b?m.swap(a,{display:"inline-block"},Jb,[a,"marginRight"]):void 0}),m.each({margin:"",padding:"",border:"Width"},function(a,b){m.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+T[d]+b]=f[d]||f[d-2]||f[0];return e}},Gb.test(a)||(m.cssHooks[a+b].set=Wb)}),m.fn.extend({css:function(a,b){return V(this,function(a,b,c){var d,e,f={},g=0;if(m.isArray(b)){for(d=Ib(a),e=b.length;e>g;g++)f[b[g]]=m.css(a,b[g],!1,d);return f}return void 0!==c?m.style(a,b,c):m.css(a,b)},a,b,arguments.length>1)},show:function(){return Vb(this,!0)},hide:function(){return Vb(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){U(this)?m(this).show():m(this).hide()})}});function Zb(a,b,c,d,e){return new Zb.prototype.init(a,b,c,d,e)}m.Tween=Zb,Zb.prototype={constructor:Zb,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||"swing",this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(m.cssNumber[c]?"":"px")
-},cur:function(){var a=Zb.propHooks[this.prop];return a&&a.get?a.get(this):Zb.propHooks._default.get(this)},run:function(a){var b,c=Zb.propHooks[this.prop];return this.pos=b=this.options.duration?m.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Zb.propHooks._default.set(this),this}},Zb.prototype.init.prototype=Zb.prototype,Zb.propHooks={_default:{get:function(a){var b;return null==a.elem[a.prop]||a.elem.style&&null!=a.elem.style[a.prop]?(b=m.css(a.elem,a.prop,""),b&&"auto"!==b?b:0):a.elem[a.prop]},set:function(a){m.fx.step[a.prop]?m.fx.step[a.prop](a):a.elem.style&&(null!=a.elem.style[m.cssProps[a.prop]]||m.cssHooks[a.prop])?m.style(a.elem,a.prop,a.now+a.unit):a.elem[a.prop]=a.now}}},Zb.propHooks.scrollTop=Zb.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},m.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2}},m.fx=Zb.prototype.init,m.fx.step={};var $b,_b,ac=/^(?:toggle|show|hide)$/,bc=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),cc=/queueHooks$/,dc=[ic],ec={"*":[function(a,b){var c=this.createTween(a,b),d=c.cur(),e=bc.exec(b),f=e&&e[3]||(m.cssNumber[a]?"":"px"),g=(m.cssNumber[a]||"px"!==f&&+d)&&bc.exec(m.css(c.elem,a)),h=1,i=20;if(g&&g[3]!==f){f=f||g[3],e=e||[],g=+d||1;do h=h||".5",g/=h,m.style(c.elem,a,g+f);while(h!==(h=c.cur()/d)&&1!==h&&--i)}return e&&(g=c.start=+g||+d||0,c.unit=f,c.end=e[1]?g+(e[1]+1)*e[2]:+e[2]),c}]};function fc(){return setTimeout(function(){$b=void 0}),$b=m.now()}function gc(a,b){var c,d={height:a},e=0;for(b=b?1:0;4>e;e+=2-b)c=T[e],d["margin"+c]=d["padding"+c]=a;return b&&(d.opacity=d.width=a),d}function hc(a,b,c){for(var d,e=(ec[b]||[]).concat(ec["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function ic(a,b,c){var d,e,f,g,h,i,j,l,n=this,o={},p=a.style,q=a.nodeType&&U(a),r=m._data(a,"fxshow");c.queue||(h=m._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,n.always(function(){n.always(function(){h.unqueued--,m.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[p.overflow,p.overflowX,p.overflowY],j=m.css(a,"display"),l="none"===j?m._data(a,"olddisplay")||Fb(a.nodeName):j,"inline"===l&&"none"===m.css(a,"float")&&(k.inlineBlockNeedsLayout&&"inline"!==Fb(a.nodeName)?p.zoom=1:p.display="inline-block")),c.overflow&&(p.overflow="hidden",k.shrinkWrapBlocks()||n.always(function(){p.overflow=c.overflow[0],p.overflowX=c.overflow[1],p.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],ac.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(q?"hide":"show")){if("show"!==e||!r||void 0===r[d])continue;q=!0}o[d]=r&&r[d]||m.style(a,d)}else j=void 0;if(m.isEmptyObject(o))"inline"===("none"===j?Fb(a.nodeName):j)&&(p.display=j);else{r?"hidden"in r&&(q=r.hidden):r=m._data(a,"fxshow",{}),f&&(r.hidden=!q),q?m(a).show():n.done(function(){m(a).hide()}),n.done(function(){var b;m._removeData(a,"fxshow");for(b in o)m.style(a,b,o[b])});for(d in o)g=hc(q?r[d]:0,d,n),d in r||(r[d]=g.start,q&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function jc(a,b){var c,d,e,f,g;for(c in a)if(d=m.camelCase(c),e=b[d],f=a[c],m.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=m.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function kc(a,b,c){var d,e,f=0,g=dc.length,h=m.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=$b||fc(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:m.extend({},b),opts:m.extend(!0,{specialEasing:{}},c),originalProperties:b,originalOptions:c,startTime:$b||fc(),duration:c.duration,tweens:[],createTween:function(b,c){var d=m.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?h.resolveWith(a,[j,b]):h.rejectWith(a,[j,b]),this}}),k=j.props;for(jc(k,j.opts.specialEasing);g>f;f++)if(d=dc[f].call(j,a,k,j.opts))return d;return m.map(k,hc,j),m.isFunction(j.opts.start)&&j.opts.start.call(a,j),m.fx.timer(m.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}m.Animation=m.extend(kc,{tweener:function(a,b){m.isFunction(a)?(b=a,a=["*"]):a=a.split(" ");for(var c,d=0,e=a.length;e>d;d++)c=a[d],ec[c]=ec[c]||[],ec[c].unshift(b)},prefilter:function(a,b){b?dc.unshift(a):dc.push(a)}}),m.speed=function(a,b,c){var d=a&&"object"==typeof a?m.extend({},a):{complete:c||!c&&b||m.isFunction(a)&&a,duration:a,easing:c&&b||b&&!m.isFunction(b)&&b};return d.duration=m.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in m.fx.speeds?m.fx.speeds[d.duration]:m.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){m.isFunction(d.old)&&d.old.call(this),d.queue&&m.dequeue(this,d.queue)},d},m.fn.extend({fadeTo:function(a,b,c,d){return this.filter(U).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=m.isEmptyObject(a),f=m.speed(b,c,d),g=function(){var b=kc(this,m.extend({},a),f);(e||m._data(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=m.timers,g=m._data(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&cc.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&m.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=m._data(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=m.timers,g=d?d.length:0;for(c.finish=!0,m.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),m.each(["toggle","show","hide"],function(a,b){var c=m.fn[b];m.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(gc(b,!0),a,d,e)}}),m.each({slideDown:gc("show"),slideUp:gc("hide"),slideToggle:gc("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){m.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),m.timers=[],m.fx.tick=function(){var a,b=m.timers,c=0;for($b=m.now();ca",d=b.getElementsByTagName("a")[0],c=y.createElement("select"),e=c.appendChild(y.createElement("option")),a=b.getElementsByTagName("input")[0],d.style.cssText="top:1px",k.getSetAttribute="t"!==b.className,k.style=/top/.test(d.getAttribute("style")),k.hrefNormalized="/a"===d.getAttribute("href"),k.checkOn=!!a.value,k.optSelected=e.selected,k.enctype=!!y.createElement("form").enctype,c.disabled=!0,k.optDisabled=!e.disabled,a=y.createElement("input"),a.setAttribute("value",""),k.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),k.radioValue="t"===a.value}();var lc=/\r/g;m.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=m.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,m(this).val()):a,null==e?e="":"number"==typeof e?e+="":m.isArray(e)&&(e=m.map(e,function(a){return null==a?"":a+""})),b=m.valHooks[this.type]||m.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=m.valHooks[e.type]||m.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(lc,""):null==c?"":c)}}}),m.extend({valHooks:{option:{get:function(a){var b=m.find.attr(a,"value");return null!=b?b:m.trim(m.text(a))}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],!(!c.selected&&i!==e||(k.optDisabled?c.disabled:null!==c.getAttribute("disabled"))||c.parentNode.disabled&&m.nodeName(c.parentNode,"optgroup"))){if(b=m(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=m.makeArray(b),g=e.length;while(g--)if(d=e[g],m.inArray(m.valHooks.option.get(d),f)>=0)try{d.selected=c=!0}catch(h){d.scrollHeight}else d.selected=!1;return c||(a.selectedIndex=-1),e}}}}),m.each(["radio","checkbox"],function(){m.valHooks[this]={set:function(a,b){return m.isArray(b)?a.checked=m.inArray(m(a).val(),b)>=0:void 0}},k.checkOn||(m.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var mc,nc,oc=m.expr.attrHandle,pc=/^(?:checked|selected)$/i,qc=k.getSetAttribute,rc=k.input;m.fn.extend({attr:function(a,b){return V(this,m.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){m.removeAttr(this,a)})}}),m.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(a&&3!==f&&8!==f&&2!==f)return typeof a.getAttribute===K?m.prop(a,b,c):(1===f&&m.isXMLDoc(a)||(b=b.toLowerCase(),d=m.attrHooks[b]||(m.expr.match.bool.test(b)?nc:mc)),void 0===c?d&&"get"in d&&null!==(e=d.get(a,b))?e:(e=m.find.attr(a,b),null==e?void 0:e):null!==c?d&&"set"in d&&void 0!==(e=d.set(a,c,b))?e:(a.setAttribute(b,c+""),c):void m.removeAttr(a,b))},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(E);if(f&&1===a.nodeType)while(c=f[e++])d=m.propFix[c]||c,m.expr.match.bool.test(c)?rc&&qc||!pc.test(c)?a[d]=!1:a[m.camelCase("default-"+c)]=a[d]=!1:m.attr(a,c,""),a.removeAttribute(qc?c:d)},attrHooks:{type:{set:function(a,b){if(!k.radioValue&&"radio"===b&&m.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}}}),nc={set:function(a,b,c){return b===!1?m.removeAttr(a,c):rc&&qc||!pc.test(c)?a.setAttribute(!qc&&m.propFix[c]||c,c):a[m.camelCase("default-"+c)]=a[c]=!0,c}},m.each(m.expr.match.bool.source.match(/\w+/g),function(a,b){var c=oc[b]||m.find.attr;oc[b]=rc&&qc||!pc.test(b)?function(a,b,d){var e,f;return d||(f=oc[b],oc[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,oc[b]=f),e}:function(a,b,c){return c?void 0:a[m.camelCase("default-"+b)]?b.toLowerCase():null}}),rc&&qc||(m.attrHooks.value={set:function(a,b,c){return m.nodeName(a,"input")?void(a.defaultValue=b):mc&&mc.set(a,b,c)}}),qc||(mc={set:function(a,b,c){var d=a.getAttributeNode(c);return d||a.setAttributeNode(d=a.ownerDocument.createAttribute(c)),d.value=b+="","value"===c||b===a.getAttribute(c)?b:void 0}},oc.id=oc.name=oc.coords=function(a,b,c){var d;return c?void 0:(d=a.getAttributeNode(b))&&""!==d.value?d.value:null},m.valHooks.button={get:function(a,b){var c=a.getAttributeNode(b);return c&&c.specified?c.value:void 0},set:mc.set},m.attrHooks.contenteditable={set:function(a,b,c){mc.set(a,""===b?!1:b,c)}},m.each(["width","height"],function(a,b){m.attrHooks[b]={set:function(a,c){return""===c?(a.setAttribute(b,"auto"),c):void 0}}})),k.style||(m.attrHooks.style={get:function(a){return a.style.cssText||void 0},set:function(a,b){return a.style.cssText=b+""}});var sc=/^(?:input|select|textarea|button|object)$/i,tc=/^(?:a|area)$/i;m.fn.extend({prop:function(a,b){return V(this,m.prop,a,b,arguments.length>1)},removeProp:function(a){return a=m.propFix[a]||a,this.each(function(){try{this[a]=void 0,delete this[a]}catch(b){}})}}),m.extend({propFix:{"for":"htmlFor","class":"className"},prop:function(a,b,c){var d,e,f,g=a.nodeType;if(a&&3!==g&&8!==g&&2!==g)return f=1!==g||!m.isXMLDoc(a),f&&(b=m.propFix[b]||b,e=m.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b]},propHooks:{tabIndex:{get:function(a){var b=m.find.attr(a,"tabindex");return b?parseInt(b,10):sc.test(a.nodeName)||tc.test(a.nodeName)&&a.href?0:-1}}}}),k.hrefNormalized||m.each(["href","src"],function(a,b){m.propHooks[b]={get:function(a){return a.getAttribute(b,4)}}}),k.optSelected||(m.propHooks.selected={get:function(a){var b=a.parentNode;return b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex),null}}),m.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){m.propFix[this.toLowerCase()]=this}),k.enctype||(m.propFix.enctype="encoding");var uc=/[\t\r\n\f]/g;m.fn.extend({addClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j="string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).addClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):" ")){f=0;while(e=b[f++])d.indexOf(" "+e+" ")<0&&(d+=e+" ");g=m.trim(d),c.className!==g&&(c.className=g)}return this},removeClass:function(a){var b,c,d,e,f,g,h=0,i=this.length,j=0===arguments.length||"string"==typeof a&&a;if(m.isFunction(a))return this.each(function(b){m(this).removeClass(a.call(this,b,this.className))});if(j)for(b=(a||"").match(E)||[];i>h;h++)if(c=this[h],d=1===c.nodeType&&(c.className?(" "+c.className+" ").replace(uc," "):"")){f=0;while(e=b[f++])while(d.indexOf(" "+e+" ")>=0)d=d.replace(" "+e+" "," ");g=a?m.trim(d):"",c.className!==g&&(c.className=g)}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):this.each(m.isFunction(a)?function(c){m(this).toggleClass(a.call(this,c,this.className,b),b)}:function(){if("string"===c){var b,d=0,e=m(this),f=a.match(E)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(c===K||"boolean"===c)&&(this.className&&m._data(this,"__className__",this.className),this.className=this.className||a===!1?"":m._data(this,"__className__")||"")})},hasClass:function(a){for(var b=" "+a+" ",c=0,d=this.length;d>c;c++)if(1===this[c].nodeType&&(" "+this[c].className+" ").replace(uc," ").indexOf(b)>=0)return!0;return!1}}),m.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){m.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),m.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)},bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)}});var vc=m.now(),wc=/\?/,xc=/(,)|(\[|{)|(}|])|"(?:[^"\\\r\n]|\\["\\\/bfnrt]|\\u[\da-fA-F]{4})*"\s*:?|true|false|null|-?(?!0\d)\d+(?:\.\d+|)(?:[eE][+-]?\d+|)/g;m.parseJSON=function(b){if(a.JSON&&a.JSON.parse)return a.JSON.parse(b+"");var c,d=null,e=m.trim(b+"");return e&&!m.trim(e.replace(xc,function(a,b,e,f){return c&&b&&(d=0),0===d?a:(c=e||b,d+=!f-!e,"")}))?Function("return "+e)():m.error("Invalid JSON: "+b)},m.parseXML=function(b){var c,d;if(!b||"string"!=typeof b)return null;try{a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b))}catch(e){c=void 0}return c&&c.documentElement&&!c.getElementsByTagName("parsererror").length||m.error("Invalid XML: "+b),c};var yc,zc,Ac=/#.*$/,Bc=/([?&])_=[^&]*/,Cc=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Dc=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Ec=/^(?:GET|HEAD)$/,Fc=/^\/\//,Gc=/^([\w.+-]+:)(?:\/\/(?:[^\/?#]*@|)([^\/?#:]*)(?::(\d+)|)|)/,Hc={},Ic={},Jc="*/".concat("*");try{zc=location.href}catch(Kc){zc=y.createElement("a"),zc.href="",zc=zc.href}yc=Gc.exec(zc.toLowerCase())||[];function Lc(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(E)||[];if(m.isFunction(c))while(d=f[e++])"+"===d.charAt(0)?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function Mc(a,b,c,d){var e={},f=a===Ic;function g(h){var i;return e[h]=!0,m.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function Nc(a,b){var c,d,e=m.ajaxSettings.flatOptions||{};for(d in b)void 0!==b[d]&&((e[d]?a:c||(c={}))[d]=b[d]);return c&&m.extend(!0,a,c),a}function Oc(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===e&&(e=a.mimeType||b.getResponseHeader("Content-Type"));if(e)for(g in h)if(h[g]&&h[g].test(e)){i.unshift(g);break}if(i[0]in c)f=i[0];else{for(g in c){if(!i[0]||a.converters[g+" "+i[0]]){f=g;break}d||(d=g)}f=f||d}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function Pc(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}m.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:zc,type:"GET",isLocal:Dc.test(yc[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Jc,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":m.parseJSON,"text xml":m.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?Nc(Nc(a,m.ajaxSettings),b):Nc(m.ajaxSettings,a)},ajaxPrefilter:Lc(Hc),ajaxTransport:Lc(Ic),ajax:function(a,b){"object"==typeof a&&(b=a,a=void 0),b=b||{};var c,d,e,f,g,h,i,j,k=m.ajaxSetup({},b),l=k.context||k,n=k.context&&(l.nodeType||l.jquery)?m(l):m.event,o=m.Deferred(),p=m.Callbacks("once memory"),q=k.statusCode||{},r={},s={},t=0,u="canceled",v={readyState:0,getResponseHeader:function(a){var b;if(2===t){if(!j){j={};while(b=Cc.exec(f))j[b[1].toLowerCase()]=b[2]}b=j[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===t?f:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return t||(a=s[c]=s[c]||a,r[a]=b),this},overrideMimeType:function(a){return t||(k.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>t)for(b in a)q[b]=[q[b],a[b]];else v.always(a[v.status]);return this},abort:function(a){var b=a||u;return i&&i.abort(b),x(0,b),this}};if(o.promise(v).complete=p.add,v.success=v.done,v.error=v.fail,k.url=((a||k.url||zc)+"").replace(Ac,"").replace(Fc,yc[1]+"//"),k.type=b.method||b.type||k.method||k.type,k.dataTypes=m.trim(k.dataType||"*").toLowerCase().match(E)||[""],null==k.crossDomain&&(c=Gc.exec(k.url.toLowerCase()),k.crossDomain=!(!c||c[1]===yc[1]&&c[2]===yc[2]&&(c[3]||("http:"===c[1]?"80":"443"))===(yc[3]||("http:"===yc[1]?"80":"443")))),k.data&&k.processData&&"string"!=typeof k.data&&(k.data=m.param(k.data,k.traditional)),Mc(Hc,k,b,v),2===t)return v;h=k.global,h&&0===m.active++&&m.event.trigger("ajaxStart"),k.type=k.type.toUpperCase(),k.hasContent=!Ec.test(k.type),e=k.url,k.hasContent||(k.data&&(e=k.url+=(wc.test(e)?"&":"?")+k.data,delete k.data),k.cache===!1&&(k.url=Bc.test(e)?e.replace(Bc,"$1_="+vc++):e+(wc.test(e)?"&":"?")+"_="+vc++)),k.ifModified&&(m.lastModified[e]&&v.setRequestHeader("If-Modified-Since",m.lastModified[e]),m.etag[e]&&v.setRequestHeader("If-None-Match",m.etag[e])),(k.data&&k.hasContent&&k.contentType!==!1||b.contentType)&&v.setRequestHeader("Content-Type",k.contentType),v.setRequestHeader("Accept",k.dataTypes[0]&&k.accepts[k.dataTypes[0]]?k.accepts[k.dataTypes[0]]+("*"!==k.dataTypes[0]?", "+Jc+"; q=0.01":""):k.accepts["*"]);for(d in k.headers)v.setRequestHeader(d,k.headers[d]);if(k.beforeSend&&(k.beforeSend.call(l,v,k)===!1||2===t))return v.abort();u="abort";for(d in{success:1,error:1,complete:1})v[d](k[d]);if(i=Mc(Ic,k,b,v)){v.readyState=1,h&&n.trigger("ajaxSend",[v,k]),k.async&&k.timeout>0&&(g=setTimeout(function(){v.abort("timeout")},k.timeout));try{t=1,i.send(r,x)}catch(w){if(!(2>t))throw w;x(-1,w)}}else x(-1,"No Transport");function x(a,b,c,d){var j,r,s,u,w,x=b;2!==t&&(t=2,g&&clearTimeout(g),i=void 0,f=d||"",v.readyState=a>0?4:0,j=a>=200&&300>a||304===a,c&&(u=Oc(k,v,c)),u=Pc(k,u,v,j),j?(k.ifModified&&(w=v.getResponseHeader("Last-Modified"),w&&(m.lastModified[e]=w),w=v.getResponseHeader("etag"),w&&(m.etag[e]=w)),204===a||"HEAD"===k.type?x="nocontent":304===a?x="notmodified":(x=u.state,r=u.data,s=u.error,j=!s)):(s=x,(a||!x)&&(x="error",0>a&&(a=0))),v.status=a,v.statusText=(b||x)+"",j?o.resolveWith(l,[r,x,v]):o.rejectWith(l,[v,x,s]),v.statusCode(q),q=void 0,h&&n.trigger(j?"ajaxSuccess":"ajaxError",[v,k,j?r:s]),p.fireWith(l,[v,x]),h&&(n.trigger("ajaxComplete",[v,k]),--m.active||m.event.trigger("ajaxStop")))}return v},getJSON:function(a,b,c){return m.get(a,b,c,"json")},getScript:function(a,b){return m.get(a,void 0,b,"script")}}),m.each(["get","post"],function(a,b){m[b]=function(a,c,d,e){return m.isFunction(c)&&(e=e||d,d=c,c=void 0),m.ajax({url:a,type:b,dataType:e,data:c,success:d})}}),m.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){m.fn[b]=function(a){return this.on(b,a)}}),m._evalUrl=function(a){return m.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},m.fn.extend({wrapAll:function(a){if(m.isFunction(a))return this.each(function(b){m(this).wrapAll(a.call(this,b))});if(this[0]){var b=m(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&1===a.firstChild.nodeType)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){return this.each(m.isFunction(a)?function(b){m(this).wrapInner(a.call(this,b))}:function(){var b=m(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=m.isFunction(a);return this.each(function(c){m(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){m.nodeName(this,"body")||m(this).replaceWith(this.childNodes)}).end()}}),m.expr.filters.hidden=function(a){return a.offsetWidth<=0&&a.offsetHeight<=0||!k.reliableHiddenOffsets()&&"none"===(a.style&&a.style.display||m.css(a,"display"))},m.expr.filters.visible=function(a){return!m.expr.filters.hidden(a)};var Qc=/%20/g,Rc=/\[\]$/,Sc=/\r?\n/g,Tc=/^(?:submit|button|image|reset|file)$/i,Uc=/^(?:input|select|textarea|keygen)/i;function Vc(a,b,c,d){var e;if(m.isArray(b))m.each(b,function(b,e){c||Rc.test(a)?d(a,e):Vc(a+"["+("object"==typeof e?b:"")+"]",e,c,d)});else if(c||"object"!==m.type(b))d(a,b);else for(e in b)Vc(a+"["+e+"]",b[e],c,d)}m.param=function(a,b){var c,d=[],e=function(a,b){b=m.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=m.ajaxSettings&&m.ajaxSettings.traditional),m.isArray(a)||a.jquery&&!m.isPlainObject(a))m.each(a,function(){e(this.name,this.value)});else for(c in a)Vc(c,a[c],b,e);return d.join("&").replace(Qc,"+")},m.fn.extend({serialize:function(){return m.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=m.prop(this,"elements");return a?m.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!m(this).is(":disabled")&&Uc.test(this.nodeName)&&!Tc.test(a)&&(this.checked||!W.test(a))}).map(function(a,b){var c=m(this).val();return null==c?null:m.isArray(c)?m.map(c,function(a){return{name:b.name,value:a.replace(Sc,"\r\n")}}):{name:b.name,value:c.replace(Sc,"\r\n")}}).get()}}),m.ajaxSettings.xhr=void 0!==a.ActiveXObject?function(){return!this.isLocal&&/^(get|post|head|put|delete|options)$/i.test(this.type)&&Zc()||$c()}:Zc;var Wc=0,Xc={},Yc=m.ajaxSettings.xhr();a.ActiveXObject&&m(a).on("unload",function(){for(var a in Xc)Xc[a](void 0,!0)}),k.cors=!!Yc&&"withCredentials"in Yc,Yc=k.ajax=!!Yc,Yc&&m.ajaxTransport(function(a){if(!a.crossDomain||k.cors){var b;return{send:function(c,d){var e,f=a.xhr(),g=++Wc;if(f.open(a.type,a.url,a.async,a.username,a.password),a.xhrFields)for(e in a.xhrFields)f[e]=a.xhrFields[e];a.mimeType&&f.overrideMimeType&&f.overrideMimeType(a.mimeType),a.crossDomain||c["X-Requested-With"]||(c["X-Requested-With"]="XMLHttpRequest");for(e in c)void 0!==c[e]&&f.setRequestHeader(e,c[e]+"");f.send(a.hasContent&&a.data||null),b=function(c,e){var h,i,j;if(b&&(e||4===f.readyState))if(delete Xc[g],b=void 0,f.onreadystatechange=m.noop,e)4!==f.readyState&&f.abort();else{j={},h=f.status,"string"==typeof f.responseText&&(j.text=f.responseText);try{i=f.statusText}catch(k){i=""}h||!a.isLocal||a.crossDomain?1223===h&&(h=204):h=j.text?200:404}j&&d(h,i,j,f.getAllResponseHeaders())},a.async?4===f.readyState?setTimeout(b):f.onreadystatechange=Xc[g]=b:b()},abort:function(){b&&b(void 0,!0)}}}});function Zc(){try{return new a.XMLHttpRequest}catch(b){}}function $c(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}m.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(a){return m.globalEval(a),a}}}),m.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),m.ajaxTransport("script",function(a){if(a.crossDomain){var b,c=y.head||m("head")[0]||y.documentElement;return{send:function(d,e){b=y.createElement("script"),b.async=!0,a.scriptCharset&&(b.charset=a.scriptCharset),b.src=a.url,b.onload=b.onreadystatechange=function(a,c){(c||!b.readyState||/loaded|complete/.test(b.readyState))&&(b.onload=b.onreadystatechange=null,b.parentNode&&b.parentNode.removeChild(b),b=null,c||e(200,"success"))},c.insertBefore(b,c.firstChild)},abort:function(){b&&b.onload(void 0,!0)}}}});var _c=[],ad=/(=)\?(?=&|$)|\?\?/;m.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=_c.pop()||m.expando+"_"+vc++;return this[a]=!0,a}}),m.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(ad.test(b.url)?"url":"string"==typeof b.data&&!(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&ad.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=m.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(ad,"$1"+e):b.jsonp!==!1&&(b.url+=(wc.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||m.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,_c.push(e)),g&&m.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),m.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||y;var d=u.exec(a),e=!c&&[];return d?[b.createElement(d[1])]:(d=m.buildFragment([a],b,e),e&&e.length&&m(e).remove(),m.merge([],d.childNodes))};var bd=m.fn.load;m.fn.load=function(a,b,c){if("string"!=typeof a&&bd)return bd.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>=0&&(d=m.trim(a.slice(h,a.length)),a=a.slice(0,h)),m.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(f="POST"),g.length>0&&m.ajax({url:a,type:f,dataType:"html",data:b}).done(function(a){e=arguments,g.html(d?m("").append(m.parseHTML(a)).find(d):a)}).complete(c&&function(a,b){g.each(c,e||[a.responseText,b,a])}),this},m.expr.filters.animated=function(a){return m.grep(m.timers,function(b){return a===b.elem}).length};var cd=a.document.documentElement;function dd(a){return m.isWindow(a)?a:9===a.nodeType?a.defaultView||a.parentWindow:!1}m.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=m.css(a,"position"),l=m(a),n={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=m.css(a,"top"),i=m.css(a,"left"),j=("absolute"===k||"fixed"===k)&&m.inArray("auto",[f,i])>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),m.isFunction(b)&&(b=b.call(a,c,h)),null!=b.top&&(n.top=b.top-h.top+g),null!=b.left&&(n.left=b.left-h.left+e),"using"in b?b.using.call(a,n):l.css(n)}},m.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){m.offset.setOffset(this,a,b)});var b,c,d={top:0,left:0},e=this[0],f=e&&e.ownerDocument;if(f)return b=f.documentElement,m.contains(b,e)?(typeof e.getBoundingClientRect!==K&&(d=e.getBoundingClientRect()),c=dd(f),{top:d.top+(c.pageYOffset||b.scrollTop)-(b.clientTop||0),left:d.left+(c.pageXOffset||b.scrollLeft)-(b.clientLeft||0)}):d},position:function(){if(this[0]){var a,b,c={top:0,left:0},d=this[0];return"fixed"===m.css(d,"position")?b=d.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),m.nodeName(a[0],"html")||(c=a.offset()),c.top+=m.css(a[0],"borderTopWidth",!0),c.left+=m.css(a[0],"borderLeftWidth",!0)),{top:b.top-c.top-m.css(d,"marginTop",!0),left:b.left-c.left-m.css(d,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||cd;while(a&&!m.nodeName(a,"html")&&"static"===m.css(a,"position"))a=a.offsetParent;return a||cd})}}),m.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c=/Y/.test(b);m.fn[a]=function(d){return V(this,function(a,d,e){var f=dd(a);return void 0===e?f?b in f?f[b]:f.document.documentElement[d]:a[d]:void(f?f.scrollTo(c?m(f).scrollLeft():e,c?e:m(f).scrollTop()):a[d]=e)},a,d,arguments.length,null)}}),m.each(["top","left"],function(a,b){m.cssHooks[b]=Lb(k.pixelPosition,function(a,c){return c?(c=Jb(a,b),Hb.test(c)?m(a).position()[b]+"px":c):void 0})}),m.each({Height:"height",Width:"width"},function(a,b){m.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){m.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return V(this,function(b,c,d){var e;return m.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?m.css(b,c,g):m.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),m.fn.size=function(){return this.length},m.fn.andSelf=m.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return m});var ed=a.jQuery,fd=a.$;return m.noConflict=function(b){return a.$===m&&(a.$=fd),b&&a.jQuery===m&&(a.jQuery=ed),m},typeof b===K&&(a.jQuery=a.$=m),m});
diff --git a/all_tools/js/meshcoder_worker.js b/all_tools/js/meshcoder_worker.js
deleted file mode 100644
index 61f1dc8..0000000
--- a/all_tools/js/meshcoder_worker.js
+++ /dev/null
@@ -1,954 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-onmessage = function(job) {
- if(typeof(job.data) == "string") return;
- var node = job.data.node;
- var signature = job.data.signature;
- var patches = job.data.patches;
-// var now =new Date().getTime();
-
- var size;
- if(!node.buffer) return;
- else size = node.buffer.byteLength;
- var buffer;
- for(var i =0 ; i < 1; i++) {
- var coder = new MeshCoder(signature, node, patches);
- buffer = coder.decode(node.buffer);
- }
- node.buffer = buffer;
-// var elapsed = new Date().getTime() - now;
- var t = node.nface;
-// console.log("Z Time: " + elapsed + " Size: " + size + " KT/s " + (t/(elapsed)) + " Mbps " + (8*1000*node.buffer.byteLength/elapsed)/(1<<20));
- postMessage(node);
-}
-
-// actually bitstreams expects a little endian uin64 type. convert it to 2 uint32
-
-BitStream = function(array) {
- this.a = array;
- for(var i = 0; i < array.length; i += 2) {
- var s = array[i];
- array[i] = array[i+1];
- array[i+1] = s;
- }
- this.position = 0;
- this.bitsPending = 0;
-};
-
-BitStream.prototype = {
- read: function(bits) {
- var bitBuffer = 0;
- while(bits > 0) {
- var partial;
- var bitsConsumed;
- if (this.bitsPending > 0) {
- var byte = (this.a[this.position - 1] & (0xffffffff >>> (32 - this.bitsPending)))>>>0;
- bitsConsumed = Math.min(this.bitsPending, bits);
- this.bitsPending -= bitsConsumed;
- partial = byte >>> this.bitsPending;
- } else {
- bitsConsumed = Math.min(32, bits);
- this.bitsPending = 32 - bitsConsumed;
- partial = this.a[this.position++] >>> this.bitsPending;
- }
- bits -= bitsConsumed;
- bitBuffer = ((bitBuffer << bitsConsumed) | partial)>>>0;
- }
- return bitBuffer;
- },
- replace: function(bits, value) {
- //zero last part
- value = (value & (0xffffffff >>> 32 - bits)) >>> 0;
- value = (value | read(bits)) >>> 0;
- return value;
- }
-};
-
-Stream = function(buffer) {
- this.data = buffer;
- this.buffer = new Uint8Array(buffer);
- this.pos = 0;
-}
-
-Stream.prototype = {
- readChar: function() {
- var c = this.buffer[this.pos++];
- if(c > 127) c -= 256;
- return c;
- },
- readUChar: function() {
- return this.buffer[this.pos++];
- },
- readInt: function() {
- var c = this.buffer[this.pos + 3]
- c <<= 8;
- c |= this.buffer[this.pos + 2];
- c <<= 8;
- c |= this.buffer[this.pos + 1];
- c <<= 8;
- c |= this.buffer[this.pos + 0];
- this.pos += 4;
- return c;
- },
- readArray: function(n) {
- var a = this.buffer.subarray(this.pos, this.pos+n);
- this.pos += n;
- return a;
- },
- readBitStream:function() {
- var n = this.readInt();
- var pad = this.pos & 0x3;
- if(pad != 0)
- this.pos += 4 - pad;
- var b = new BitStream(new Uint32Array(this.data, this.pos, n*2));
- this.pos += n*8;
- return b;
- }
-};
-
-function Tunstall(wordsize, lookup_size) {
- this.wordsize = wordsize? wordsize : 8;
- this.lookup_size = lookup_size? lookup_size : 8;
-}
-
-Tunstall.prototype = {
- decompress: function(stream) {
- var nsymbols = stream.readUChar();
- this.probabilities = stream.readArray(nsymbols*2);
- this.createDecodingTables();
- var size = stream.readInt();
- var data = new Uint8Array(size);
- var compressed_size = stream.readInt();
- var compressed_data = stream.readArray(compressed_size);
- if(size)
- this._decompress(compressed_data, compressed_size, data, size);
- return data;
- },
-
- createDecodingTables: function() {
- //read symbol,prob,symbol,prob as uchar.
- //Here probabilities will range from 0 to 0xffff for better precision
-
- var n_symbols = this.probabilities.length/2;
- if(n_symbols <= 1) return;
-
- var queues = []; //array of arrays
- var buffer = [];
-
- //initialize adding all symbols to queues
- for(var i = 0; i < n_symbols; i++) {
- var symbol = this.probabilities[i*2];
- var s = [(this.probabilities[i*2+1])<<8, buffer.length, 1]; //probability, position in the buffer, length
- queues[i] = [s];
- buffer.push(this.probabilities[i*2]); //symbol
- }
- var dictionary_size = 1< max_prob) {
- best = i;
- max_prob = p;
- }
- }
- var symbol = queues[best][0];
- var pos = buffer.length;
-
- for(var i = 0; i < n_symbols; i++) {
- var sym = this.probabilities[i*2];
- var prob = this.probabilities[i*2+1]<<8;
- var s = [((prob*symbol[0])>>>16), pos, symbol[2]+1]; //combine probabilities, keep track of buffer, keep length of queue
-
- for(var k = 0; k < symbol[2]; k++)
- buffer[pos+k] = buffer[symbol[1] + k]; //copy sequence of symbols
-
- pos += symbol[2];
- buffer[pos++] = sym; //append symbol
- queues[i].push(s);
- }
- table_length += (n_symbols-1)*(symbol[2] + 1) +1;
- n_words += n_symbols -1;
- queues[best].shift(); //remove first thing
- }
-
- this.index = new Uint32Array(n_words);
- this.lengths = new Uint32Array(n_words);
- this.table = new Uint8Array(table_length);
- var word = 0;
- var pos = 0;
- for(i = 0; i < queues.length; i++) {
- var queue = queues[i];
- for(var k = 0; k < queue.length; k++) {
- var s = queue[k];
- this.index[word] = pos;
- this.lengths[word] = s[2]; //length
- word++;
-
- for(var j = 0; j < s[2]; j++)
- this.table[pos + j] = buffer[s[1] + j]; //buffer of offset
- pos += s[2]; //length
- }
- }
- },
- _decompress: function(input, input_size, output, output_size) {
- var input_pos = 0;
- var output_pos = 0;
- if(this.probabilities.length == 2) {
- var symbol = this.probabilities[0];
- for(var i = 0; i < output_size; i++)
- output[i] = symbol;
- return;
- }
-
- while(input_pos < input_size-1) {
- var symbol = input[input_pos++];
- var start = this.index[symbol];
- var end = start + this.lengths[symbol];
- for(var i = start; i < end; i++)
- output[output_pos++] = this.table[i];
- }
-
- //last symbol might override so we check.
- var symbol = input[input_pos];
- var start = this.index[symbol];
- var end = start + output_size - output_pos;
- var length = output_size - output_pos;
- for(var i = start; i < end; i++)
- output[output_pos++] = this.table[i];
-
- return output;
- }
-}
-
-ZPoint = function(h, l) {
- this.lo = l;
- this.hi = h;
-}
-
-ZPoint.prototype = {
- copy: function(z) {
- this.lo = z.lo;
- this.hi = z.hi;
- },
- setBit: function(d) {
- if(d < 32)
- this.lo = (this.lo | (1<>>0;
- else
- this.hi = (this.hi | (1<<(d-32)))>>>0;
- },
- toPoint: function(min, step, buffer, pos) {
- var x = this.morton3(this.lo, this.hi>>>1);
- var y = this.morton3(this.lo>>>1, this.hi>>>2);
- var z = this.morton3((this.lo>>>2 | (this.hi & 0x1)<<30 )>>>0, this.hi>>>3); //first hi bit needs to go into low.
-
- buffer[pos+0] = (x + min[0])*step;
- buffer[pos+1] = (y + min[1])*step;
- buffer[pos+2] = (z + min[2])*step;
- },
- morton3: function(lo, hi) {
- lo = ( lo & 0x49249249)>>>0;
- lo = ((lo | (lo >>> 2 )) & 0xc30c30c3)>>>0;
- lo = ((lo | (lo >>> 4 )) & 0x0f00f00f)>>>0;
- lo = ((lo | (lo >>> 8 )) & 0xff0000ff)>>>0;
- lo = ((lo | (lo >>> 16)) & 0x0000ffff)>>>0;
-
- hi = ( hi & 0x49249249)>>>0;
- hi = ((hi | (hi >> 2 )) & 0xc30c30c3)>>>0;
- hi = ((hi | (hi >> 4 )) & 0x0f00f00f)>>>0;
- hi = ((hi | (hi >> 8 )) & 0xff0000ff)>>>0;
- hi = ((hi | (hi >> 16)) & 0x0000ffff)>>>0;
-
- return ((hi<<11) | lo)>>>0;
- }
-};
-
-//node is an object with nvert, nface
-//patches is an array of offsets in the index, triangle are grouped by those offsets
-//signature tells wether mesh has indices, normals, colors, etc. {'colors': true, 'normals':true, 'indices': true }
-
-function MeshCoder(signature, node, patches) {
- this.sig = signature;
- this.node = node;
- this.patches = patches;
-
- this.last = new Int32Array(this.node.nvert);
- this.last_count = 0;
-}
-
-MeshCoder.prototype = {
- //assumes input is an ArrayBuffer
-decode: function(input) {
- var t = this;
-
- t.buffer = new ArrayBuffer(t.node.nvert*(12 + t.sig.texcoords*8 + t.sig.normals*6 + t.sig.colors*4) + t.node.nface*t.sig.indices*6);
-
- var size = t.node.nvert*12; //float
- t.coords = new Float32Array(t.buffer, 0, t.node.nvert*3);
-
- if(t.sig.texcoords) {
- t.texcoords = new Float32Array(t.buffer, size, t.node.nvert*2);
- size += t.node.nvert*8; //float
- }
- if(t.sig.normals) {
- t.normals = new Int16Array(t.buffer, size, t.node.nvert*3);
- size += t.node.nvert*6; //short
- }
- if(t.sig.colors) {
- t.colors = new Uint8ClampedArray(t.buffer, size, t.node.nvert*4);
- size += t.node.nvert*4; //chars
- }
- if(t.sig.indices) {
- t.faces = new Uint16Array(t.buffer, size, t.node.nface*3);
- size += t.node.nface*6; //short
- }
-
- t.stream = new Stream(input);
-
- t.stack = new Float32Array(12); //min0, min1, min2, step, tmin0, tmin1, tstep
-
- t.stack[3] = t.stream.readInt();
- t.stack[4] = t.stream.readInt();
- t.stack[5] = t.stream.readInt();
-
- t.coord_q = t.stream.readChar();
- t.coord_bits = t.stream.readChar()*3;
-
- t.stack[6] = Math.pow(2.0, t.coord_q);
-
- if(t.sig.texcoords) {
- t.stack[9] = t.stream.readInt();
- t.stack[10] = t.stream.readInt();
-
- t.texcoord_q = t.stream.readChar();
- t.texcoord_bits = t.stream.readChar()*2;
- t.stack[11] = Math.pow(2.0, t.texcoord_q);
- }
-
- if(t.sig.indices) {
- t.decodeFaces();
-
-// var faces = window.performance.now() - start;
-// start += faces;
- } else {
- t.decodeCoordinates();
-// var coords = window.performance.now() - start;
-// start += coords;
- }
-
- if(t.sig.normals)
- t.decodeNormals();
-// var normals = window.performance.now() - start;
-// start += normals;
- if(t.sig.colors)
- t.decodeColors();
-// var colors = window.performance.now() - start;
-// start += colors;
-// console.log("Decode " + (faces + coords + normals + colors) + "ms. C: " + coords + " F: " + faces + " N: " + normals + " C: " + colors);
-
- return t.buffer;
-},
-
-decodeCoordinates: function() {
- var t = this;
- t.min = [t.stack[3], t.stack[4], t.stack[5]];
-
- var step = Math.pow(2.0, t.coord_q);
-
- var hi_bits = Math.max(t.coord_bits - 32, 0);
- var lo_bits = Math.min(t.coord_bits, 32);
-
- var bitstream = t.stream.readBitStream();
-
- var tunstall = new Tunstall;
- var diffs = tunstall.decompress(t.stream);
-
- var hi = bitstream.read(hi_bits);
- var lo = bitstream.read(lo_bits);
- var p = new ZPoint(hi, lo);
- var count = 0;
- p.toPoint(t.min, step, t.coords, count);
- count += 3;
- for(var i = 1; i < t.node.nvert; i++) {
- var d = diffs[i-1];
- p.setBit(d, 1);
- if(d > 32) {
- p.hi = (p.hi & ~((1<<(d-32))-1))>>>0;
- var e = bitstream.read(d - 32);
- p.hi = (p.hi | e)>>>0;
- p.lo = bitstream.read(32);
- } else {
-
- if(d == 32) {
- p.lo = bitstream.read(d);
- } else {
- var e = bitstream.read(d);
- p.lo = (p.lo & ~((1<>>0;
- p.lo = (p.lo | e)>>>0;
- }
- }
- p.toPoint(t.min, step, t.coords, count);
- count += 3;
- }
-},
-
-decodeFaces: function() {
- if(!this.node.nface) return;
-
- this.vertex_count = 0;
- var start = 0;
- for(var p = 0; p < this.patches.length; p++) {
- var end = this.patches[p];
- this.decodeConnectivity(end - start, start*3);
- start = end;
- }
- //dequantize positions
- var tot = this.node.nvert*3;
- var coords = this.coords;
- var stack = this.stack;
- for(var i = 0; i < tot; ) {
- coords[i] = (coords[i] + stack[3])*stack[6]; i++;
- coords[i] = (coords[i] + stack[4])*stack[6]; i++;
- coords[i] = (coords[i] + stack[5])*stack[6]; i++;
- }
- if(this.sig.texcoords) {
- var t_tot = this.node.nvert*2;
- var t_coords = this.texcoords;
- for(var i = 0; i < tot; ) {
- t_coords[i] = (t_coords[i] + stack[9])*stack[11]; i++;
- t_coords[i] = (t_coords[i] + stack[10])*stack[11]; i++;
- }
- }
-},
-
-decodeNormals: function() {
- var norm_q = this.stream.readChar();
-
- var dtunstall = new Tunstall;
- var diffs = dtunstall.decompress(this.stream);
-
- var stunstall = new Tunstall;
- var signs = stunstall.decompress(this.stream);
- var bitstream = this.stream.readBitStream();
-
- var side = (1<<(16 - norm_q))>>>0;
- var diffcount = 0;
- var signcount = 0;
-
- if(!this.sig.indices) {
- for(var k = 0; k < 2; k++) {
- var on = 0;
- for(var i = 0; i < this.node.nvert; i++) {
- var d = this.decodeDiff(diffs[diffcount++], bitstream);
- on = on + d;
- this.normals[3*i + k] = on*side;
- }
- }
- for(var i = 0; i < this.node.nvert; i++) {
- var offset = i*3;
- var x = this.normals[offset + 0];
- var y = this.normals[offset + 1];
- var z = 32767.0*32767.0 - x*x - y*y;
-
- if(z < 0) z = 0;
- z = Math.sqrt(z);
- if(z > 32767) z = 32767;
- if(signs[i] == 0)
- z = -z;
- this.normals[offset + 2] = z;
- }
- return;
- }
-
- var boundary = this.markBoundary();
- this.computeNormals();
-
- if(this.sig.texcoords) //hack, fixing normals makes it worse actually
- return;
-
- var stat = 0;
- //get difference between original and predicted
- for(var i = 0; i < this.node.nvert; i++) {
- if(!boundary[i]) continue;
- var offset = i*3;
- var x = (this.normals[offset + 0]/side);
- var y = (this.normals[offset + 1]/side);
- var dx = this.decodeDiff(diffs[diffcount++], bitstream);
- var dy = this.decodeDiff(diffs[diffcount++], bitstream);
- x = (x + dx)*side;
- y = (y + dy)*side;
-
- var z = 32767.0*32767.0 - x*x - y*y;
-
- if(z < 0) z = 0;
- z = Math.sqrt(z);
- //sign
- if(z > 32767.0) z = 32767.0;
- var signbit = signs[signcount++];
-// if(this.normals[offset+2] < 0 != signbit)
- if((this.normals[offset+2] < 0 && signbit == 0) || (this.normals[offset+2] > 0 && signbit == 1))
- z = -z;
- this.normals[offset + 0] = x;
- this.normals[offset + 1] = y;
- this.normals[offset + 2] = z;
- }
-},
-
-decodeColors: function() {
- var color_q = [];
- for(var k = 0; k < 4; k++)
- color_q[k] = this.stream.readChar();
-
- var diffs = [];
- for(var k = 0; k < 4; k++) {
- var tunstall = new Tunstall;;
- diffs[k] = tunstall.decompress(this.stream);
- }
- var bitstream = this.stream.readBitStream();
-
- var count = 0;
- if(this.sig.indices) {
- for(var i = 0; i < this.node.nvert; i++) {
- var last = this.last[i]*4;
- var offset = i*4;
-
- for(var k = 0; k < 4; k++) {
- var c = this.decodeDiff(diffs[k][count], bitstream);
-
- if(last >= 0)
- c += this.colors[last + k];
- this.colors[offset] = c;
- offset++;
- }
- count++;
- }
- } else {
- for(var k = 0; k < 4; k++)
- this.colors[k] = this.decodeDiff(diffs[k][count], bitstream);
- count++;
-
- var offset = 4;
- for(var i = 1; i < this.node.nvert; i++) {
- for(var k = 0; k < 4; k++) {
- var d = this.decodeDiff(diffs[k][count], bitstream);
- this.colors[offset] = this.colors[offset-4] + d;
- offset ++;
- }
- count++;
- }
- }
-
- var steps = [];
- for(var k = 0; k < 4; k++)
- steps[k] = (1<<(8 - color_q[k]));
-
- //convert to rgb
- for(var i = 0; i < this.node.nvert; i++) {
- var offset = i*4;
-
- var e0 = this.colors[offset + 0] * steps[0];
- var e1 = this.colors[offset + 1] * steps[1];
- var e2 = this.colors[offset + 2] * steps[2];
-
- this.colors[offset + 0] = (e2 + e0)&0xff;
- this.colors[offset + 1] = e0;
- this.colors[offset + 2] = (e1 + e0)&0xff;
- }
-},
-
-//how to determine if a vertex is a boundary without topology:
-//for each edge a vertex is in, add or subtract the id of the other vertex depending on order
-//for internal vertices sum is zero.
-//unless we have strange configurations and a lot of sfiga, zero wont happen. //TODO think about this
-markBoundary: function() {
-// var boundary = new Uint8Array(this.node.nvert);
- var count = new Uint32Array(this.node.nvert);
-
- var offset = 0;
- for(var i = 0; i < this.node.nface; i++) {
- count[this.faces[offset + 0]] += this.faces[offset + 1] - this.faces[offset + 2];
- count[this.faces[offset + 1]] += this.faces[offset + 2] - this.faces[offset + 0];
- count[this.faces[offset + 2]] += this.faces[offset + 0] - this.faces[offset + 1];
- offset += 3;
- }
- return count;
-// for(var i = 0; i < this.node.nvert; i++)
-// if(count[i] != 0)
-// boundary[i] = true;
-// return boundary;
-},
-
-norm: function(buffer, a, b, c) { //a b c offsets in the buffer
- var ba0 = buffer[b+0] - buffer[a+0];
- var ba1 = buffer[b+1] - buffer[a+1];
- var ba2 = buffer[b+2] - buffer[a+2];
-
- var ca0 = buffer[c+0] - buffer[a+0];
- var ca1 = buffer[c+1] - buffer[a+1];
- var ca2 = buffer[c+2] - buffer[a+2];
-
- var p = [];
- p[0] = ba1*ca2 - ba2*ca1;
- p[1] = ba2*ca0 - ba0*ca2;
- p[2] = ba0*ca1 - ba1*ca0;
- return p;
-},
-
-normalize: function(buffer, offset) {
- var x = buffer[offset + 0];
- var y = buffer[offset + 1];
- var z = buffer[offset + 2];
- var n = Math.sqrt(x*x + y*y + z*z);
- if(n > 0) {
- buffer[offset + 0] = x/n;
- buffer[offset + 1] = y/n;
- buffer[offset + 2] = z/n;
- }
-},
-
-computeNormals:function() {
- var tmp_normals = new Float32Array(this.node.nvert*3);
-
- var offset = 0;
- for(var i = 0; i < this.node.nface; i++) {
- var a = 3*this.faces[offset + 0];
- var b = 3*this.faces[offset + 1];
- var c = 3*this.faces[offset + 2];
-
- var buffer = this.coords;
- var ba0 = buffer[b+0] - buffer[a+0];
- var ba1 = buffer[b+1] - buffer[a+1];
- var ba2 = buffer[b+2] - buffer[a+2];
-
- var ca0 = buffer[c+0] - buffer[a+0];
- var ca1 = buffer[c+1] - buffer[a+1];
- var ca2 = buffer[c+2] - buffer[a+2];
-
- var n0 = ba1*ca2 - ba2*ca1;
- var n1 = ba2*ca0 - ba0*ca2;
- var n2 = ba0*ca1 - ba1*ca0;
-
- tmp_normals[a + 0] += n0;
- tmp_normals[a + 1] += n1;
- tmp_normals[a + 2] += n2;
- tmp_normals[b + 0] += n0;
- tmp_normals[b + 1] += n1;
- tmp_normals[b + 2] += n2;
- tmp_normals[c + 0] += n0;
- tmp_normals[c + 1] += n1;
- tmp_normals[c + 2] += n2;
- offset += 3;
- }
-
- //normalize
- var offset = 0;
- for(var i = 0; i < this.node.nvert; i++) {
- var x = tmp_normals[offset + 0];
- var y = tmp_normals[offset + 1];
- var z = tmp_normals[offset + 2];
- var n = Math.sqrt(x*x + y*y + z*z);
- if(n > 0) {
- tmp_normals[offset + 0] = x/n;
- tmp_normals[offset + 1] = y/n;
- tmp_normals[offset + 2] = z/n;
- }
- this.normals[offset + 0] = tmp_normals[offset + 0]*32767;
- this.normals[offset + 1] = tmp_normals[offset + 1]*32767;
- this.normals[offset + 2] = tmp_normals[offset + 2]*32767;
- offset += 3;
- }
-},
-
-decodeDiff: function(diff, bitstream) {
- var val;
- if(diff == 0) {
- val = 1;
- } else {
- val = 1<<(diff);
- val |= bitstream.read(diff);
- };
- val--; //vall is always >= 1
- if(val & 0x1)
- val = -((val+1)>>1);
- else
- val = val>>1;
- return val;
-},
-
-/* an edge is: uint16_t face, uint16_t side, uint32_t prev, next, bool deleted
-I do not want to create millions of small objects, I will use aUint32Array.
-Problem is how long, sqrt(nface) we will over blow using nface.
-*/
-
-decodeConnectivity: function(length, start) {
-
- var t = this;
- var ctunstall = new Tunstall;
- var clers = ctunstall.decompress(this.stream);
- var cler_count = 0;
-
- var dtunstall = new Tunstall;
- var diffs = dtunstall.decompress(this.stream);
- var diff_count = 0;
-
- var tdiffs;
- var tdiff_count = 0;
- if(t.sig.texcoords) {
- var ttunstall = new Tunstall;
- tdiffs = ttunstall.decompress(this.stream);
- }
-
- var bitstream = this.stream.readBitStream(bitstream);
-
- var current_face = 0; //keep track of connected component start
- //t.vertex_count = 0;
- var front = new Uint32Array(this.node.nface*18);
- var front_count = 0; //count each integer so it's front_back*5
- function addFront(_v0, _v1, _v2, _prev, _next) {
- front[front_count++] = _v0;
- front[front_count++] = _v1;
- front[front_count++] = _v2;
- front[front_count++] = _prev;
- front[front_count++] = _next;
- front[front_count++] = 0; //deleted
- }
- function _next(t) {
- t++;
- if(t == 3) t = 0;
- return t;
- }
- function _prev(t) {
- t--;
- if(t == -1) t = 2;
- return t;
- }
-
- var delayed = [];
- var faceorder = [];
-
- var faces_count = start; //count indices in this.faces array
- var totfaces = length;
-// var estimated = [0, 0, 0]; //no! use stack.
- var stack = this.stack;
- var coords = this.coords;
- var texcoords = this.texcoords;
- var hasTexCoords = t.sig.texcoords;
-
- while(totfaces > 0) {
- if(!faceorder.length && !delayed.length) {
- if(current_face == this.node.nface) break; //no more faces to encode exiting
-
- stack[0] = stack[1] = stack[2] = 0;
- stack[7] = stack[8] = 0; //texcoords
- var last_index = -1;
- var index = [];
- for(var k = 0; k < 3; k++) {
- this.last[this.last_count++] = last_index;
- var diff = diffs[diff_count++];
- var tdiff = diff && hasTexCoords? tdiffs[tdiff_count++] : 0;
- var v = this.decodeVertex(bitstream, diff, tdiff);
- index[k] = v;
- this.faces[faces_count++] = v;
- stack[0] = coords[v*3];
- stack[1] = coords[v*3+1];
- stack[2] = coords[v*3+2];
- if(t.sig.texcoords) {
- stack[7] = texcoords[v*2];
- stack[8] = texcoords[v*2+1];
- }
- last_index = v;
- }
- var current_edge = front_count;
- for(var k = 0; k < 3; k++) {
- faceorder.push(front_count);
- front[front_count++] = index[_next(k)];
- front[front_count++] = index[_prev(k)];
- front[front_count++] = index[k];
- front[front_count++] = current_edge + _prev(k)*6;
- front[front_count++] = current_edge + _next(k)*6;
- front_count++;
-// addFront(index[_next(k)], index[_prev(k)], index[k], current_edge + _prev(k)*6, current_edge + _next(k)*6);
- }
- current_face++;
- totfaces--;
- continue;
- }
- var f;
- if(faceorder.length)
- f = faceorder.shift();
- else
- f = delayed.pop();
-
- var edge_start = f;
-
- if(front[edge_start + 5]) continue; //deleted
- front[edge_start + 5] = 1; //set edge as deleted anyway
-
- var c = clers[cler_count++];
- if(c == 4) continue; //BOUNDARY
-
- var v0 = front[edge_start + 0];
- var v1 = front[edge_start + 1];
- var v2 = front[edge_start + 2];
- var prev = front[edge_start + 3];
- var next = front[edge_start + 4];
-
- var first_edge = front_count; //points to new edge to be inserted
- var opposite = -1;
- if(c == 0) { //VERTEX
- //predict position based on v0, v1 and v2
- for(var k = 0; k < 3; k++)
- stack[k] = coords[v0*3 + k] + coords[v1*3 + k] - coords[v2*3 + k];
-
- if(hasTexCoords)
- for(var k = 0; k < 2; k++)
- stack[7+k] = texcoords[v0*2 + k] + texcoords[v1*2 + k] - texcoords[v2*2 + k];
-
- var diff = diffs[diff_count++];
- var tdiff = diff && hasTexCoords? tdiffs[tdiff_count++] : 0;
- opposite = this.decodeVertex(bitstream, diff, tdiff);
- if(diff != 0)
- this.last[this.last_count++] = v1;
-
- front[prev + 4] = first_edge;
- front[next + 3] = first_edge + 6;
- faceorder.unshift(front_count);
-
- front[front_count++] = v0;
- front[front_count++] = opposite;
- front[front_count++] = v1;
- front[front_count++] = prev;
- front[front_count++] = first_edge+6;
- front_count++;
-// addFront(v0, opposite, v1, prev, first_edge + 6);
-
- faceorder.push(front_count);
-
- front[front_count++] = opposite;
- front[front_count++] = v1;
- front[front_count++] = v0;
- front[front_count++] = first_edge;
- front[front_count++] = next;
- front_count++;
-// addFront(opposite, v1, v0, first_edge, next);
-
- } else if(c == 3) { //END
- front[prev + 5] = 1;
- front[next + 5] = 1;
- front[front[prev + 3] + 4] = front[next + 4];
- front[front[next + 4] + 3] = front[prev + 3];
- opposite = front[prev + 0];
-
- } else if(c == 1) { //LEFT
- front[prev + 5] = 1; //deleted
- front[front[prev + 3] + 4] = first_edge;
- front[next + 3] = first_edge;
- opposite = front[prev + 0];
-
- faceorder.unshift(front_count);
-
- front[front_count++] = opposite;
- front[front_count++] = v1;
- front[front_count++] = v0;
- front[front_count++] = front[prev +3];
- front[front_count++] = next;
- front_count++;
-// addFront(opposite, v1, v0, front[prev + 3], next);
-
- } else if(c == 2) { //RIGHT
- front[next + 5] = 1;
- front[front[next + 4] + 3] = first_edge;
- front[prev + 4] = first_edge;
- opposite = front[next + 1];
-
-
- faceorder.unshift(front_count);
-
- front[front_count++] = v0;
- front[front_count++] = opposite;
- front[front_count++] = v1;
- front[front_count++] = prev;
- front[front_count++] = front[next+4];
- front_count++;
-// addFront(v0, opposite, v1, prev, front[next + 4]);
-
- } else if(c == 5) { //DELAY
- front[edge_start + 5] = 0;
- delayed.push(edge_start);
- continue;
- }
- this.faces[faces_count++] = v1;
- this.faces[faces_count++] = v0;
- this.faces[faces_count++] = opposite;
- totfaces--;
- }
-},
-
-decodeVertex: function(bitstream, diff, tdiff) {
- if(diff == 0)
- return bitstream.read(16);
-
- var v = this.vertex_count++;
-
- var max = 1<<(diff-1);
-
- for(var k = 0; k < 3; k++) {
- var d = bitstream.read(diff) - max;
- this.coords[v*3+k] = this.stack[k] + d; //stack 0-3 is used as extimated
- }
- if(this.sig.texcoords) {
- var tmax = 1<<(tdiff-1);
- for(var k = 0; k < 2; k++) {
- var d = bitstream.read(tdiff) - tmax;
- this.texcoords[v*2+k] = this.stack[7+k] + d; //stack 7-9 is used as extimated
- }
- }
- return v;
-},
-
-decodeDiff: function(diff, bitstream) {
- var val;
- if(diff == 0) {
- return 0;
- }
- val = 1<>>= 1;
- else
- val = -(val>>>1);
-
- return val;
-}
-
-};
-
-var tot = 0;
-
-
diff --git a/all_tools/js/nexus.js b/all_tools/js/nexus.js
deleted file mode 100644
index a6a5442..0000000
--- a/all_tools/js/nexus.js
+++ /dev/null
@@ -1,1616 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-var Nexus = { };
-
-Nexus.LITTLE_ENDIAN_DATA = true;
-Nexus.PADDING = 256;
-
-Nexus.Debug = {
- nodes: false, //color each node
- culling: false, //visibility culling disabled
- draw: false, //final rendering call disabled
- extract: false, //no extraction
- request: false, //no network requests
- worker: false //no web workers
-}
-
-Nexus.Attribute = function () {
- this.size = 0;
- this.type = Nexus.Attribute.NONE;
- this.glType = Nexus.Attribute._typeGLMap[this.type];
- this.normalized = Nexus.Attribute._typeNormalized[this.type];
- this.stride = 0;
- this.offset = 0;
-};
-
-Nexus.Attribute.NONE = 0;
-Nexus.Attribute.BYTE = 1;
-Nexus.Attribute.UNSIGNED_BYTE = 2;
-Nexus.Attribute.SHORT = 3;
-Nexus.Attribute.UNSIGNED_SHORT = 4;
-Nexus.Attribute.INT = 5;
-Nexus.Attribute.UNSIGNED_INT = 6;
-Nexus.Attribute.FLOAT = 7;
-Nexus.Attribute.DOUBLE = 8;
-
-Nexus.Attribute._typeSizeMap = { };
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.NONE ] = 0;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.BYTE ] = 1;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.UNSIGNED_BYTE ] = 1;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.SHORT ] = 2;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.UNSIGNED_SHORT] = 2;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.INT ] = 4;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.UNSIGNED_INT ] = 4;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.FLOAT ] = 4;
-Nexus.Attribute._typeSizeMap[Nexus.Attribute.DOUBLE ] = 8;
-
-Nexus.Attribute._typeGLMap = { };
-Nexus.Attribute._typeGLMap[Nexus.Attribute.NONE ] = WebGLRenderingContext.prototype.NONE;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.BYTE ] = WebGLRenderingContext.prototype.BYTE;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.UNSIGNED_BYTE ] = WebGLRenderingContext.prototype.UNSIGNED_BYTE;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.SHORT ] = WebGLRenderingContext.prototype.SHORT;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.UNSIGNED_SHORT] = WebGLRenderingContext.prototype.UNSIGNED_SHORT;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.INT ] = WebGLRenderingContext.prototype.INT;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.UNSIGNED_INT ] = WebGLRenderingContext.prototype.UNSIGNED_INT;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.FLOAT ] = WebGLRenderingContext.prototype.FLOAT;
-Nexus.Attribute._typeGLMap[Nexus.Attribute.DOUBLE ] = WebGLRenderingContext.prototype.DOUBLE;
-
-Nexus.Attribute._typeNormalized = { };
-Nexus.Attribute._typeNormalized[Nexus.Attribute.NONE ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.BYTE ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.UNSIGNED_BYTE ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.SHORT ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.UNSIGNED_SHORT] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.INT ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.UNSIGNED_INT ] = true;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.FLOAT ] = false;
-Nexus.Attribute._typeNormalized[Nexus.Attribute.DOUBLE ] = false;
-
-Nexus.Attribute.prototype = {
- get isNull() {
- return (this.type == Nexus.Attribute.NONE);
- },
-
- get byteLength() {
- return (Nexus.Attribute._typeSizeMap[this.type] * this.size);
- },
-
- import : function (view, offset, littleEndian) {
- var s = 0;
- this.type = view.getUint8(offset + s, littleEndian); s += Uint8Array.BYTES_PER_ELEMENT;
- this.size = view.getUint8(offset + s, littleEndian); s += Uint8Array.BYTES_PER_ELEMENT;
-
- this.glType = Nexus.Attribute._typeGLMap[this.type];
- this.normalized = Nexus.Attribute._typeNormalized[this.type];
- this.stride = Nexus.Attribute._typeSizeMap[this.type] * this.size;
- this.offset = 0;
-
- return s;
- }
-};
-
-Nexus.Attribute.SIZEOF = 2 * Uint8Array.BYTES_PER_ELEMENT;
-
-Nexus.Element = function () {
- this.attributes = new Array(8);
- for (var i=0; i<8; ++i) {
- this.attributes[i] = new Nexus.Attribute();
- }
- this.lastAttribute = -1;
-};
-
-Nexus.Element.prototype = {
- get byteLength() {
- var s = 0;
- for (var i=0; i 0);
- },
-
- reset : function () {
- this.magic = 0;
- this.version = 0;
- this.verticesCount = 0;
- this.facesCount = 0;
- this.signature = new Nexus.Signature();
- this.nodesCount = 0;
- this.patchesCount = 0;
- this.texturesCount = 0;
- this.sphere = new Nexus.Sphere3f();
- },
-
- import : function (view, offset, littleEndian) {
- this.reset();
-
- var s = 0;
-
- this.magic = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- if (this.magic != Nexus.Header.MAGIC) return 0;
-
- this.version = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- this.verticesCount = this._getUint64(view, offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT * 2;
- this.facesCount = this._getUint64(view, offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT * 2;
- s += this.signature.import(view, offset + s, littleEndian);
- this.nodesCount = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- this.patchesCount = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- this.texturesCount = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- s += this.sphere.import(view, offset + s, littleEndian);
-
- return s;
- }
-};
-
-Nexus.Cone3s = function () {
- this.n = [0, 0, 0, 0];
-};
-
-Nexus.Cone3s.SIZEOF = 4 * Uint16Array.BYTES_PER_ELEMENT;
-
-Nexus.Cone3s.prototype = {
- backFace : function (sphere, view) {
- var n = this.n;
-
- var norm = [n[0] / 32766.0, n[1] / 32766.0, n[2] / 32766.0];
- var d = [0.0, 0.0, 0.0];
- var f = 0.0;
- var dd = 0.0;
-
- for (var i=0; i<3; ++i) {
- d[i] = (sphere.center[i] - norm[i] * sphere.radius) - view[i];
- norm[i] *= n[3] / 32766.0;
- f += d[i] * norm[i];
- dd = d[i] * d[i];
- }
-
- return !((f < 0.001) || ((f * f) < dd));
- },
-
- frontFace : function (sphere, view) {
- var n = this.n;
-
- var norm = [n[0] / 32766.0, n[1] / 32766.0, n[2] / 32766.0];
- var d = [0.0, 0.0, 0.0];
- var f = 0.0;
- var dd = 0.0;
-
- for (var i=0; i<3; ++i) {
- d[i] = (sphere.center[i] + norm[i] * sphere.radius) - view[i];
- norm[i] *= n[3] / 32766.0;
- f += -d[i] * norm[i];
- dd = d[i] * d[i];
- }
-
- return !((f < 0.001) || ((f * f) < dd));
- },
-
- import : function (view, offset, littleEndian) {
- var s = 0;
- for (var i=0; i<4; ++i) {
- this.n[i] = view.getInt16(offset + s, littleEndian);
- s += Uint16Array.BYTES_PER_ELEMENT;
- }
- return s;
- }
-};
-
-Nexus.Node = function() {
- this.offset = 0;
- this.verticesCount = 0;
- this.facesCount = 0;
- this.error = 0.0;
- this.cone = new Nexus.Cone3s();
- this.sphere = new Nexus.Sphere3f();
- this.tightRadius = 0.0;
- this.firstPatch = 0;
-
- // computed
- this.lastPatch = 0;
- this.lastByte = 0;
-};
-
-Nexus.Node.SIZEOF = 2 * Uint32Array.BYTES_PER_ELEMENT + 2 * Uint16Array.BYTES_PER_ELEMENT + 2 * Float32Array.BYTES_PER_ELEMENT + Nexus.Sphere3f.SIZEOF + Nexus.Cone3s.SIZEOF;
-
-Nexus.Node.prototype = {
- get isEmpty() {
- return (this.end == this.outBegin);
- },
-
- import : function (view, offset, littleEndian) {
- var s = 0;
- this.offset = Nexus.PADDING * view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- this.verticesCount = view.getUint16(offset + s, littleEndian); s += Uint16Array.BYTES_PER_ELEMENT;
- this.facesCount = view.getUint16(offset + s, littleEndian); s += Uint16Array.BYTES_PER_ELEMENT;
- this.error = view.getFloat32(offset + s, littleEndian); s += Float32Array.BYTES_PER_ELEMENT;
- s += this.cone.import(view, offset + s, littleEndian);
- s += this.sphere.import(view, offset + s, littleEndian);
- this.tightRadius = view.getFloat32(offset + s, littleEndian); s += Float32Array.BYTES_PER_ELEMENT;
- this.firstPatch = view.getUint32(offset + s, littleEndian); s += Uint32Array.BYTES_PER_ELEMENT;
- return s;
- }
-};
-
-Nexus.NodeIndex = function() {
-};
-
-Nexus.NodeIndex.prototype = {
- get length() {
- return this.items.length;
- },
-
- get sink() {
- return (this.items.length - 1);
- },
-
- import : function (nodesCount, view, offset, littleEndian) {
- this.items = new Array(nodesCount);
- var s = 0;
- for (var i=0; i 0) {
- this.content[0] = end;
- this.sinkDown(0);
- }
- return result;
- },
- size: function() { return this.content.length; },
- bubbleUp: function(n) {
- var element = this.content[n];
- while (n > 0) {
- var parentN = ((n+1)>>1) -1;
- var parent = this.content[parentN];
- if(parent.node.renderError > element.node.renderError)
- break;
- this.content[parentN] = element;
- this.content[n] = parent;
- n = parentN;
- }
- },
-
- sinkDown: function(n) {
- var length = this.content.length;
- var element = this.content[n]
-
- while(true) {
- var child2N = (n + 1) * 2;
- var child1N = child2N - 1;
- var swap = null;
- if (child1N < length) {
- var child1 = this.content[child1N];
- if(child1.node.renderError > element.node.renderError)
- swap = child1N;
- }
- if (child2N < length) {
- var child2 = this.content[child2N];
- if (child2.node.renderError > (swap == null ? element.node.renderError : child1.node.renderError))
- swap = child2N;
- }
-
- if (swap == null) break;
-
- this.content[n] = this.content[swap];
- this.content[swap] = element;
- n = swap;
- }
- }
-};
-
-Nexus.Plane3f = function (p0, p1, p2) {
- this._normal = SglVec3.normalize(SglVec3.cross(SglVec3.sub(p1, p0), SglVec3.sub(p2, p0)));
- this._offset = SglVec3.dot(p0, this._normal);
-};
-
-Nexus.Plane3f.prototype = {
- get normal() {
- return this._normal.slice();
- },
-
- get offset() {
- return this._offset;
- },
-
- signedDistanceToPoint : function (p) {
- return (SglVec3.dot(this._normal, p) - this._offset);
- }
-};
-
-Nexus.Renderer = function (gl) {
- this._gl = gl;
-
- this.targetError = Nexus.Renderer.DEFAULT_TARGET_ERROR;
- this._targetFps = null; //Nexus.Renderer.DEFAULT_TARGET_FPS;
- this._maxPendingRequests = Nexus.Renderer.DEFAULT_MAX_PENDING_REQUESTS;
- this._maxCacheSize = Nexus.Renderer.DEFAULT_CACHE_SIZE;
- this.drawBudget = Nexus.Renderer.DEFAULT_DRAW_BUDGET;
- this._minDrawBudget = Nexus.Renderer.DEFAULT_DRAW_BUDGET / 4;
- this._onUpdate = null;
- this._onSceneReady = null;
-
- this._mmat = SglMat4.identity();
- this._vmat = SglMat4.identity();
- this._pmat = SglMat4.identity();
- this._vp = [ 0.0, 0.0, 1.0, 1.0 ];
-
- this._mode = 0;
-
- this._reset();
-
- this._updateView();
-};
-
-Nexus.Renderer.STATUS_NONE = 0;
-Nexus.Renderer.STATUS_OPENING = 1;
-Nexus.Renderer.STATUS_OPEN = 2;
-
-Nexus.Renderer.DEFAULT_TARGET_ERROR = 1.0;
-Nexus.Renderer.DEFAULT_TARGET_FPS = 20;
-Nexus.Renderer.DEFAULT_MAX_PENDING_REQUESTS = 3; // 3 is good for uncompressed online work
-Nexus.Renderer.DEFAULT_CACHE_SIZE = 256 * 1024 * 1024;
-Nexus.Renderer.DEFAULT_DRAW_BUDGET = 2.0 * 1024 * 1024;
-
-Nexus.Renderer._NODE_NONE = 0;
-Nexus.Renderer._NODE_PENDING = 1;
-Nexus.Renderer._NODE_READY = 2;
-
-Nexus.Renderer._sortPatchesFunction = function (a, b) {
- return ((a.frame != b.frame) ? (b.frame - a.frame) : (b.error - a.error));
-};
-
-Nexus.Renderer._sortNodesFunction = function (a, b) {
- return a.node.renderError - b.node.renderError;
-};
-
-Nexus.Renderer._sortNodeCacheFunction = function (a, b) {
- return ((a.renderFrame != b.renderFrame) ? (b.renderFrame - a.renderFrame) : (b.renderError - a.renderError));
- //return b.renderError - a.renderError;
-};
-
-Nexus.Renderer.prototype = {
- _reset : function () {
- this._status = Nexus.Renderer.STATUS_NONE;
-
- this._inBegin = false;
-
- this._url = null;
-
- this._header = null;
- this._nodes = null;
- this._patches = null;
- this._textures = null;
-
- this._visitedNodes = null;
- this._blockedNodes = null;
- this._selectedNodes = null;
- this._drawSize = 0; //number of triangle to be rendered
- this._rendered = 0; //currently rendered triangles
- this._estimatedTpS = 200000; //in million triangles
- this._cacheSize = 0;
- this._cachedNodes = null;
- this._readyNodes = null;
- this._frame = 0;
-
- this._pendingRequests = 0;
- this._candidateNodes = null;
- this._redrawOnNewNodes = true;
-
- var t = this;
- var path;
- $('script').each(function(a) { var str = $(this).attr('src'); if(!str) return; if(str.search('nexus.js') >= 0) path = str; });
- path = path.replace('nexus.js', 'meshcoder_worker.js');
- this._worker = new Worker(path);
- this._worker.onmessage = function(e) { t._workerFinished(e); };
-
- /**Safari PATCH**/
- /**/(sayswho()[0]==='Safari' && sayswho()[1]<9) ? (this._cachePatch = true) : (this._cachePatch = false);
- /**Safari PATCH**/
- },
-
- _requestHeader : function () {
- var offset = 0;
- var size = Nexus.Header.SIZEOF;
-
- var that = this;
- var r = new XMLHttpRequest();
- r.open('GET', this.url(), true);
- r.responseType = 'arraybuffer';
- r.setRequestHeader("Range", "bytes=" + offset + "-" + (offset + size -1));
- r.onload = function () {
- that._handleHeader(r.response);
- that._requestIndex();
- }
- r.send();
- },
-
- _handleHeader : function (buffer) {
- var view = new DataView(buffer);
- var offset = 0;
- var littleEndian = Nexus.LITTLE_ENDIAN_DATA;
-
- var header = new Nexus.Header();
- header.import(view, offset, littleEndian);
- this._header = header;
- },
-
- _requestIndex : function () {
- var header = this._header;
- var offset = Nexus.Header.SIZEOF;
- var size = header.nodesCount * Nexus.Node.SIZEOF + header.patchesCount * Nexus.Patch.SIZEOF + header.texturesCount * Nexus.Texture.SIZEOF;
-
- var that = this;
- var r = new XMLHttpRequest();
- r.open('GET', this.url(), true);
- r.responseType = 'arraybuffer';
- r.setRequestHeader("Range", "bytes=" + offset + "-" + (offset + size -1));
- r.onload = function () {
- that._handleIndex(r.response);
- that._openReady();
- }
- r.send();
- },
-
- _handleIndex : function (buffer) {
- var header = this._header;
- var view = new DataView(buffer);
- var offset = 0;
- var littleEndian = Nexus.LITTLE_ENDIAN_DATA;
-
- var offset = 0;
-
- this._nodes = new Nexus.NodeIndex();
- offset += this._nodes.import(header.nodesCount, view, offset, littleEndian);
-
- this._patches = new Nexus.PatchIndex();
- offset += this._patches.import(header.patchesCount, view, offset, littleEndian);
-
- this._textures = new Nexus.TextureIndex();
- offset += this._textures.import(header.texturesCount, view, offset, littleEndian);
-
- this.renderMode = ["POINT"];
- if (header.signature.face.hasIndex) this.renderMode.unshift("FILL");
-
- this.setPrimitiveMode(this.renderMode[0]);
-
- this.hasPosition = header.signature.vertex.hasPosition;
- this.hasNormal = header.signature.vertex.hasNormal;
- this.hasColor = header.signature.vertex.hasColor;
- this.hasTexture = header.signature.vertex.hasTexCoord;
- },
-
- _openReady : function() {
- var nodesCount = this._nodes.length;
- var nodes = this._nodes.items;
- for (var i=0; i maxSize) {
- firstVictim = i;
- break;
- }
- if (node.request) {
- newNodes.push(node);
- }
- else {
- size += nsize
- }
- }
-
- if (firstVictim >= 0) {
- for (var i=firstVictim, n=newCache.length; i this.drawBudget) {
-// console.log("Stop because of draw budget: " + this._drawSize + " > " + this.drawBudget);
- return false;
- }
-
-
- var sphere = node.sphere
- if(this._hierarchyVisit_isVisible(sphere.center, node.tightRadius))
- this._drawSize += node.verticesCount*0.8;
- //we are adding half of the new faces. (but we are using the vertices so *2)
-
- if(node.status != Nexus.Renderer._NODE_READY) {
-// console.log("Stop because node not ready:" + node.status);
-// here: mark a redraw when new nodes available.
- this._redrawOnNewNodes = true;
- return false;
- }
- return true;
- },
-
- _hierarchyVisit_insertChildren : function (n, visitQueue, block) {
- var nodes = this._nodes.items;
- var node = nodes[n];
- var patches = this._patches.items;
- var blockedNodes = this._blockedNodes;
- for(var i = node.firstPatch; i < node.lastPatch; ++i) {
- var patch = patches[i];
- var child = patch.node;
- if (block) blockedNodes[child] = 1;
- this._hierarchyVisit_insertNode(child, visitQueue);
- }
- },
-
- _hierarchyVisit : function () {
- if(Nexus.Debug.extract == true)
- return;
- this._redrawOnNewNodes = false;
-
- var visitQueue = new Nexus.PriorityQueue();
-
- var nodesCount = this._nodes.length;
- for(var i = 0; i < nodesCount; i++) {
- this._visitedNodes[i] = 0;
- this._blockedNodes[i] = 0;
- this._selectedNodes[i] = 0;
- }
- this._hierarchyVisit_insertNode(0, visitQueue);
-
- var nodes = this._nodes.items;
-
- var candidatesCount = 0;
- this._candidateNodes = [ ];
- var candidateNodes = this._candidateNodes;
-
- this.currentError = 1e20;
- this._drawSize = 0;
- var count = 0;
- while (visitQueue.size() && (count < this._maxPendingRequests)) {
- var nodeData = visitQueue.pop();
- var n = nodeData.index;
- var node = nodeData.node;
- if ((candidatesCount < this._maxPendingRequests) && (node.status == Nexus.Renderer._NODE_NONE)) {
- candidatesCount++;
- candidateNodes.push(node);
- }
- var blocked = this._blockedNodes[n] || !this._hierarchyVisit_expandNode(nodeData);
- if (blocked) {
- count++;
- }
- else {
- this._selectedNodes[n] = 1;
- this.currentError = nodeData.node.renderError;
- }
-
- this._hierarchyVisit_insertChildren(n, visitQueue, blocked);
- }
- },
-
- _createNodeHandler : function (node) {
- //compressed use worker:
- var that = this;
- return function () {
-// console.log("received node: " + node.index);
- node.request.buffer = node.request.response;
-
- var compressed = Nexus.Signature.MECO + Nexus.Signature.CTM1 + Nexus.Signature.CTM2;
- if(!Nexus.Debug.worker && that._header.signature.flags & compressed) {
- var sig = {
- texcoords: that._header.signature.vertex.hasTexCoord,
- normals: that._header.signature.vertex.hasNormal,
- colors: that._header.signature.vertex.hasColor,
- indices: that._header.signature.face.hasIndex
- };
- var _node = {
- index: node.index,
- nvert: node.verticesCount,
- nface: node.facesCount,
- firstPatch: 0,
- lastPatch: node.lastPatch - node.firstPatch,
- buffer: node.request.response
- };
- var p = [];
- for(var k = node.firstPatch; k < node.lastPatch; k++)
- p.push(that._patches.items[k].lastTriangle);
- if(that._header.signature.flags & Nexus.Signature.MECO)
- that._worker.postMessage({signature:sig, node:_node, patches:p });
- } else {
- that._workerFinished({data: {index:node.index, buffer:node.request.response}});
- }
- }
- },
-
- _workerFinished: function(_node) {
- var node = this._nodes.items[_node.data.index];
- node.buffer = _node.data.buffer;
- this._readyNodes.push(node);
- if(this._redrawOnNewNodes) { //redraw only if new nodes might improve rendering
- this._signalUpdate();
- }
- },
-
- _createTextureHandler : function (tex) {
- var that = this;
-
- return function () {
- //TODO USE REF COUNTER INSTEAD OF LIST BOTH FOR NODES AND FOR TEXTURES
- var blob = tex.request.response;
- var urlCreator = window.URL || window.webkitURL;
- tex.img = document.createElement('img');
- tex.img.onerror = function(e) { console.log("Failed loading texture."); };
- tex.img.src = urlCreator.createObjectURL(blob);
-
- tex.img.onload = function() {
- urlCreator.revokeObjectURL(tex.img.src);
-
- var gl = that._gl;
- tex.texture = gl.createTexture();
- gl.bindTexture(gl.TEXTURE_2D, tex.texture);
- var s = gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, tex.img);
- 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_T, gl.CLAMP_TO_EDGE);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- gl.bindTexture(gl.TEXTURE_2D, null);
-
- tex.status = Nexus.Renderer._NODE_READY;
- //find all nodes pending
- for(var i = 0; i < tex.nodes.length; i++) {
- var node = tex.nodes[i];
- if(node.vbo === null) continue; //not loaded still
- var isReady = true;
- for(var k = node.firstPatch; k < node.lastPatch; ++k) {
- var patch = that._patches.items[k];
- if(patch.texture == 0xffffffff) continue;
- var t = that._textures.items[patch.texture];
- if(t.status != Nexus.Renderer._NODE_READY) {
- isReady = false;
- break;
- }
- }
- if(isReady) {
- node.status = Nexus.Renderer._NODE_READY;
- //WAKEUP CALL DRAFT
- that._signalUpdate();
- }
- }
- };
- }
- },
-
- _requestNodes : function () {
- if(Nexus.Debug.request) {
- this._candidateNodes = [];
- return;
- }
- var candidateNodes = this._candidateNodes;
- if (candidateNodes.length <= 0) return;
-
- var cachedNodes = this._cachedNodes.slice();
- cachedNodes.sort(Nexus.Renderer._sortNodeCacheFunction);
-
- var nodesToRequest = 0;
- var cacheSize = this._cacheSize;
- for (var i=0, n=candidateNodes.length; i=0; --j) {
- var p = cachedNodes[j];
- var psize = p.lastByte - p.offset + 1;
- k = j;
- if (Nexus.Renderer._sortNodeCacheFunction(c, p) >= 0) break;
- s += psize;
- freed += psize;
- if (s >= csize) break;
- }
- }
-
- if (s >= csize) {
- nodesToRequest++;
- cachedNodes = cachedNodes.slice(0, k);
- cachedNodes.push(c);
- cacheSize -= freed;
- cacheSize += csize;
- }
- else {
- break;
- }
- }
-
- var that = this;
- var url = this.url();
- for (var i=0; i 1) pointsize = 1;
- gl.vertexAttrib1fv(Nexus.VertexElement.DATA0, [pointsize]);
- }
- if (Nexus.Debug.draw) continue;
-
- //point cloud do not need patches
- if(this._mode == 0) {
- var fraction = (node.renderError/this.currentError - 1);
- if(fraction > 1) fraction = 1;
-
- var count = fraction * (node.verticesCount);
- if(count!=0) {
- gl.drawArrays(gl.POINTS, 0, count);
- this._rendered += count;
- }
- continue;
- }
-
- //concatenate renderings to remove useless calls. except we have textures.
- var first = 0;
- var last = 0;
- for (var p = node.firstPatch; p < node.lastPatch; ++p) {
- var patch = patches[p];
-
- if(!selectedNodes[patch.node]) { //skip this patch
- last = patch.lastTriangle;
- if(p < node.lastPatch-1) //if textures we do not join. TODO: should actually check for same texture of last one.
- continue;
- }
- if(last > first) {
- //here either we skip or is the last node
-
- if(patch.texture != 0xffffffff && patch.texture != last_texture) { //bind texture
- var tex = this._textures.items[patch.texture].texture;
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, tex);
- var error = gl.getError();
- }
- gl.glDrawElements(gl.TRIANGLES, (last - first) * 3, gl.UNSIGNED_SHORT, first * 3 * Uint16Array.BYTES_PER_ELEMENT);
- this._rendered += last - first;
- }
- first = patch.lastTriangle;
- }
- }
-
- for (var i = 0; i < 4; ++i) {
- if (vertexAttributes[order[i]].isNull) continue;
- gl.disableVertexAttribArray(order[i]);
- }
-
- SglVertexBuffer.unbind(gl);
- SglIndexBuffer.unbind(gl);
- },
-
- begin : function () {
- if (!this.isOpen) return;
- if (this.inBegin) return;
- this._inBegin = true;
- if (this._header.nodesCount <= 0) return;
- this._prepare();
- },
-
- end : function () {
- if (!this.inBegin) return;
- this._frame++;
- this._inBegin = false;
- },
-
- render : function () {
- if (!this.inBegin) return;
- this._beginRender();
- this._render();
- this._endRender();
- },
-
- setPrimitiveMode : function (mode) {
- switch(mode) {
- case "POINT":
- this._mode = 0;
- break;
- case "FILL":
- this._mode = 4;
- break;
- default:
- this._mode = 0;
- }
- }
-};
-
-sayswho = function() {
- var ua= navigator.userAgent, tem,
- M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || [];
- if(/trident/i.test(M[1])){
- tem= /\brv[ :]+(\d+)/g.exec(ua) || [];
- return 'IE '+(tem[1] || '');
- }
- if(M[1]=== 'Chrome'){
- tem= ua.match(/\b(OPR|Edge)\/(\d+)/);
- if(tem!= null) return tem.slice(1).join(' ').replace('OPR', 'Opera');
- }
- M= M[2]? [M[1], M[2]]: [navigator.appName, navigator.appVersion, '-?'];
- if((tem= ua.match(/version\/(\d+)/i))!= null) M.splice(1, 1, tem[1]);
- return M;
-};
diff --git a/all_tools/js/ply.js b/all_tools/js/ply.js
deleted file mode 100644
index 305b9c3..0000000
--- a/all_tools/js/ply.js
+++ /dev/null
@@ -1,1037 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-var parsePly = (function(){
- var canonicTypes = {
- "char" : "int8",
- "int8" : "int8",
- "uchar" : "uint8",
- "uint8" : "uint8",
- "short" : "int16",
- "int16" : "int16",
- "ushort" : "uint16",
- "uint16" : "uint16",
- "int" : "int32",
- "int32" : "int32",
- "uint" : "uint32",
- "uint32" : "uint32",
- "float" : "float32",
- "float32" : "float32",
- "double" : "float64",
- "float64" : "float64"
- };
-
- function trim(s) {
- var r = s;
- var n = r.length;
- var i = 0;
- var blanks = " \n\r\t";
- while ((i < n) && (blanks.indexOf(r.charAt(i)) >= 0)) { i++; }
- r = r.substring(i, r.length);
- i = r.length - 1;
- while ((i > 0) && (blanks.indexOf(r.charAt(i)) >= 0)) { i--; }
- r = r.substring(0, i+1);
- return r;
- }
-
- function extractHeader(data) {
- if (!data || !data.view || !data.view.buffer) return null;
-
- var u8 = new Uint8Array(data.view.buffer);
- var endHeaderToken = "end_header";
- var header = "";
- var found = false;
- var currC = null;
- var prevC = null;
- var pos = data.pos;
- var p = 0;
- var n = 0;
-
- for (pos=0, n=u8.byteLength; pos= endHeaderToken.length) {
- p = pos - endHeaderToken.length;
- if (prevC == "\r") p--;
- if (header.substring(p, p + endHeaderToken.length) == endHeaderToken) {
- found = true;
- break;
- }
- }
- }
- prevC = currC;
- }
-
- data.pos = pos;
-
- if (!found) {
- return null;
- }
-
- data.pos++;
- return header;
- }
-
- function splitHeader(header) {
- var lines = header.split("\n");
- var trimmed = [ ];
- var tokens = null;
- var s = null;
- for (var i=0, n=lines.length; i 0) {
- for (var j=0, m=tokens.length; j= 3) {
- info.format = {
- name : tokens[1],
- version : tokens[2],
- binary : (tokens[1].toLowerCase().indexOf("binary") >= 0),
- littleEndian : ((tokens[1].toLowerCase()) == "binary_little_endian")
- };
- }
- break;
-
- case "comment":
- info.comments.push(tokens.slice(1));
- break;
-
- case "element":
- if (tn >= 3) {
- elem = {
- name : tokens[1],
- count : parseInt(tokens[2]),
- properties : [ ],
- propertyMap : { }
- };
- info.elements.push(elem);
- info.elementMap[elem.name.toLowerCase()] = elem;
- }
- break;
-
- case "property":
- if (elem && (tn >= 3)) {
- prop = {
- name : tokens[tn-1],
- type : tokens.slice(1, tn - 1)
- };
- elem.properties.push(prop);
- elem.propertyMap[prop.name.toLowerCase()] = prop;
- }
- break;
-
- default:
- info.others.push(tokens.slice());
- break;
- }
- }
-
- if (!info.format) {
- return false;
- }
-
- return info;
- }
-
- var tabStr = "\t";
-
- function setupLines(lines, tabs) {
- for (var i=0, n=lines.length; i 0) {
- verticesCount = elem.count;
- props = elem.propertyMap;
-
- vertexLines = [ ];
-
- vertexLines.push("function (header, elementInfo, index, element) {");
- vertexLines.push(tabStr + "var littleEndian = SpiderGL.Type.LITTLE_ENDIAN;");
- vertexLines.push(tabStr + "var sf32 = SpiderGL.Type.SIZEOF_FLOAT32;");
- vertexLines.push(tabStr + "var sui8 = SpiderGL.Type.SIZEOF_UINT8;");
- vertexLines.push(tabStr + "var offset = index * this._vertexStride;");
- vertexLines.push(tabStr + "var view = this._view;");
- vertexLines.push("");
-
- ptypes = propertiesTypes(props["x"], props["y"], props["z"]);
- if (ptypes.length == 1) {
- hasPosition = true;
- switch (ptypes[0]) {
- case "float32":
- vertexLines.push(tabStr + "view.setFloat32(offset, element.x, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.y, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.z, littleEndian); offset += sf32;");
- vertexLines.push("");
- vertexAttributes["position"] = {
- size : 3,
- type : SpiderGL.Type.FLOAT32,
- offset : vertexStride
- };
- vertexStride += 3 * SpiderGL.Type.SIZEOF_FLOAT32;
- break;
- default: break;
- }
- }
-
- ptypes = propertiesTypes(props["nx"], props["ny"], props["nz"]);
- if (ptypes.length == 1) {
- hasNormal = true;
- switch (ptypes[0]) {
- case "float32":
- vertexLines.push(tabStr + "view.setFloat32(offset, element.nx, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.ny, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.nz, littleEndian); offset += sf32;");
- vertexLines.push("");
- vertexAttributes["normal"] = {
- size : 3,
- type : SpiderGL.Type.FLOAT32,
- offset : vertexStride
- };
- vertexStride += 3 * SpiderGL.Type.SIZEOF_FLOAT32;
- break;
- default: break;
- }
- }
-
- ptypes = propertiesTypes(props["red"], props["green"], props["blue"]);
- if (ptypes.length == 1) {
- hasColor = true;
- switch (ptypes[0]) {
- case "uint8":
- vertexLines.push(tabStr + "view.setUint8(offset, element.red ); offset += sui8;");
- vertexLines.push(tabStr + "view.setUint8(offset, element.green); offset += sui8;");
- vertexLines.push(tabStr + "view.setUint8(offset, element.blue ); offset += sui8;");
- vertexLines.push(tabStr + "view.setUint8(offset, 255 ); offset += sui8;");
- vertexLines.push("");
- vertexAttributes["color"] = {
- size : 4,
- type : SpiderGL.Type.UINT8,
- offset : vertexStride,
- normalized : true
- };
- vertexStride += 4 * SpiderGL.Type.SIZEOF_UINT8;
- break;
- case "float32":
- vertexLines.push(tabStr + "view.setFloat32(offset, element.red, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.green, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.blue, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, 1.0, littleEndian); offset += sf32;");
- vertexLines.push("");
- vertexAttributes["color"] = {
- size : 4,
- type : SpiderGL.Type.FLOAT32,
- offset : vertexStride
- };
- vertexStride += 4 * SpiderGL.Type.SIZEOF_FLOAT32;
- break;
- default: break;
- }
- }
-
- ptypes = propertiesTypes(props["texture_u"], props["texture_v"]);
- if (ptypes.length == 1) {
- hasTexCoord = true;
- switch (ptypes[0]) {
- case "float32":
- vertexLines.push(tabStr + "view.setFloat32(offset, element.texture_u, littleEndian); offset += sf32;");
- vertexLines.push(tabStr + "view.setFloat32(offset, element.texture_v, littleEndian); offset += sf32;");
- vertexLines.push("");
- vertexAttributes["texturecoord"] = {
- size : 2,
- type : SpiderGL.Type.FLOAT32,
- offset : vertexStride
- };
- vertexStride += 2 * SpiderGL.Type.SIZEOF_FLOAT32;
- break;
- default: break;
- }
- }
-
- vertexLines.push("}");
- }
-
- var facesCount = 0;
- var faceLines = null;
-
- elem = header.elementMap["face"];
- if (elem && elem.count > 0) {
- facesCount = elem.count;
- props = elem.propertyMap;
-
- faceLines = [ ];
-
- faceLines.push("function (header, elementInfo, index, element) {");
- faceLines.push(tabStr + "var littleEndian = SpiderGL.Type.LITTLE_ENDIAN;");
- faceLines.push(tabStr + "var sui32 = SpiderGL.Type.SIZEOF_UINT32;");
- faceLines.push(tabStr + "var offset = index * 3 * sui32;");
- faceLines.push(tabStr + "var view = this._view;");
- faceLines.push("");
-
- if (props["vertex_indices"]) {
- faceLines.push(tabStr + "view.setUint32(offset, element.vertex_indices[0], littleEndian); offset += sui32;");
- faceLines.push(tabStr + "view.setUint32(offset, element.vertex_indices[1], littleEndian); offset += sui32;");
- faceLines.push(tabStr + "view.setUint32(offset, element.vertex_indices[2], littleEndian); offset += sui32;");
- }
- else {
- facesCount = 0;
- }
-
- faceLines.push("}");
- }
-
- this._mesh = null;
-
- this._hasPosition = hasPosition;
- this._hasNormal = hasNormal;
- this._hasColor = hasColor;
- this._hasTexCoord = hasTexCoord;
-
- this._verticesCount = verticesCount;
- this._vertexAttributes = vertexAttributes;
- this._vertexStride = vertexStride;
- this._vertexBuffer = null;
- this._handleVertex = emptyFunction;
-
- if (vertexStride > 0) {
- var vertexFuncStr = vertexLines.join("\n");
- this._handleVertex = eval("(" + vertexFuncStr + ")");
- }
-
- this._facesCount = facesCount;
- this._indexBuffer = null;
- this._handleFace = emptyFunction;
-
- if (facesCount > 0) {
- var faceFuncStr = faceLines.join("\n");
- this._handleFace = eval("(" + faceFuncStr + ")");
- }
- },
-
- onBeginContent : function (header) {
- },
-
- onBeginElements : function (header, elementInfo) {
- switch (elementInfo.name) {
- case "vertex":
- this._vertexBuffer = new ArrayBuffer(this._verticesCount * this._vertexStride);
- this._view = new DataView(this._vertexBuffer);
- this._handleElement = this._handleVertex;
- break;
- case "face":
- this._indexBuffer = new ArrayBuffer(this._facesCount * 3 * SpiderGL.Type.SIZEOF_UINT32);
- this._view = new DataView(this._indexBuffer);
- this._handleElement = this._handleFace;
- break;
- default:
- this._view = null;
- this._handleElement = emptyFunction;
- break;
- }
- },
-
- onElement : function (header, elementInfo, index, element) {
- // bounding box calculation
- if (elementInfo.name=="vertex"){
- if(element.x < this._boundingBox.min[0])
- this._boundingBox.min[0] = element.x;
- if(element.y < this._boundingBox.min[1])
- this._boundingBox.min[1] = element.y;
- if(element.z < this._boundingBox.min[2])
- this._boundingBox.min[2] = element.z;
-
- if(element.x > this._boundingBox.max[0])
- this._boundingBox.max[0] = element.x;
- if(element.y > this._boundingBox.max[1])
- this._boundingBox.max[1] = element.y;
- if(element.z > this._boundingBox.max[2])
- this._boundingBox.max[2] = element.z;
- }
-
- this._handleElement(header, elementInfo, index, element);
- },
-
- onEndElements : function (header, elementInfo) {
- this._view = null;
- this._handleElement = emptyFunction;
- },
-
- onEndContent : function () {
- },
-
- onEnd : function () {
- if ((this._verticesCount <= 0) && (this._facesCount <= 0)) return;
-
-// var gl = this._gl;
- var modelDescriptor = {
- version : "0.0.1.0 EXP",
- meta : {
- },
- data : {
- vertexBuffers : {
- },
- indexBuffers : {
- }
- },
- access : {
- vertexStreams : {
- },
- primitiveStreams : {
- }
- },
- semantic : {
- bindings : {
- },
- chunks : {
- }
- },
- logic : {
- parts : {
- }
- },
- control : {
- },
- extra : {
- }
- };
-
- var modelVertexBuffers = modelDescriptor.data.vertexBuffers;
- var modelIndexBuffers = modelDescriptor.data.indexBuffers;
- var modelVertexStreams = modelDescriptor.access.vertexStreams;
- var modelPrimitiveStreams = modelDescriptor.access.primitiveStreams;
- var modelBindings = modelDescriptor.semantic.bindings;
- var modelChunks = modelDescriptor.semantic.chunks;
- var modelParts = modelDescriptor.logic.parts;
-
- modelDescriptor.extra.boundingBox = this._boundingBox;
-
- modelDescriptor.extra.renderMode = this._renderMode;
-
- modelDescriptor.extra.hasPosition = this._hasPosition;
- modelDescriptor.extra.hasNormal = this._hasNormal;
- modelDescriptor.extra.hasColor = this._hasColor;
- modelDescriptor.extra.hasTexCoord = this._hasTexCoord;
-
- modelDescriptor.extra.textureUrl = this._textureUrl;
-
- var maxVerticesCount = (1 << 16) - 1;
-
- var baseVertexBufferName = "mainVertexBuffer";
- var baseIndexBufferName = "mainIndexBuffer";
- var baseBindingName = "mainBinding";
- var baseChunkName = "mainChunk";
- var basePointStreamName = "vertices";
- var baseTriStreamName = "triangles";
- var basePartName = "mainPart";
-
- if (this._facesCount > 0) {
- var littleEndian = SpiderGL.Type.LITTLE_ENDIAN;
- var indexStride = SpiderGL.Type.SIZEOF_UINT32;
- var wholeSize = Float64Array.BYTES_PER_ELEMENT;
-
- var stride = this._vertexStride;
- var partCount = stride % wholeSize;
- var wholeCount = (stride - partCount) / wholeSize;
-
- var vertexBufferView = new Uint8Array(this._vertexBuffer);
- var indexBufferView = new Uint32Array(this._indexBuffer);
-
- var chunksCount = 0;
- var chunkVertexBuffers = [ ];
- var chunkVerticesCount = [ ];
- var chunkIndexBuffers = [ ];
- var chunkIndicesCount = [ ];
-
- var facesLeft = this._facesCount;
- var currFaceIndex = 0;
-
- var indicesBuffer = new Uint32Array(this._facesCount * 3);
-
- while (facesLeft > 0) {
- var verticesMap = new Uint32Array(this._verticesCount);
- var verticesNew = new Uint32Array(maxVerticesCount);
- var verticesCount = 0;
- var indicesCount = 0;
- var facesCount = 0;
-
- while ((verticesCount <= (maxVerticesCount - 3)) && (facesLeft > 0)) {
- for (var k=0; k<3; ++k, ++currFaceIndex) {
- var v = indexBufferView[currFaceIndex];
- var r = verticesMap[v];
- if (!r) {
- verticesNew[verticesCount++] = v;
- verticesMap[v] = verticesCount;
- }
- indicesBuffer[indicesCount++] = v;
- }
- facesLeft--;
- facesCount++;
- }
-
- if (facesCount <= 0) continue;
-
- var chunkVertexBuffer = new ArrayBuffer(verticesCount * stride);
- var chunkVertexBufferView = new Uint8Array(chunkVertexBuffer);
- var chunkIndexBuffer = new Uint16Array(indicesCount);
-
- for (var i=0; i 0) {
- var vertexBufferName = baseVertexBufferName;
- modelVertexBuffers[vertexBufferName] = {
- typedArray : this._vertexBuffer
- };
-
- for (var a in this._vertexAttributes) {
- var attr = this._vertexAttributes[a];
- modelVertexStreams[a] = {
- buffer : vertexBufferName,
- size : attr.size,
- type : attr.type,
- stride : this._vertexStride,
- offset : attr.offset,
- normalized : !!attr.normalized
- };
- binding.vertexStreams[a.toUpperCase()] = [a];
- }
-
- modelPrimitiveStreams[basePointStreamName] = {
- mode : SpiderGL.Type.POINTS,
- count : this._verticesCount
- };
- binding.primitiveStreams["POINT"] = [basePointStreamName];
- }
-
- if ((this._verticesCount > 0) || (this._facesCount > 0)) {
- modelChunks[baseChunkName] = {
- techniques : {
- "common" : {
- binding : baseBindingName
- }
- }
- };
-
- modelParts[basePartName] = {
- chunks : [baseChunkName]
- };
- }
- }
-
- this._modelDescriptor = modelDescriptor;
- }
- };
-
- function mainImportPly(buffer) {
- var handler = new PlyHandler(buffer);
- parsePly(buffer, handler);
- var modelDescriptor = handler.modelDescriptor;
- return modelDescriptor;
- };
-
- return mainImportPly;
-})();
diff --git a/all_tools/js/presenter.js b/all_tools/js/presenter.js
deleted file mode 100644
index cda240a..0000000
--- a/all_tools/js/presenter.js
+++ /dev/null
@@ -1,3582 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-SpiderGL.openNamespace();
-
-//----------------------------------------------------------------------------------------
-// CONSTANTS
-//----------------------------------------------------------------------------------------
-// sgltrackball
-const SGL_TRACKBALL_NO_ACTION = 0;
-const SGL_TRACKBALL_ROTATE = 1;
-const SGL_TRACKBALL_PAN = 2;
-const SGL_TRACKBALL_DOLLY = 3;
-const SGL_TRACKBALL_SCALE = 4;
-// selectors
-const HOP_ALL = 256;
-// starting debug mode
-const HOP_DEBUGMODE = false;
-// default light direction
-const HOP_DEFAULTLIGHT = [0, 0, -1];
-// default points size
-const HOP_DEFAULTPOINTSIZE = 1.0;
-
-Presenter = function (canvas) {
- this._supportsWebGL = sglHandleCanvas(canvas, this);
-};
-
-Presenter.prototype = {
-//----------------------------------------------------------------------------------------
-// PARSING FUNCTIONS
-//----------------------------------------------------------------------------------------
-_parseScene : function (options) {
- options = options || { };
- var r = {
- background : this._parseBackground(options.background),
- meshes : this._parseMeshes(options.meshes),
- texturedQuads : this._parseTexturedQuads(options.texturedQuads),
- modelInstances : this._parseModelInstances(options.modelInstances),
- spots : this._parseSpots(options.spots),
- trackball : this._parseTrackball(options.trackball),
- space : this._parseSpace(options.space),
- config : this._parseConfig(options.config)
- };
- return r;
-},
-
-_parseBackground : function (options) {
- options = options || { };
- var r = sglGetDefaultObject({
- image : null,
- isEnvironment : false,
- color : [ 0.0, 0.0, 0.0, 0.0 ]
- }, options);
- return r;
-},
-
-_parseMeshes : function (options) {
- var r = { };
- for (var m in options) {
- r[m] = this._parseMesh(options[m]);
- }
- return r;
-},
-
-_parseMesh : function (options) {
- var r = sglGetDefaultObject({
- url : null,
- transform : null
- }, options);
- r.transform = this._parseTransform(r.transform);
- return r;
-},
-
-_parseTexturedQuads : function (options) {
- var r = { };
- for (var m in options) {
- r[m] = this._parseTexturedQuad(options[m]);
- }
- return r;
-},
-
-_parseTexturedQuad : function (options) {
- return options;
-},
-
-_parseModelInstances : function (options) {
- var r = { };
- for (var m in options) {
- r[m] = this._parseModelInstance(options[m]);
- }
- return r;
-},
-
-_parseModelInstance : function (options) {
- var r = sglGetDefaultObject({
- mesh : null,
- rendermode : null,
- color : [ 1.0, 1.0, 1.0 ],
- useSolidColor : false,
- alpha : 0.5,
- useTransparency : false,
- cursor : "default",
- ID : 0,
- transform : null,
- visible : true,
- tags : [ ],
- clippable : true,
- }, options);
- r.transform = this._parseTransform(r.transform);
- r.ID = this._instancesProgressiveID;
- if (r.color[3]) r.alpha = r.color[3];
- this._instancesProgressiveID += 1;
- return r;
-},
-
-_parseSpots : function (options) {
- var r = { };
- for (var m in options) {
- r[m] = this._parseSpot(options[m]);
- }
- return r;
-},
-
-_parseSpot : function (options) {
- var r = sglGetDefaultObject({
- mesh : null,
- rendermode : null,
- color : [ 0.0, 0.25, 1.0 ],
- useSolidColor : true,
- alpha : 0.5,
- useTransparency : true,
- cursor : "pointer",
- ID : 0,
- transform : null,
- visible : true,
- tags : [ ]
- }, options);
- r.transform = this._parseTransform(r.transform);
- r.ID = this._spotsProgressiveID;
- if (r.color[3]) r.alpha = r.color[3]; //3DHOP 2.0 backward compatibility
- this._spotsProgressiveID += 1;
- return r;
-},
-
-_parseTrackball : function (options) {
- var r = sglGetDefaultObject({
- type : TurnTableTrackball,
- trackOptions : {}
- }, options);
- return r;
-},
-
-_parseSpace : function (options) {
- options = options || { };
- var r = sglGetDefaultObject({
- centerMode : "first",
- radiusMode : "first",
- whichInstanceCenter : "",
- whichInstanceRadius : "",
- explicitCenter : [0.0, 0.0, 0.0],
- explicitRadius : 1.0,
- transform : null,
- cameraFOV : 60.0,
- cameraNearFar : [0.1, 10.0],
- cameraType : "perspective",
- }, options);
- r.transform = this._parseTransform(r.transform);
- if(r.cameraFOV < 2.0) r.cameraFOV=2.0;
- if(r.cameraFOV > 88.0) r.cameraFOV=88.0;
- if((r.cameraType != "perspective") && (r.cameraType != "ortho"))
- r.cameraType = "perspective";
- return r;
-},
-
-_parseConfig : function (options) {
- options = options || { };
- var r = sglGetDefaultObject({
- pickedpointColor : [1.0, 0.0, 1.0],
- measurementColor : [0.5, 1.0, 0.5],
- showClippingPlanes : true,
- showClippingBorder : false,
- clippingBorderSize : 0.5,
- clippingBorderColor : [0.0, 1.0, 1.0],
- pointSize : 1.0,
- pointSizeMinMax : [1.0, 5.0],
- }, options);
- return r;
-},
-
-_parseTransform : function (options) {
- var r = sglGetDefaultObject({
- matrix : SglMat4.identity(),
- rotation : [0.0, 0.0, 0.0],
- translation : [0.0, 0.0, 0.0],
- scale : [1.0, 1.0, 1,0],
- }, options);
-
- // if any of rotation, translation or scale are defined, matrix is overwritten
- var overwrite = false;
- var matrixT = SglMat4.identity();
- var matrixR = SglMat4.identity();
- var matrixS = SglMat4.identity();
- if((r.translation[0] != 0.0)||(r.translation[1] != 0.0)||(r.translation[2] != 0.0))
- {
- matrixT = SglMat4.translation(r.translation);
- overwrite = true;
- }
- if((r.rotation[0] != 0.0)||(r.rotation[1] != 0.0)||(r.rotation[2] != 0.0))
- {
- var mrX = SglMat4.rotationAngleAxis(sglDegToRad(r.rotation[0]), [1.0, 0.0, 0.0]);
- var mrY = SglMat4.rotationAngleAxis(sglDegToRad(r.rotation[1]), [0.0, 1.0, 0.0])
- var mrZ = SglMat4.rotationAngleAxis(sglDegToRad(r.rotation[2]), [0.0, 0.0, 1.0])
- matrixR = SglMat4.mul(SglMat4.mul(mrZ, mrY), mrX);
- overwrite = true;
- }
- if((r.scale[0] != 1.0)||(r.scale[1] != 1.0)||(r.scale[2] != 1.0))
- {
- matrixS = SglMat4.scaling(r.scale);
- overwrite = true;
- }
- if (overwrite)
- r.matrix = SglMat4.mul(SglMat4.mul(matrixT, matrixR), matrixS);
-
- return r;
-},
-
-//----------------------------------------------------------------------------------------
-//SHADERS RELATED FUNCTIONS
-//----------------------------------------------------------------------------------------
-// standard program for NXS rendering, points and faces
-_createStandardPointNXSProgram : function () {
- var gl = this.ui.gl;
- var nxsVertexShader = new SglVertexShader(gl, "\
- precision highp float; \n\
- \n\
- uniform mat4 uWorldViewProjectionMatrix; \n\
- uniform mat3 uViewSpaceNormalMatrix; \n\
- uniform mat4 uModelMatrix; \n\
- uniform float uPointSize; \n\
- \n\
- attribute vec3 aPosition; \n\
- attribute vec3 aNormal; \n\
- attribute vec4 aColor; \n\
- attribute float aPointSize; \n\
- \n\
- varying vec3 vNormal; \n\
- varying vec4 vColor; \n\
- varying vec4 vModelPos; \n\
- \n\
- void main(void) \n\
- { \n\
- vNormal = uViewSpaceNormalMatrix * aNormal; \n\
- vColor = aColor; \n\
- vModelPos = uModelMatrix * vec4(aPosition, 1.0); \n\
- \n\
- gl_Position = uWorldViewProjectionMatrix * vec4(aPosition, 1.0); \n\
- gl_PointSize = uPointSize * aPointSize; \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("STD POINT Vertex Shader Log:\n" + nxsVertexShader.log);
-
- var nxsFragmentShader = new SglFragmentShader(gl, "\
- #extension GL_EXT_frag_depth : enable \n\
- precision highp float; \n\
- \n\
- uniform vec3 uViewSpaceLightDirection; \n\
- uniform float uAlpha; \n\
- uniform bool uUseSolidColor; \n\
- uniform vec3 uSolidColor; \n\
- uniform vec3 uClipPoint; \n\
- uniform vec3 uClipAxis; \n\
- uniform vec3 uClipColor; \n\
- uniform float uClipColorSize; \n\
- \n\
- varying vec3 vNormal; \n\
- varying vec4 vColor; \n\
- varying vec4 vModelPos; \n\
- \n\
- void main(void) \n\
- { \n\
- if((uClipAxis[0] == 1.0)&&(vModelPos[0] > uClipPoint[0])) discard; \n\
- else if((uClipAxis[0] == -1.0)&&(vModelPos[0] < uClipPoint[0])) discard; \n\
- if((uClipAxis[1] == 1.0)&&(vModelPos[1] > uClipPoint[1])) discard; \n\
- else if((uClipAxis[1] == -1.0)&&(vModelPos[1] < uClipPoint[1])) discard; \n\
- if((uClipAxis[2] == 1.0)&&(vModelPos[2] > uClipPoint[2])) discard; \n\
- else if((uClipAxis[2] == -1.0)&&(vModelPos[2] < uClipPoint[2])) discard; \n\
- \n\
- float a = pow(2.0*(gl_PointCoord.x - 0.5), 2.0); \n\
- float b = pow(2.0*(gl_PointCoord.y - 0.5), 2.0); \n\
- float c = 1.0 - (a + b); \n\
- if(c < 0.0) { discard; } \n\
- \n\
- vec3 diffuse = vColor.rgb; \n\
- \n\
- if(uUseSolidColor) { \n\
- if(uSolidColor.r + uSolidColor.g + uSolidColor.b == -3.0) \n\
- diffuse = vColor.aaa; \n\
- else \n\
- diffuse = uSolidColor; \n\
- } \n\
- \n\
- if(vNormal[0] != 0.0 || vNormal[1] != 0.0 || vNormal[2] != 0.0) { \n\
- vec3 normal = normalize(vNormal); \n\
- float nDotL = dot(normal, -uViewSpaceLightDirection); \n\
- diffuse = diffuse * max(0.0, nDotL); \n\
- } \n\
- \n\
- if((uClipAxis[0] == 1.0)&&((uClipPoint[0]-vModelPos[0]) uClipPoint[0])) discard; \n\
- else if((uClipAxis[0] == -1.0)&&(vModelPos[0] < uClipPoint[0])) discard; \n\
- if((uClipAxis[1] == 1.0)&&(vModelPos[1] > uClipPoint[1])) discard; \n\
- else if((uClipAxis[1] == -1.0)&&(vModelPos[1] < uClipPoint[1])) discard; \n\
- if((uClipAxis[2] == 1.0)&&(vModelPos[2] > uClipPoint[2])) discard; \n\
- else if((uClipAxis[2] == -1.0)&&(vModelPos[2] < uClipPoint[2])) discard; \n\
- \n\
- vec3 diffuse = vColor.rgb; \n\
- \n\
- if(vTextureCoord.x != 0.0) \n\
- diffuse = texture2D(uSampler, vTextureCoord).xyz; \n\
- \n\
- if(uUseSolidColor) { \n\
- if(uSolidColor.r + uSolidColor.g + uSolidColor.b == -3.0) \n\
- diffuse = vColor.aaa; \n\
- else \n\
- diffuse = uSolidColor; \n\
- } \n\
- \n\
- if(vNormal[0] != 0.0 || vNormal[1] != 0.0 || vNormal[2] != 0.0) { \n\
- vec3 normal = normalize(vNormal); \n\
- float nDotL = dot(normal, -uViewSpaceLightDirection); \n\
- if(gl_FrontFacing) \n\
- diffuse = diffuse * max(0.0, nDotL); \n\
- else \n\
- diffuse = diffuse * vec3(0.4, 0.3, 0.3) * abs(nDotL); \n\
- } \n\
- else if(!gl_FrontFacing) \n\
- diffuse = diffuse * vec3(0.4, 0.3, 0.3); \n\
- \n\
- if((uClipAxis[0] == 1.0)&&((uClipPoint[0]-vModelPos[0]) uClipPoint[0])) discard; \n\
- else if((uClipAxis[0] == -1.0)&&(vModelPos[0] < uClipPoint[0])) discard; \n\
- if((uClipAxis[1] == 1.0)&&(vModelPos[1] > uClipPoint[1])) discard; \n\
- else if((uClipAxis[1] == -1.0)&&(vModelPos[1] < uClipPoint[1])) discard; \n\
- if((uClipAxis[2] == 1.0)&&(vModelPos[2] > uClipPoint[2])) discard; \n\
- else if((uClipAxis[2] == -1.0)&&(vModelPos[2] < uClipPoint[2])) discard; \n\
- \n\
- vec4 myColor; \n\
- myColor = pack_depth(gl_FragCoord.z); \n\
- gl_FragColor = myColor; \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("XYZ Fragment Shader Log:\n" + nxsFragmentShader.log);
-
- var program = new SglProgram(gl, {
- shaders : [
- nxsVertexShader,
- nxsFragmentShader
- ],
- attributes : {
- "aPosition" : 0,
- "aNormal" : 1,
- "aColor" : 2,
- "aPointSize": 4
- },
- uniforms : {
- "uWorldViewProjectionMatrix" : SglMat4.identity(),
- "uModelMatrix" : SglMat4.identity(),
- "uClipPoint" : [0.0, 0.0, 0.0],
- "uClipAxis" : [0.0, 0.0, 0.0],
- "uPointSize" : 1.0
- }
- });
- if(this._isDebugging)
- console.log("XYZ Program Log:\n" + program.log);
-
- return program;
-},
-
-// color coded ID program for NXS rendering, points and faces
-_createColorCodedIDNXSProgram : function () {
- var gl = this.ui.gl;
- var nxsVertexShader = new SglVertexShader(gl, "\
- precision highp float; \n\
- \n\
- uniform mat4 uWorldViewProjectionMatrix; \n\
- uniform float uPointSize; \n\
- \n\
- attribute vec3 aPosition; \n\
- attribute vec3 aNormal; \n\
- attribute vec3 aColor; \n\
- attribute float aPointSize; \n\
- \n\
- void main(void) \n\
- { \n\
- gl_Position = uWorldViewProjectionMatrix * vec4(aPosition, 1.0); \n\
- gl_PointSize = uPointSize * aPointSize; \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("COLORCODED ID Vertex Shader Log:\n" + nxsVertexShader.log);
-
- var nxsFragmentShader = new SglFragmentShader(gl, "\
- precision highp float; \n\
- \n\
- uniform vec4 uColorID; \n\
- \n\
- void main(void) \n\
- { \n\
- gl_FragColor = uColorID; \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("COLORCODED ID Fragment Shader Log:\n" + nxsFragmentShader.log);
-
- var program = new SglProgram(gl, {
- shaders : [
- nxsVertexShader,
- nxsFragmentShader
- ],
- attributes : {
- "aPosition" : 0,
- "aNormal" : 1,
- "aColor" : 2,
- "aPointSize": 4
- },
- uniforms : {
- "uWorldViewProjectionMatrix" : SglMat4.identity(),
- "uColorID" : [1.0, 0.5, 0.0, 1.0],
- "uPointSize" : 1.0
- }
- });
- if(this._isDebugging)
- console.log("COLORCODED ID Program Log:\n" + program.log);
-
- return program;
-},
-
-// single-color barely-shaded program for NXS rendering, points and faces
-_createColorShadedNXSProgram : function () {
- var gl = this.ui.gl;
- var nxsVertexShader = new SglVertexShader(gl, "\
- precision highp float; \n\
- \n\
- uniform mat4 uWorldViewProjectionMatrix; \n\
- uniform mat3 uViewSpaceNormalMatrix; \n\
- uniform float uPointSize; \n\
- \n\
- attribute vec3 aPosition; \n\
- attribute vec3 aNormal; \n\
- attribute float aPointSize; \n\
- \n\
- varying vec3 vNormal; \n\
- \n\
- void main(void) \n\
- { \n\
- vNormal = uViewSpaceNormalMatrix * aNormal; \n\
- \n\
- gl_Position = uWorldViewProjectionMatrix * vec4(aPosition, 1.0); \n\
- gl_PointSize = uPointSize * aPointSize; \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("COLOR SHADED Vertex Shader Log:\n" + nxsVertexShader.log);
-
- var nxsFragmentShader = new SglFragmentShader(gl, "\
- precision highp float; \n\
- \n\
- uniform vec3 uViewSpaceLightDirection; \n\
- uniform vec4 uColorID; \n\
- \n\
- varying vec3 vNormal; \n\
- \n\
- void main(void) \n\
- { \n\
- vec3 diffuse = vec3(uColorID[0], uColorID[1], uColorID[2]); \n\
- \n\
- if(vNormal[0] != 0.0 || vNormal[1] != 0.0 || vNormal[2] != 0.0) { \n\
- vec3 normal = normalize(vNormal); \n\
- float nDotL = dot(normal, -uViewSpaceLightDirection); \n\
- float lambert = max(-nDotL, nDotL); \n\
- \n\
- diffuse = (diffuse * 0.5) + (diffuse * lambert * 0.5); \n\
- } \n\
- gl_FragColor = vec4(diffuse, uColorID[3]); \n\
- } \n\
- ");
- if(this._isDebugging)
- console.log("COLOR SHADED Fragment Shader Log:\n" + nxsFragmentShader.log);
-
- var program = new SglProgram(gl, {
- shaders : [
- nxsVertexShader,
- nxsFragmentShader
- ],
- attributes : {
- "aPosition" : 0,
- "aNormal" : 1,
- "aPointSize": 4
- },
- uniforms : {
- "uWorldViewProjectionMatrix" : SglMat4.identity(),
- "uViewSpaceNormalMatrix" : SglMat3.identity(),
- "uViewSpaceLightDirection" : [0.0, 0.0, -1.0],
- "uColorID" : [1.0, 0.5, 0.0, 1.0],
- "uPointSize" : 1.0
- }
- });
- if(this._isDebugging)
- console.log("COLOR SHADED Program Log:\n" + program.log);
-
- return program;
-},
-
-//standard technique for PLY rendering, points and faces
-_createStandardPointPLYtechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- program : this._createStandardPointNXSProgram(),
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 0.0, 0.0 ],
- "aColor" : [ 0.8, 0.8, 0.8, 1.0 ],
- "aPointSize" : 1.0
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uViewSpaceNormalMatrix" : { semantic : "uViewSpaceNormalMatrix", value : SglMat3.identity() },
- "uModelMatrix" : { semantic : "uModelMatrix", value : SglMat4.identity() },
- "uViewSpaceLightDirection" : { semantic : "uViewSpaceLightDirection", value : [ 0.0, 0.0, -1.0 ] },
- "uPointSize" : { semantic : "uPointSize", value : 1.0 },
- "uAlpha" : { semantic : "uAlpha", value : 1.0 },
- "uUseSolidColor" : { semantic : "uUseSolidColor", value : false },
- "uSolidColor" : { semantic : "uSolidColor", value : [ 1.0, 1.0, 1.0 ] },
- "uClipPoint" : { semantic : "uClipPoint", value : [ 0.0, 0.0, 0.0 ] },
- "uClipAxis" : { semantic : "uClipAxis", value : [ 0.0, 0.0, 0.0 ] },
- "uClipColor" : { semantic : "uClipColor", value : [ 1.0, 1.0, 1.0 ]},
- "uClipColorSize" : { semantic : "uClipColorSize", value : 0.5 }
- }
- });
-
- return technique;
-},
-
-_createStandardFacePLYtechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- program : this._createStandardFaceNXSProgram(),
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 0.0, 0.0 ],
- "aColor" : [ 0.8, 0.8, 0.8, 1.0 ]
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uViewSpaceNormalMatrix" : { semantic : "uViewSpaceNormalMatrix", value : SglMat3.identity() },
- "uModelMatrix" : { semantic : "uModelMatrix", value : SglMat4.identity() },
- "uViewSpaceLightDirection" : { semantic : "uViewSpaceLightDirection", value : [ 0.0, 0.0, -1.0 ] },
- "uAlpha" : { semantic : "uAlpha", value : 1.0 },
- "uUseSolidColor" : { semantic : "uUseSolidColor", value : false },
- "uSolidColor" : { semantic : "uSolidColor", value : [ 1.0, 1.0, 1.0 ] },
- "uClipPoint" : { semantic : "uClipPoint", value : [ 0.0, 0.0, 0.0 ] },
- "uClipAxis" : { semantic : "uClipAxis", value : [ 0.0, 0.0, 0.0 ] },
- "uClipColor" : { semantic : "uClipColor", value : [ 1.0, 1.0, 1.0 ]},
- "uClipColorSize" : { semantic : "uClipColorSize", value : 0.5 },
- "uSampler" : { semantic : "uSampler", value : 0 }
- }
- });
-
- return technique;
-},
-
-// depth to color technique for PLY rendering
-_createXYZPLYtechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- program : this._createXYZNXSProgram(),
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 0.0, 0.0 ],
- "aColor" : [ 0.8, 0.8, 0.8, 1.0 ],
- "aPointSize" : 1.0
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uModelMatrix" : { semantic : "uModelMatrix", value : SglMat4.identity() },
- "uPointSize" : { semantic : "uPointSize", value : 1.0 },
- "uClipPoint" : { semantic : "uClipPoint", value : [ 0.0, 0.0, 0.0 ] },
- "uClipAxis" : { semantic : "uClipAxis", value : [ 0.0, 0.0, 0.0 ] }
- }
- });
-
- return technique;
-},
-
-// color coded ID technique for PLY rendering
-_createColorCodedIDPLYtechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- program : this._createColorCodedIDNXSProgram(),
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 0.0, 0.0 ],
- "aColor" : [ 0.8, 0.8, 0.8, 1.0 ],
- "aPointSize" : 1.0
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uColorID" : { semantic : "uColorID", value : [1.0, 0.5, 0.25, 1.0] },
- "uPointSize" : { semantic : "uPointSize", value : 1.0 }
- }
- });
-
- return technique;
-},
-
-// single-color barely-shaded technique for PLY rendering
-_createColorShadedPLYtechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- program : this._createColorShadedNXSProgram(),
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 0.0, 0.0 ],
- "aPointSize" : 1.0
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uViewSpaceNormalMatrix" : { semantic : "uViewSpaceNormalMatrix", value : SglMat3.identity() },
- "uViewSpaceLightDirection" : { semantic : "uViewSpaceLightDirection", value : [ 0.0, 0.0, -1.0 ] },
- "uColorID" : { semantic : "uColorID", value : [1.0, 0.5, 0.25, 1.0] },
- "uPointSize" : { semantic : "uPointSize", value : 1.0 }
- }
- });
-
- return technique;
-},
-
-// 2 points line rendering
-_createSimpleLinetechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- vertexShader : "\
- precision highp float; \n\
- \n\
- uniform mat4 uWorldViewProjectionMatrix; \n\
- uniform vec3 uPointA; \n\
- uniform vec3 uPointB; \n\
- \n\
- attribute vec3 aPosition; \n\
- attribute vec3 aNormal; \n\
- attribute vec3 aColor; \n\
- \n\
- void main(void) \n\
- { \n\
- vec3 newPos; \n\
- if(aPosition[0]==0.0) \n\
- newPos = uPointA; \n\
- else \n\
- newPos = uPointB; \n\
- gl_Position = uWorldViewProjectionMatrix * vec4(newPos, 1.0); \n\
- gl_PointSize = 8.0; \n\
- } \n\
- ",
- fragmentShader : "\
- precision highp float; \n\
- \n\
- uniform vec4 uLineColor; \n\
- \n\
- void main(void) \n\
- { \n\
- gl_FragColor = uLineColor; \n\
- } \n\
- ",
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 1.0, 0.0 ],
- "aColor" : [ 1.0, 0.0, 0.0, 1.0 ]
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- "uLineColor" : { semantic : "uLineColor", value : [0.0, 1.0, 0.5, 1.0] },
- "uPointA" : { semantic : "uPointA", value : [0.0, 0.0, 0.0] },
- "uPointB" : { semantic : "uPointB", value : [1.0, 1.0, 1.0] }
- }
- });
-
- return technique;
-},
-
-// multiple lines/points rendering
-_createMultiLinesPointstechnique : function () {
- var gl = this.ui.gl;
- var technique = new SglTechnique(gl, {
- vertexShader : "\
- precision highp float; \n\
- \n\
- uniform mat4 uWorldViewProjectionMatrix; \n\
- \n\
- attribute vec3 aPosition; \n\
- attribute vec3 aNormal; \n\
- attribute vec4 aColor; \n\
- \n\
- varying vec3 vNormal; \n\
- varying vec4 vColor; \n\
- \n\
- void main(void) \n\
- { \n\
- vColor = aColor; \n\
- gl_Position = uWorldViewProjectionMatrix * vec4(aPosition, 1.0); \n\
- gl_PointSize = 8.0; \n\
- } \n\
- ",
- fragmentShader : "\
- precision highp float; \n\
- \n\
- varying vec4 vColor; \n\
- \n\
- void main(void) \n\
- { \n\
- gl_FragColor = vColor; \n\
- } \n\
- ",
- vertexStreams : {
- "aNormal" : [ 0.0, 0.0, 1.0, 0.0 ],
- "aColor" : [ 1.0, 0.0, 1.0, 1.0 ]
- },
- globals : {
- "uWorldViewProjectionMatrix" : { semantic : "uWorldViewProjectionMatrix", value : SglMat4.identity() },
- }
- });
-
- return technique;
-},
-
-//----------------------------------------------------------------------------------------
-// SUPPORT FUNCTIONS
-//----------------------------------------------------------------------------------------
-_onMeshReady : function () {
- this._objectLoaded();
-},
-
-_onTextureReady : function () {
- this._objectLoaded();
-},
-
-_onBackgroundReady : function () {
- this._objectLoaded();
-},
-
-_objectLoaded : function () {
- this._objectsToLoad--;
- this._testReady();
-},
-
-_testReady : function () {
- if (this._objectsToLoad != 0) return;
- this.trackball.track(SglMat4.identity(), 0.0, 0.0, 0.0);
-
- this._sceneReady = this._scenePrepare();
-
- this.ui.postDrawEvent();
-},
-
-_scenePrepare : function () {
- var meshes = this._scene.meshes;
- var instances = this._scene.modelInstances;
- var spots = this._scene.spots;
- for (var mesh in meshes) {
- if (!meshes[mesh].renderable) continue;
- for (var inst in instances)
- if (mesh == instances[inst].mesh)
- instances[inst].rendermode = meshes[mesh].renderable.renderMode[0];
- for (var spt in spots)
- if (mesh == spots[spt].mesh)
- spots[spt].rendermode = meshes[mesh].renderable.renderMode[0];
- }
- return true;
-},
-
-_isSceneReady : function () {
- var r = (this._scene && this._sceneParsed && this._sceneReady);
- return r;
-},
-
-_pickingRefresh: function(x,y) {
- this._pickpoint[0] = x;
- this._pickpoint[1] = y;
-
- var pickedPixel;
- var ID, cursor;
-
- if(this._onEndPickingPoint||this._onEndMeasurement||this._onPickedSpot||this._onEnterSpot||this._onLeaveSpot){
- pickedPixel = this._drawScenePickingSpots();
- ID = this._Color2ID(pickedPixel);
- if(this._lastSpotID != ID){
- var spots = this._scene.spots;
- if(ID != 0){
- for (var spt in spots) {
- if (spots[spt].ID == ID) {
- this._pickedSpot = spt;
- if(this._onHover){
- if(spots[this._lastPickedSpot]) spots[this._lastPickedSpot].alpha -= 0.2;
- spots[this._pickedSpot].alpha += 0.2;
- cursor = spots[spt].cursor;
- if(/*!this._movingLight ||*/ !this._isMeasuring){
- this._lastCursor = document.getElementById(this.ui.canvas.id).style.cursor;
- document.getElementById(this.ui.canvas.id).style.cursor = cursor;
- }
- if(this._onLeaveSpot && this._lastPickedSpot!=null) this._onLeaveSpot(this._lastPickedSpot);
- if(this._onEnterSpot && this._pickedSpot!=null) this._onEnterSpot(this._pickedSpot);
- this.ui.postDrawEvent();
- }
- this._lastPickedSpot = spt;
- break;
- }
- }
- this._lastSpotID = ID;
- }
- else{
- this._pickedSpot = null;
- if(this._onHover){
- if(spots[this._lastPickedSpot]) spots[this._lastPickedSpot].alpha -= 0.2;
- if(/*!this._movingLight ||*/ !this._isMeasuring) document.getElementById(this.ui.canvas.id).style.cursor = "default";
- if(this._onLeaveSpot && this._lastPickedSpot!=null) this._onLeaveSpot(this._lastPickedSpot);
- //if(this._onEnterSpot) this._onEnterSpot(this._pickedSpot);
- this._lastPickedSpot = null;
- this.ui.postDrawEvent();
- }
- this._lastSpotID = ID;
- }
- }
- }
-
- if(this._onEndPickingPoint||this._onEndMeasurement||this._onPickedInstance||this._onEnterInstance||this._onLeaveInstance){
- pickedPixel = this._drawScenePickingInstances();
- ID = this._Color2ID(pickedPixel);
- if(this._lastInstanceID == ID && !(this._onPickedSpot||this._onEnterSpot||this._onLeaveSpot)) return;
- if(ID != 0){
- var instances = this._scene.modelInstances;
- for (var inst in instances) {
- if (instances[inst].ID == ID) {
- this._pickedInstance = inst;
- if(this._onHover){
- cursor = instances[inst].cursor;
- if(/*!this._movingLight ||*/ !this._isMeasuring){
- this._lastCursor = cursor;
- if(this._pickedSpot==null)document.getElementById(this.ui.canvas.id).style.cursor = cursor;
- this.ui.postDrawEvent();
- }
- if(this._onLeaveInstance && this._lastPickedInstance!=null) this._onLeaveInstance(this._lastPickedInstance);
- if(this._onEnterInstance && this._pickedInstance!=null) this._onEnterInstance(this._pickedInstance);
- }
- this._lastPickedInstance = inst;
- break;
- }
- }
- }
- else{
- this._pickedInstance = null;
- if(this._onHover){
- this._lastCursor = "default";
- if((/*!this._movingLight ||*/ !this._isMeasuring) && this._pickedSpot==null) document.getElementById(this.ui.canvas.id).style.cursor = "default";
- if(this._onLeaveInstance && this._lastPickedInstance!=null) this._onLeaveInstance(this._lastPickedInstance);
- //if(this._onEnterInstance) this._onEnterInstance(this._pickedInstance);
- this.ui.postDrawEvent();
- }
- this._lastPickedInstance = null;
- }
- this._lastInstanceID = ID;
- }
-},
-
-_measureRefresh : function (button, x, y, e) {
-// if(e.target.id!=this.ui.gl.canvas.id) return;
-
- if(this._isMeasuringDistance){
- this._pickpoint[0] = x;
- this._pickpoint[1] = y;
- var ppoint = this._drawScenePickingXYZ();
- if ((ppoint!=null)&&(this._measurementStage != 2)) {
- this._pointA = ppoint;
- this._measurementStage=2;
- this.ui.postDrawEvent();
- }
- else if ((ppoint!=null)&&(this._measurementStage == 2)) {
- this._pointB = ppoint;
- this.measurement = SglVec3.length(SglVec3.sub(this._pointA, this._pointB));
- this._measurementStage=3;
- this.ui.postDrawEvent();
- if(this._onEndMeasurement) this._onEndMeasurement(this.measurement, this._pointA, this._pointB);
- }
- }
-},
-
-_startMeasurement : function () {
- if (this._isMeasuringDistance) return;
- this._isMeasuring = this._isMeasuringDistance = true;
- this._measurementStage = 1; // 0=inactive 1=picking pointA 2=picking pointB 3=measurement ready
- this._pointA = [0.0, 0.0, 0.0];
- this._pointB = [0.0, 0.0, 0.0];
- this.measurement = 0.0;
- this.ui.postDrawEvent();
-},
-
-_stopMeasurement : function () {
- this._isMeasuringDistance = false;
- if (!this._isMeasuringPickpoint) this._isMeasuring = this._isMeasuringDistance;
- this._measurementStage = 0; // 0=inactive 1=picking pointA 2=picking pointB 3=measurement ready
- this._pointA = [0.0, 0.0, 0.0];
- this._pointB = [0.0, 0.0, 0.0];
- this.measurement = 0.0;
- this.ui.postDrawEvent();
-},
-
-_pickpointRefresh : function (button, x, y, e) {
-// if(e.target.id!=this.ui.gl.canvas.id) return;
- if(this._isMeasuringPickpoint){
- this._pickpoint[0] = x;
- this._pickpoint[1] = y;
- var ppoint = this._drawScenePickingXYZ();
- if (ppoint!=null)
- {
- this._pickedPoint = ppoint;
- this._pickValid = true;
- if(this._onEndPickingPoint) this._onEndPickingPoint(this._pickedPoint);
- this.ui.postDrawEvent();
- }
- }
-},
-
-_startPickPoint : function () {
- if (this._isMeasuringPickpoint) return;
- this._isMeasuring = this._isMeasuringPickpoint = true;
- this._pickValid = false;
- this._pickedPoint = [0.0, 0.0, 0.0];
- this.ui.postDrawEvent();
-},
-
-_stopPickPoint : function () {
- this._isMeasuringPickpoint = false;
- if (!this._isMeasuringDistance) this._isMeasuring = this._isMeasuringPickpoint;
- this._pickValid = false;
- this._pickedPoint = [0.0, 0.0, 0.0];
- this.ui.postDrawEvent();
-},
-
-//----------------------------------------------------------------------------------------
-// DRAWING SUPPORT FUNCTIONS
-//----------------------------------------------------------------------------------------
-_setSceneCenterRadius : function () {
- var meshes = this._scene.meshes;
- var instances = this._scene.modelInstances;
- this.sceneCenter = [0.0, 0.0, 0.0];
- this.sceneRadiusInv = 1.0;
-
- if(this._scene.space.centerMode == "explicit")
- {
- this.sceneCenter = this._scene.space.explicitCenter;
- }
- else if(this._scene.space.centerMode == "specific" && this._scene.space.whichInstanceCenter != "")
- {
- var mesh = meshes[instances[this._scene.space.whichInstanceCenter].mesh];
- if((mesh)&&(mesh.renderable)){
- var instCenter = SglVec3.to4(mesh.renderable.datasetCenter,1);
-
- instCenter = SglMat4.mul4(mesh.transform.matrix, instCenter);
- instCenter = SglMat4.mul4(instances[this._scene.space.whichInstanceCenter].transform.matrix, instCenter);
- instCenter = SglMat4.mul4(this._scene.space.transform.matrix, instCenter);
-
- instCenter = SglVec4.to3(instCenter);
-
- this.sceneCenter = instCenter;
- }
- }
- else if(this._scene.space.centerMode == "scene")
- {
- var smin = SglVec3.maxNumber();
- var smax = SglVec3.minNumber();
- var imin = [0.0, 0.0, 0.0];
- var imax = [0.0, 0.0, 0.0];
-
- for (var inst in instances) {
- var mesh = meshes[instances[inst].mesh];
- if((mesh)&&(mesh.renderable)){
- var instCenter = SglVec3.to4(mesh.renderable.datasetCenter,1);
- instCenter = SglMat4.mul4(mesh.transform.matrix, instCenter);
- instCenter = SglMat4.mul4(instances[inst].transform.matrix, instCenter);
- instCenter = SglMat4.mul4(this._scene.space.transform.matrix, instCenter);
- instCenter = SglVec4.to3(instCenter);
-
- var radius = mesh.renderable.datasetRadius;
- var vector111 = SglVec3.one();
- vector111 = SglMat3.mul3(SglMat4.to33(mesh.transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(instances[inst].transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(this._scene.space.transform.matrix), vector111);
- var scalefactor = SglVec3.length(vector111) / SglVec3.length([1,1,1]);
- radius = radius*scalefactor;
-
- imin[0] = instCenter[0] - radius;
- imin[1] = instCenter[1] - radius;
- imin[2] = instCenter[2] - radius;
- imax[0] = instCenter[0] + radius;
- imax[1] = instCenter[1] + radius;
- imax[2] = instCenter[2] + radius;
-
- if(imin[0] < smin[0]) smin[0] = imin[0];
- if(imin[1] < smin[1]) smin[1] = imin[1];
- if(imin[2] < smin[2]) smin[2] = imin[2];
- if(imax[0] > smax[0]) smax[0] = imax[0];
- if(imax[1] > smax[1]) smax[1] = imax[1];
- if(imax[2] > smax[2]) smax[2] = imax[2];
- }
- }
-
- this.sceneCenter = [ (smax[0] + smin[0])/2.0, (smax[1] + smin[1])/2.0, (smax[2] + smin[2])/2.0 ];
- }
- else //if(this._scene.space.centerMode == "first")
- {
- for (var inst in instances) {
- var mesh = meshes[instances[inst].mesh];
- if((mesh)&&(mesh.renderable)){
- var instCenter = SglVec3.to4(mesh.renderable.datasetCenter,1);
-
- instCenter = SglMat4.mul4(mesh.transform.matrix, instCenter);
- instCenter = SglMat4.mul4(instances[inst].transform.matrix, instCenter);
- instCenter = SglMat4.mul4(this._scene.space.transform.matrix, instCenter);
-
- instCenter = SglVec4.to3(instCenter);
-
- this.sceneCenter = instCenter;
- break;
- }
- }
- }
-
- if(this._scene.space.radiusMode == "explicit")
- {
- this.sceneRadiusInv = 1.0 / this._scene.space.explicitRadius;
- }
- else if(this._scene.space.radiusMode == "specific" && this._scene.space.whichInstanceRadius != "")
- {
- var mesh = meshes[instances[this._scene.space.whichInstanceRadius].mesh];
- if((mesh)&&(mesh.renderable)){
- var radius = mesh.renderable.datasetRadius;
- var vector111 = SglVec3.one();
-
- vector111 = SglMat3.mul3(SglMat4.to33(mesh.transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(instances[this._scene.space.whichInstanceRadius].transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(this._scene.space.transform.matrix), vector111);
-
- var scalefactor = SglVec3.length(vector111) / SglVec3.length([1,1,1]);
-
- this.sceneRadiusInv = 1.0 / (radius*scalefactor);
- }
- }
- else if(this._scene.space.radiusMode == "scene")
- {
- var smin = SglVec3.maxNumber();
- var smax = SglVec3.minNumber();
- var imin = [0.0, 0.0, 0.0];
- var imax = [0.0, 0.0, 0.0];
-
- for (var inst in instances) {
- var mesh = meshes[instances[inst].mesh];
- if((mesh)&&(mesh.renderable)){
- var instCenter = SglVec3.to4(mesh.renderable.datasetCenter,1);
- instCenter = SglMat4.mul4(mesh.transform.matrix, instCenter);
- instCenter = SglMat4.mul4(instances[inst].transform.matrix, instCenter);
- instCenter = SglMat4.mul4(this._scene.space.transform.matrix, instCenter);
- instCenter = SglVec4.to3(instCenter);
-
- var radius = mesh.renderable.datasetRadius;
- var vector111 = SglVec3.one();
- vector111 = SglMat3.mul3(SglMat4.to33(mesh.transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(instances[inst].transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(this._scene.space.transform.matrix), vector111);
-
- var scalefactor = SglVec3.length(vector111) / SglVec3.length([1,1,1]);
- radius = radius*scalefactor;
-
- imin[0] = instCenter[0] - radius;
- imin[1] = instCenter[1] - radius;
- imin[2] = instCenter[2] - radius;
- imax[0] = instCenter[0] + radius;
- imax[1] = instCenter[1] + radius;
- imax[2] = instCenter[2] + radius;
-
- if(imin[0] < smin[0]) smin[0] = imin[0];
- if(imin[1] < smin[1]) smin[1] = imin[1];
- if(imin[2] < smin[2]) smin[2] = imin[2];
- if(imax[0] > smax[0]) smax[0] = imax[0];
- if(imax[1] > smax[1]) smax[1] = imax[1];
- if(imax[2] > smax[2]) smax[2] = imax[2];
- }
- }
- var scenter = [ (smax[0] + smin[0])/2.0, (smax[1] + smin[1])/2.0, (smax[2] + smin[2])/2.0 ]
- this.sceneRadiusInv = 1.0 / SglVec3.length(SglVec3.sub(smax, scenter));
- }
- else //if(this._scene.space.radiusMode == "first")
- {
- for (var inst in instances) {
- var mesh = meshes[instances[inst].mesh];
- if((mesh)&&(mesh.renderable)){
- var radius = mesh.renderable.datasetRadius;
- var vector111 = SglVec3.one();
-
- vector111 = SglMat3.mul3(SglMat4.to33(mesh.transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(instances[inst].transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(this._scene.space.transform.matrix), vector111);
-
- var scalefactor = SglVec3.length(vector111) / SglVec3.length([1,1,1]);
-
- this.sceneRadiusInv = 1.0 / (radius*scalefactor);
- break;
- }
- }
- }
-},
-
-_destroyPickFramebuffer : function () {
- if (this.pickFramebuffer) {
- this.pickFramebuffer.destroy();
- this.pickFramebuffer = null;
- }
- if (this.pickColorTexture) {
- this.pickColorTexture.destroy();
- this.pickColorTexture = null;
- }
- if (this.pickDepthRenderbuffer) {
- this.pickDepthRenderbuffer.destroy();
- this.pickDepthRenderbuffer = null;
- }
-},
-
-_createPickFramebuffer : function (width, height) {
- if (this.pickFramebuffer && (this.pickFramebuffer.width == width) && (this.pickFramebuffer.height == height))
- return;
- else
- this._destroyPickFramebuffer();
-
- var gl = this.ui.gl;
-
- this.pickColorTexture = new SglTexture2D(gl, {
- internalFormat : gl.RGBA,
- width : width,
- height : height
- });
-
- this.pickDepthRenderbuffer = new SglRenderbuffer(gl, {
- internalFormat : gl.DEPTH_COMPONENT16,
- width : width,
- height : height
- });
-
- this.pickFramebuffer = new SglFramebuffer(gl, {
- color : this.pickColorTexture,
- depth : this.pickDepthRenderbuffer,
- autoViewport : true
- });
-},
-
-_setupDraw : function () {
- var width = this.ui.width;
- var height = this.ui.height;
- var xform = this.xform;
- var space = this._scene.space;
-
- this.ui.gl.viewport(0, 0, width, height);
-
- var FOV = space.cameraFOV;
- var nearP = space.cameraNearFar[0];
- var farP = space.cameraNearFar[1];
-
- // getting scale/center for scene
- this._setSceneCenterRadius();
-
- xform.projection.loadIdentity();
-
- if(space.cameraType == "ortho")
- {
- //default camera distance in ortho view is "as large as scene size"
- // then, if the trackball is able to provide a better value, we use it
- var cDistance = 1.0;
- if(typeof this.trackball.distance != "undefined")
- cDistance = this.trackball.distance;
- var a = cDistance * SpiderGL.Math.tan(sglDegToRad(FOV) / 2);
- var b = a * width/height;
-
- xform.projection.ortho([-b, -a, nearP], [b, a, farP]);
- }
- else
- {
- xform.projection.perspective(sglDegToRad(FOV), width/height, nearP, farP);
- }
-
- xform.view.loadIdentity();
- xform.view.lookAt([0.0, 0.0, 0.0], [0.0, 0.0, -1.0], [0.0, 1.0, 0.0]);
- this.viewMatrix = xform.viewMatrix;
-
- xform.model.loadIdentity();
- xform.model.multiply(this.trackball.matrix);
-
- // scale to unit box + recenter
- xform.model.scale([this.sceneRadiusInv, this.sceneRadiusInv, this.sceneRadiusInv]);
- xform.model.translate(SglVec3.neg(this.sceneCenter));
-},
-
-_ID2Color : function (ID) {
- var intID = ID | 0;
- var IDr = intID % 10;
- var IDg = ((intID-IDr) / 10) % 10;
- var IDb = ((((intID-IDr) / 10) - IDg) / 10) % 10;
-
- var colorID = [IDr * 0.1, IDg * 0.1, IDb * 0.1, 1.0];
- return colorID;
-},
-
-_Color2ID : function (color) {
- var IDr = Math.round(((color[0])/255.0) / 0.1) | 0;
- var IDg = (Math.round(((color[1])/255.0) / 0.1) * 10) | 0;
- var IDb = (Math.round(((color[2])/255.0) / 0.1) * 100) | 0;
-
- var ID = (IDr + IDg + IDb) | 0;
- return ID;
-},
-
-_onPlyLoaded : function (req, thatmesh, gl) {
- var plyData = req.buffer;
- var modelDescriptor = importPly(plyData);
- var TMR = thatmesh.renderable = new SglModel(gl, modelDescriptor);
-
- TMR.renderMode = modelDescriptor.extra.renderMode;
- TMR.boundingBox = modelDescriptor.extra.boundingBox;
-
- // center and radius
- TMR.datasetCenter = [0.0, 0.0, 0.0];
- TMR.datasetRadius = 1.0;
-
- TMR.datasetCenter[0] = (TMR.boundingBox.max[0] + TMR.boundingBox.min[0]) / 2.0;
- TMR.datasetCenter[1] = (TMR.boundingBox.max[1] + TMR.boundingBox.min[1]) / 2.0;
- TMR.datasetCenter[2] = (TMR.boundingBox.max[2] + TMR.boundingBox.min[2]) / 2.0;
-
- TMR.datasetRadius = Math.sqrt( Math.pow((TMR.boundingBox.max[0] - TMR.boundingBox.min[0]),2) +
- Math.pow((TMR.boundingBox.max[1] - TMR.boundingBox.min[1]),2) +
- Math.pow((TMR.boundingBox.max[2] - TMR.boundingBox.min[2]),2) ) / 2.0;
-
- // texture
- if(modelDescriptor.extra.textureUrl) {
- var that = this;
- var texUrl = "";
- var tmpUrl = req._url.split("/");
- for (var j=0; j nexus.drawBudget)
- nexus.drawBudget = 0.9 * nexus.drawBudget + 0.1*newBudget;
- }
-
- var program;
- if(instance.rendermode=="FILL")
- program = CurrFaceProgram;
- else
- program = CurrPointProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(instance.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
- }
- else { //drawing ply
- var technique;
- if(instance.rendermode=="FILL")
- technique = CurrFaceTechnique;
- else
- technique = CurrPointTechnique;
- renderer.begin();
- renderer.setTechnique(technique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(instance.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.setTexture(0, renderable.texture);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.DEPTH_TEST);
-
- xform.model.pop();
- }
-
- // draw transparent geometries
- for (var inst in instances) {
- var instance = instances[inst];
- var mesh = meshes[instance.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!instance.visible) continue;
- if (!instance.useTransparency) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(false);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(instance.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var modelMatrix = SglMat4.identity();
- modelMatrix = SglMat4.mul(modelMatrix, space.transform.matrix);
- modelMatrix = SglMat4.mul(modelMatrix, instance.transform.matrix);
- modelMatrix = SglMat4.mul(modelMatrix, mesh.transform.matrix);
- var thisClipAxis = instance.clippable?this._clipAxis:[0.0, 0.0, 0.0];
- var thisClipBordersize = config.showClippingBorder?config.clippingBorderSize:0.0;
-
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uViewSpaceNormalMatrix" : xform.viewSpaceNormalMatrix,
- "uModelMatrix" : modelMatrix,
- "uViewSpaceLightDirection" : this._lightDirection,
- "uPointSize" : config.pointSize,
- "uAlpha" : instance.alpha,
- "uUseSolidColor" : instance.useSolidColor,
- "uSolidColor" : [instance.color[0], instance.color[1], instance.color[2]],
- "uClipPoint" : [0.0, 0.0, 0.0],
- "uClipPoint" : this._clipPoint,
- "uClipAxis" : thisClipAxis,
- "uClipColor" : config.clippingBorderColor,
- "uClipColorSize" : thisClipBordersize
- };
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
-
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
- var fps = this.ui.framesPerSecond;
- if(nexus._targetFps && fps) {
- var newBudget = (nexus.drawBudget * fps) / nexus._targetFps;
- if(newBudget < nexus._minDrawBudget)
- newBudget = nexus._minDrawBudget;
- // logic: increase budget only if we stop rendering because of it (instead of just waiting for download.
- if(newBudget < nexus.drawBudget || nexus._drawSize > nexus.drawBudget)
- nexus.drawBudget = 0.9 * nexus.drawBudget + 0.1*newBudget;
- }
-
- var program;
- if(instance.rendermode=="FILL")
- program = CurrFaceProgram;
- else
- program = CurrPointProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(instance.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
- }
- else { //drawing ply
- var technique;
- if(instance.rendermode=="FILL")
- technique = CurrFaceTechnique;
- else
- technique = CurrPointTechnique;
- renderer.begin();
- renderer.setTechnique(technique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(instance.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.setTexture(0, renderable.texture);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.disable(gl.DEPTH_TEST);
-
- xform.model.pop();
- }
-
- // draw picked point (if valid)
- if (this._pickValid) {
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
- gl.depthFunc(gl.LESS);
-
- xform.model.push();
-
- var lineUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uLineColor" : [config.pickedpointColor[0], config.pickedpointColor[1], config.pickedpointColor[2], 1.0],
- "uPointA" : this._pickedPoint,
- "uPointB" : this._pickedPoint
- };
-
- //drawing points
- renderer.begin();
- renderer.setTechnique(lineTechnique);
- renderer.setDefaultGlobals();
- renderer.setGlobals(lineUniforms);
- renderer.setPrimitiveMode("POINT");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.end();
-
- lineUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uLineColor" : [config.pickedpointColor[0] * 0.4, config.pickedpointColor[1] * 0.5, config.pickedpointColor[2] * 0.6, 0.5],
- "uPointA" : this._pickedPoint,
- "uPointB" : this._pickedPoint
- };
-
- gl.depthFunc(gl.GREATER);
- gl.depthMask(false);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- //drawing points and line
- renderer.begin();
- renderer.setTechnique(lineTechnique);
- renderer.setDefaultGlobals();
- renderer.setGlobals(lineUniforms);
- renderer.setPrimitiveMode("POINT");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.end();
-
- // GLstate cleanup
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.depthFunc(gl.LESS);
- gl.disable(gl.DEPTH_TEST);
-
- xform.model.pop();
- }
-
- // draw measurement line (if any)
- if (this._measurementStage >= 2) {// 0=inactive 1=picking pointA 2=picking pointB 3=measurement ready
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
- gl.depthFunc(gl.LESS);
-
- xform.model.push();
-
- var lineUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uLineColor" : [config.measurementColor[0], config.measurementColor[1], config.measurementColor[2], 1.0],
- "uPointA" : this._pointA,
- "uPointB" : (this._measurementStage==2)?this._pointA:this._pointB,
- };
-
- //drawing points and line
- renderer.begin();
- renderer.setTechnique(lineTechnique);
- renderer.setDefaultGlobals();
- renderer.setGlobals(lineUniforms);
- renderer.setPrimitiveMode("LINE");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.setPrimitiveMode("POINT");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.end();
-
- lineUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uLineColor" : [config.measurementColor[0] * 0.4, config.measurementColor[1] * 0.5, config.measurementColor[2] * 0.6, 0.5],
- "uPointA" : this._pointA,
- "uPointB" : (this._measurementStage==2)?this._pointA:this._pointB,
- };
-
- gl.depthFunc(gl.GREATER);
- gl.depthMask(false);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- //drawing points and line
- renderer.begin();
- renderer.setTechnique(lineTechnique);
- renderer.setDefaultGlobals();
- renderer.setGlobals(lineUniforms);
- renderer.setPrimitiveMode("LINE");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.setPrimitiveMode("POINT");
- renderer.setModel(this.simpleLineModel);
- renderer.renderModel();
- renderer.end();
-
- // GLstate cleanup
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.depthFunc(gl.LESS);
- gl.disable(gl.DEPTH_TEST);
-
- xform.model.pop();
- }
-
- // draw transparent spot geometries
- for (var spt in spots) {
- var spot = spots[spt];
- var mesh = meshes[spot.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!spot.visible) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(false);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(spot.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uViewSpaceNormalMatrix" : xform.viewSpaceNormalMatrix,
- "uViewSpaceLightDirection" : this._lightDirection,
- "uPointSize" : config.pointSize,
- "uColorID" : [spot.color[0], spot.color[1], spot.color[2], spot.alpha]
- }
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
-
- var program = CCProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(spot.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
- }
- else { //drawing ply
- renderer.begin();
- renderer.setTechnique(CCTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(spot.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.disable(gl.DEPTH_TEST);
-
- xform.model.pop();
}
-
- // draw clipping plane (if any)
- if(config.showClippingPlanes)
- {
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
- gl.depthMask(false);
- gl.enable(gl.BLEND);
- gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
-
- if(this._clipAxis[0] != 0.0) {
- xform.model.push();
- xform.model.translate([this._clipPoint[0], this._sceneBboxCenter[1], this._sceneBboxCenter[2]]);
- xform.model.scale([(this._sceneBboxMax[0] - this._sceneBboxMin[0]),
- (this._sceneBboxMax[1] - this._sceneBboxMin[1]),
- (this._sceneBboxMax[2] - this._sceneBboxMin[2])]);
-
- var QuadUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uViewSpaceNormalMatrix" : xform.viewSpaceNormalMatrix,
- "uViewSpaceLightDirection" : this._lightDirection,
- "uColorID" : [1.0, 0.0, 0.0, 0.25]
- };
-
- renderer.begin();
- renderer.setTechnique(CCTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode("FILL");
- renderer.setGlobals(QuadUniforms);
- renderer.setModel(this.simpleQuadXModel);
- renderer.renderModel();
- renderer.end();
-
- xform.model.pop();
- }
-
- if(this._clipAxis[1] != 0.0) {
- xform.model.push();
- xform.model.translate([this._sceneBboxCenter[0], this._clipPoint[1], this._sceneBboxCenter[2]]);
- xform.model.scale([(this._sceneBboxMax[0] - this._sceneBboxMin[0]),
- (this._sceneBboxMax[1] - this._sceneBboxMin[1]),
- (this._sceneBboxMax[2] - this._sceneBboxMin[2])]);
-
- var QuadUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uViewSpaceNormalMatrix" : xform.viewSpaceNormalMatrix,
- "uViewSpaceLightDirection" : this._lightDirection,
- "uColorID" : [0.0, 1.0, 0.0, 0.25]
- };
-
- renderer.begin();
- renderer.setTechnique(CCTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode("FILL");
- renderer.setGlobals(QuadUniforms);
- renderer.setModel(this.simpleQuadYModel);
- renderer.renderModel();
- renderer.end();
-
- xform.model.pop();
- }
-
- if(this._clipAxis[2] != 0.0) {
- xform.model.push();
- xform.model.translate([this._sceneBboxCenter[0], this._sceneBboxCenter[1], this._clipPoint[2]]);
- xform.model.scale([(this._sceneBboxMax[0] - this._sceneBboxMin[0]),
- (this._sceneBboxMax[1] - this._sceneBboxMin[1]),
- (this._sceneBboxMax[2] - this._sceneBboxMin[2])]);
-
- var QuadUniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uViewSpaceNormalMatrix" : xform.viewSpaceNormalMatrix,
- "uViewSpaceLightDirection" : this._lightDirection,
- "uColorID" : [0.0, 0.0, 1.0, 0.25]
- };
-
- renderer.begin();
- renderer.setTechnique(CCTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode("FILL");
- renderer.setGlobals(QuadUniforms);
- renderer.setModel(this.simpleQuadZModel);
- renderer.renderModel();
- renderer.end();
-
- xform.model.pop();
- }
-
- // GLstate cleanup
- gl.disable(gl.BLEND);
- gl.depthMask(true);
- gl.disable(gl.DEPTH_TEST);
- }
-},
-
-_drawScenePickingXYZ : function () {
- var gl = this.ui.gl;
- var width = this.ui.width;
- var height = this.ui.height;
- var xform = this.xform;
- var renderer = this.renderer;
- var CurrProgram = this.colorCodedXYZNXSProgram;
- var CurrTechnique = this.colorCodedXYZPLYTechnique;
- var meshes = this._scene.meshes;
- var instances = this._scene.modelInstances;
- var space = this._scene.space;
- var pixel = new Uint8Array(4);
-
- // picking FB
- this._createPickFramebuffer(width, height);
-
- // basic setup, matrices for projection & view
- this._setupDraw();
-
- // clear buffer
- this.pickFramebuffer.bind();
- gl.clearColor(0.0, 0.0, 0.0, 0.0);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
- this.pickFramebuffer.unbind();
-
- for (var inst in instances) {
- var instance = instances[inst];
- var mesh = meshes[instance.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!instance.visible) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(instance.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var modelMatrix = SglMat4.identity();
- modelMatrix = SglMat4.mul(modelMatrix, space.transform.matrix);
- modelMatrix = SglMat4.mul(modelMatrix, instance.transform.matrix);
- modelMatrix = SglMat4.mul(modelMatrix, mesh.transform.matrix);
- var thisClipAxis = instance.clippable?this._clipAxis:[0.0, 0.0, 0.0];
-
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uModelMatrix" : modelMatrix,
- "uClipPoint" : this._clipPoint,
- "uClipAxis" : thisClipAxis,
- "uPointSize" : this._scene.config.pointSize
- };
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
-
- this.pickFramebuffer.bind();
-
- var program = CurrProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(instance.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
-
- this.pickFramebuffer.unbind();
- }
- else { //drawing ply
- renderer.begin();
- renderer.setFramebuffer(this.pickFramebuffer);
- renderer.setTechnique(CurrTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(instance.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.DEPTH_TEST);
- // undo transform
- xform.model.pop();
- }
-
- this.pickFramebuffer.readPixels(pixel, {
- x : this._pickpoint[0],
- y : this._pickpoint[1],
- width : 1,
- height : 1,
- format : gl.RGBA,
- type : gl.UNSIGNED_BYTE
- });
-
- var rr = pixel[0] / 255.0;
- var gg = pixel[1] / 255.0;
- var bb = pixel[2] / 255.0;
- var aa = pixel[3] / 255.0;
- var depth = aa + ( bb / (256.0)) + ( gg / (256.0*256.0)) + ( rr / (256.0*256.0*256.0));
-
- var ppointc;
-
- if((rr==0.0) && (gg==0.0) && (bb==00))
- return(null);
- else
- ppointc = xform.unproject([this._pickpoint[0]/width,this._pickpoint[1]/height,depth]);
-
- return([ppointc[0], ppointc[1], ppointc[2]]);
-},
-
-_drawScenePickingInstances : function () {
- var gl = this.ui.gl;
- var width = this.ui.width;
- var height = this.ui.height;
- var xform = this.xform;
- var renderer = this.renderer;
- var CurrProgram = this.colorCodedIDNXSProgram;
- var CurrTechnique = this.colorCodedIDPLYTechnique;
- var meshes = this._scene.meshes;
- var instances = this._scene.modelInstances;
- var space = this._scene.space;
- var pixel = new Uint8Array(4);
-
- // picking FB
- this._createPickFramebuffer(width, height);
-
- // basic setup, matrices for projection & view
- this._setupDraw();
-
- // clear buffer
- this.pickFramebuffer.bind();
- gl.clearColor(0.0, 0.0, 0.0, 0.0);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
- this.pickFramebuffer.unbind();
-
- for (var inst in instances) {
- var instance = instances[inst];
- var mesh = meshes[instance.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!instance.visible) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(instance.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var colorID = this._ID2Color(instance.ID);
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uPointSize" : this._scene.config.pointSize,
- "uColorID" : colorID
- };
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
-
- this.pickFramebuffer.bind();
-
- var program = CurrProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(instance.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
-
- this.pickFramebuffer.unbind();
- }
- else { //drawing ply
- renderer.begin();
- renderer.setFramebuffer(this.pickFramebuffer);
- renderer.setTechnique(CurrTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(instance.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.DEPTH_TEST);
- // undo transform
- xform.model.pop();
- }
-
- this.pickFramebuffer.readPixels(pixel, {
- x : this._pickpoint[0],
- y : this._pickpoint[1],
- width : 1,
- height : 1,
- format : gl.RGBA,
- type : gl.UNSIGNED_BYTE
- });
-
- return pixel;
-},
-
-_drawScenePickingSpots : function () {
- var gl = this.ui.gl;
- var width = this.ui.width;
- var height = this.ui.height;
- var xform = this.xform;
- var renderer = this.renderer;
- var CurrProgram = this.colorCodedIDNXSProgram;
- var CurrTechnique = this.colorCodedIDPLYTechnique;
- var meshes = this._scene.meshes;
- var spots = this._scene.spots;
- var instances = this._scene.modelInstances;
- var space = this._scene.space;
- var pixel = new Uint8Array(4);
-
- // picking FB
- this._createPickFramebuffer(width, height);
-
- // basic setup, matrices for projection & view
- this._setupDraw();
-
- // clear buffer
- this.pickFramebuffer.bind();
- gl.clearColor(0.0, 0.0, 0.0, 0.0);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
- this.pickFramebuffer.unbind();
-
- // first pass, draw invisible instances, for occlusion
- for (var inst in instances) {
- var instance = instances[inst];
- var mesh = meshes[instance.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!instance.visible) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(instance.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uPointSize" : this._scene.config.pointSize,
- "uColorID" : [0.0, 0.0, 0.0, 0.0]
- };
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
-
- this.pickFramebuffer.bind();
-
- var program = CurrProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(instance.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
-
- this.pickFramebuffer.unbind();
- }
- else { //drawing ply
- renderer.begin();
- renderer.setFramebuffer(this.pickFramebuffer);
- renderer.setTechnique(CurrTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(instance.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.DEPTH_TEST);
- // undo transform
- xform.model.pop();
- }
-
- // second pass, draw color coded spots, for picking
- for (var spt in spots) {
- var spot = spots[spt];
- var mesh = meshes[spot.mesh];
- if (!mesh) continue;
- var renderable = mesh.renderable;
- if (!renderable) continue;
- if (!spot.visible) continue;
-
- // GLstate setup
- gl.enable(gl.DEPTH_TEST);
-
- xform.model.push();
- xform.model.multiply(space.transform.matrix);
- xform.model.multiply(spot.transform.matrix);
- xform.model.multiply(mesh.transform.matrix);
-
- var colorID = this._ID2Color(spot.ID);
- var uniforms = {
- "uWorldViewProjectionMatrix" : xform.modelViewProjectionMatrix,
- "uPointSize" : this._scene.config.pointSize,
- "uColorID" : colorID
- };
-
- if(mesh.isNexus) {
- if (!renderable.isReady) continue;
- var nexus = renderable;
- nexus.modelMatrix = xform.modelMatrix;
- nexus.viewMatrix = xform.viewMatrix;
- nexus.projectionMatrix = xform.projectionMatrix;
- nexus.viewport = [0, 0, width, height];
-
- this.pickFramebuffer.bind();
-
- var program = CurrProgram;
- program.bind();
- program.setUniforms(uniforms);
- nexus.begin();
- nexus.setPrimitiveMode(spot.rendermode);
- nexus.render();
- nexus.end();
- program.unbind();
-
- this.pickFramebuffer.unbind();
- }
- else { //drawing ply
- renderer.begin();
- renderer.setFramebuffer(this.pickFramebuffer);
- renderer.setTechnique(CurrTechnique);
- renderer.setDefaultGlobals();
- renderer.setPrimitiveMode(spot.rendermode);
- renderer.setGlobals(uniforms);
- renderer.setModel(renderable);
- renderer.renderModel();
- renderer.end();
- }
-
- // GLstate cleanup
- gl.disable(gl.DEPTH_TEST);
- // undo transform
- xform.model.pop();
- }
-
- this.pickFramebuffer.readPixels(pixel, {
- x : this._pickpoint[0],
- y : this._pickpoint[1],
- width : 1,
- height : 1,
- format : gl.RGBA,
- type : gl.UNSIGNED_BYTE
- });
-
- return pixel;
-},
-
-_drawNull : function () {
- var gl = this.ui.gl;
- gl.clearColor(0.0, 0.0, 0.0, 0.0);
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
-},
-
-// creates simple 2-point line model
-_createLineModel : function () {
- var gl = this.ui.gl;
- this.simpleLineModel = new SglModel(gl, {
- vertices : {
- position : [ 0,0,0,
- 1,1,1 ],
- normal : [ 0,0,0,
- 0,0,0 ],
- color : {value : [ 1.0, 0.0, 0.0 ]}
- },
- primitives : ["lines","points"]
- });
-},
-
-// creates simple quad model
-_createQuadModels : function () {
- var gl = this.ui.gl;
- this.simpleQuadXModel = new SglModel(gl, {
- vertices : {
- position : [ 0.0, 0.5, 0.5,
- 0.0,-0.5, 0.5,
- 0.0,-0.5,-0.5,
- 0.0, 0.5,-0.5,
- 0.0,-0.5,-0.5,
- 0.0, 0.5, 0.5],
- normal : [ 1.0,0.0,0.0,
- 1.0,0.0,0.0,
- 1.0,0.0,0.0,
- 1.0,0.0,0.0,
- 1.0,0.0,0.0,
- 1.0,0.0,0.0 ],
- color : {value : [ 1.0, 0.0, 0.0 ]}
- },
- primitives : ["triangles"]
- });
- this.simpleQuadYModel = new SglModel(gl, {
- vertices : {
- position : [ 0.5, 0.0, 0.5,
- -0.5, 0.0, 0.5,
- -0.5, 0.0,-0.5,
- 0.5, 0.0,-0.5,
- -0.5, 0.0,-0.5,
- 0.5, 0.0, 0.5],
- normal : [ 0.0,1.0,0.0,
- 0.0,1.0,0.0,
- 0.0,1.0,0.0,
- 0.0,1.0,0.0,
- 0.0,1.0,0.0,
- 0.0,1.0,0.0 ],
- color : {value : [ 0.0, 1.0, 0.0 ]}
- },
- primitives : ["triangles"]
- });
- this.simpleQuadZModel = new SglModel(gl, {
- vertices : {
- position : [ 0.5, 0.5, 0.0,
- -0.5, 0.5, 0.0,
- -0.5,-0.5, 0.0,
- 0.5,-0.5, 0.0,
- -0.5,-0.5, 0.0,
- 0.5, 0.5, 0.0],
- normal : [ 0.0,0.0,1.0,
- 0.0,0.0,1.0,
- 0.0,0.0,1.0,
- 0.0,0.0,1.0,
- 0.0,0.0,1.0,
- 0.0,0.0,1.0 ],
- color : {value : [ 0.0, 0.0, 1.0 ]}
- },
- primitives : ["triangles"]
- });
-},
-
-//----------------------------------------------------------------------------------------
-// EVENTS HANDLERS
-//----------------------------------------------------------------------------------------
-onInitialize : function () {
- var gl = this.ui.gl;
-
- // debug mode
- this._isDebugging = HOP_DEBUGMODE;
-
- gl.getExtension('EXT_frag_depth');
- gl.clearColor(0.5, 0.5, 0.5, 1.0);
-
- // scene rendering support data
- this.renderer = new SglModelRenderer(gl);
- this.xform = new SglTransformationStack();
- this.viewMatrix = SglMat4.identity();
-
- // nexus parameters
- this._nexusTargetFps = 15.0;
- this._nexusTargetError = 1.0;
- this._nexusCacheSize = 100000000;
-
- // shaders
- this.faceNXSProgram = this._createStandardFaceNXSProgram();
- this.pointNXSProgram = this._createStandardPointNXSProgram();
- this.colorShadedNXSProgram = this._createColorShadedNXSProgram();
- this.colorCodedIDNXSProgram = this._createColorCodedIDNXSProgram();
- this.colorCodedXYZNXSProgram = this._createXYZNXSProgram();
-
- this.facePLYTechnique = this._createStandardFacePLYtechnique();
- this.pointPLYTechnique = this._createStandardPointPLYtechnique();
- this.colorShadedPLYTechnique = this._createColorShadedPLYtechnique();
- this.colorCodedIDPLYTechnique = this._createColorCodedIDPLYtechnique();
- this.colorCodedXYZPLYTechnique = this._createXYZPLYtechnique();
-
- this.simpleLineTechnique = this._createSimpleLinetechnique();
- this.multiLinesPointsTechnique = this._createMultiLinesPointstechnique();
-
- // handlers
- this._onPickedInstance = 0;
- this._onPickedSpot = 0;
- this._onEnterInstance = 0;
- this._onEnterSpot = 0;
- this._onLeaveInstance = 0;
- this._onLeaveSpot = 0;
- this._onEndPickingPoint = 0;
- this._onEndMeasurement = 0;
-
- // animation
- this.ui.animateRate = 0;
-
- // current cursor XY position
- this.x = 0.0;
- this.y = 0.0;
-
- this._keycombo = false;
-
- // SCENE DATA
- this._scene = null;
- this._sceneParsed = false;
- this._sceneReady = false;
- this._objectsToLoad = 0;
-
- this._instancesProgressiveID = 1;
- this._spotsProgressiveID = 1;
-
- this._lightDirection = HOP_DEFAULTLIGHT;
-
- this.sceneCenter = [0.0, 0.0, 0.0];
- this.sceneRadiusInv = 1.0;
-
- this._targetInstanceName = null;
- this._targetHotSpotName = null;
-
- this._animating = false;
- this._movingLight = false;
-
- this._clickable = false;
- this._onHover = false;
-
- this._lastCursor = "default";
- this._pickedInstance = null;
- this._pickedSpot = null;
- this._lastPickedInstance = null;
- this._lastPickedSpot = null;
- this._lastInstanceID = 0;
- this._lastSpotID = 0;
- this._pickpoint = [1, 1];
-
- // global measurement data
- this._isMeasuring = false;
-
- // point2point measurement data
- this._isMeasuringDistance = false;
- this._measurementStage = 0; // 0=inactive 1=picking pointA 2=picking pointB 3=measurement ready
- this._pointA = [0.0, 0.0, 0.0];
- this._pointB = [0.0, 0.0, 0.0];
- this.measurement = 0;
-
- // point picking measurement data
- this._isMeasuringPickpoint = false;
- this._pickValid = false;
- this._pickedPoint = [0.0, 0.0, 0.0];
-
- // plane section
- this._clipPoint = [0.0, 0.0, 0.0];
- this._clipAxis = [0.0, 0.0, 0.0];
- this._sceneBboxMin = [0.0, 0.0, 0.0]
- this._sceneBboxMax = [0.0, 0.0, 0.0];
- this._sceneBboxCenter = [0.0, 0.0, 0.0];
-},
-
-onDrag : function (button, x, y, e) {
- var ui = this.ui;
-
- if(this._movingLight && ui.isMouseButtonDown(0)){
- var dxl = (x / (ui.width - 1)) * 2.0 - 1.0;
- var dyl = (y / (ui.height - 1)) * 2.0 - 1.0;
- this.rotateLight(dxl/2, dyl/2);
- return;
- }
-
- if(ui.dragDeltaX(button) != 0) this.x += (ui.cursorDeltaX/500);
- if(ui.dragDeltaY(button) != 0) this.y += (ui.cursorDeltaY/500);
-
- var action = SGL_TRACKBALL_NO_ACTION;
- if ((ui.isMouseButtonDown(0) && ui.isKeyDown(17)) || ui.isMouseButtonDown(1) || ui.isMouseButtonDown(2)) {
- action = SGL_TRACKBALL_PAN;
- }
- else if (ui.isMouseButtonDown(0)) {
- action = SGL_TRACKBALL_ROTATE;
- }
-
- var testMatrix = this.trackball._matrix.slice();
-
- this.trackball.action = action;
- this.trackball.track(this.viewMatrix, this.x, this.y, 0.0);
-
- var diff;
- for(var i=0; i=3 || Math.abs(this.ui.dragDeltaY(0)>=3))) && e.detail!=-1) {
- this._pickingRefresh(x, y);
- if(this._onPickedSpot && this._pickedSpot!=null) this._onPickedSpot(this._pickedSpot);
- if(this._onPickedInstance && this._pickedInstance!=null) this._onPickedInstance(this._pickedInstance);
- if(this._isMeasuringPickpoint) this._pickpointRefresh(0, x, y, e);
- if(this._isMeasuringDistance) this._measureRefresh(0, x, y, e);
- }
- this._clickable = false;
-},
-
-onDoubleClick : function (button, x, y, e) {
- //only if trackball does support recentering, we do it
- if(this.trackball.recenter){
- this._pickpoint[0] = x;
- this._pickpoint[1] = y;
- var ppoint = this._drawScenePickingXYZ();
- if (ppoint!=null)
- {
- this.ui.animateRate = 30;
- this.trackball.recenter(ppoint);
- this.ui.postDrawEvent();
- }
- }
-},
-
-onKeyPress : function (key, e) {
- if(this._isDebugging) { // DEBUGGING-AUTHORING keys
- if((e.charCode == '80') || (e.charCode == '112')) // key "P" to print trackball
- console.log(this.trackball.getState());
- if (e.charCode == '49') { // key "1" to show nexus patches
- Nexus.Debug.nodes=!Nexus.Debug.nodes;
- this.ui.postDrawEvent();
- }
- if (e.charCode == '50') { // key "2" to toggle camera perspective/ortho
- this.toggleCameraType();
- }
- }
-},
-
-onKeyUp : function (key, e) {
- if(this._keycombo && e.keyCode == '18') {
- e.preventDefault();
- this._keycombo = false;
- }
-},
-
-onMouseWheel: function (wheelDelta, x, y, e) {
- var diff = false;
-
- if(e && e.altKey) { // key "ALT" + MOUSE WHEEL to change pointclouds point set size
- this._keycombo = true;
-
- var testValue = this._scene.config.pointSize;
-
- this._scene.config.pointSize += wheelDelta/10;
-
- if (this._scene.config.pointSize < this._scene.config.pointSizeMinMax[0]) this._scene.config.pointSize = this._scene.config.pointSizeMinMax[0];
- else if (this._scene.config.pointSize > this._scene.config.pointSizeMinMax[1]) this._scene.config.pointSize = this._scene.config.pointSizeMinMax[1];
-
- if(testValue!=this._scene.config.pointSize) {
- diff=true;
- }
- }
- else {
- var action = SGL_TRACKBALL_SCALE;
- var factor = wheelDelta > 0.0 ? (0.90) : (1.10);
-
- var testMatrix = this.trackball._matrix.slice();
-
- this.trackball.action = action;
- this.trackball.track(this.viewMatrix, 0.0, 0.0, factor);
- this.trackball.action = SGL_TRACKBALL_NO_ACTION;
-
- for(var i=0; i 0) this._animating = true;
- else this._animating = false;
- return this._animating;
-},
-
-//-----------------------------------------------------------------------------
-// functions to dynamically change center/radius mode
-
-setCenterModeFirst : function () {
- this._scene.space.centerMode = "first";
- this.ui.postDrawEvent();
-},
-setCenterModeScene : function () {
- this._scene.space.centerMode = "scene";
- this.ui.postDrawEvent();
-},
-setCenterModeSpecific : function (instancename) {
- if(this._scene.modelInstances[instancename])
- {
- this._scene.space.centerMode = "specific";
- this._scene.space.whichInstanceCenter = instancename;
- this.ui.postDrawEvent();
- }
- else
- return "ERROR - No such instance";
-},
-setCenterModeExplicit : function (newcenter) {
- if((newcenter.constructor === Array)&&(newcenter.lenght = 3)&&(isFinite(String(newcenter[0])))&&(isFinite(String(newcenter[1])))&&(isFinite(String(newcenter[2]))))
- {
- this._scene.space.centerMode = "explicit";
- this._scene.space.explicitCenter = newcenter;
- this.ui.postDrawEvent();
- }
- else
- return "ERROR - Not a point";
-},
-
-setRadiusModeFirst : function () {
- this._scene.space.radiusMode = "first";
- this.ui.postDrawEvent();
-},
-setRadiusModeScene : function () {
- this._scene.space.radiusMode = "scene";
- this.ui.postDrawEvent();
-},
-setRadiusModeSpecific : function (instancename) {
- if(this._scene.modelInstances[instancename])
- {
- this._scene.space.radiusMode = "specific";
- this._scene.space.whichInstanceRadius = instancename;
- this.ui.postDrawEvent();
- }
- else
- return "ERROR - No such instance";
-},
-setRadiusModeExplicit : function (newradius) {
- if((isFinite(String(newradius)))&&(newradius>0.0))
- {
- this._scene.space.radiusMode = "explicit";
- this._scene.space.explicitRadius = newradius;
- this.ui.postDrawEvent();
- }
- else
- return "ERROR - Not a radius";
-},
-
-//-----------------------------------------------------------------------------
-// instance solid color
-setInstanceSolidColorByName : function (name, newState, redraw, newColor) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL) {
- for (var inst in instances) {
- instances[inst].useSolidColor = newState;
- if(newColor)
- instances[inst].color = newColor;
- }
- }
- else {
- if(instances[name]) { // if an instance with that name exists
- instances[name].useSolidColor = newState;
- if(newColor)
- instances[name].color = newColor;
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-setInstanceSolidColor : function (tag, newState, redraw, newColor) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL) {
- instances[inst].useSolidColor = newState;
- if(newColor)
- instances[inst].color = newColor;
- }
- else {
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag){
- instances[inst].useSolidColor = newState;
- if(newColor)
- instances[inst].color = newColor;
- }
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceSolidColorByName : function (name, redraw) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL)
- for (var inst in instances)
- instances[inst].useSolidColor = !instances[inst].useSolidColor;
- else
- if(instances[name]) // if an instance with that name exists
- instances[name].useSolidColor = !instances[name].useSolidColor;
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceSolidColor : function (tag, redraw) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL)
- instances[inst].useSolidColor = !instances[inst].useSolidColor;
- else
- for (var tg in instances[inst].tags)
- if(instances[inst].tags[tg] == tag)
- instances[inst].useSolidColor = !instances[inst].useSolidColor;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-//-----------------------------------------------------------------------------
-// instance transparency
-setInstanceTransparencyByName : function (name, newState, redraw, newAlpha) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL) {
- for (var inst in instances)
- instances[inst].useTransparency = newState;
- if(newAlpha)
- instances[inst].alpha = newAlpha;
- }
- else {
- if(instances[name]) { // if an instance with that name exists
- instances[name].useTransparency = newState;
- if(newAlpha)
- instances[name].alpha = newAlpha;
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-setInstanceTransparency : function (tag, newState, redraw, newAlpha) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL) {
- instances[inst].useTransparency = newState;
- if(newAlpha)
- instances[inst].alpha = newAlpha;
- }
- else {
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag){
- instances[inst].useTransparency = newState;
- if(newAlpha)
- instances[inst].alpha = newAlpha;
- }
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceTransparencyByName : function (name, redraw) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL) {
- for (var inst in instances)
- instances[inst].useTransparency = !instances[inst].useTransparency;
- }
- else {
- if(instances[name]) // if an instance with that name exists
- instances[name].useTransparency = !instances[name].useTransparency;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceTransparency : function (tag, redraw) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL)
- {
- instances[inst].useTransparency = !instances[inst].useTransparency;
- }
- else
- {
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag)
- instances[inst].useTransparency = !instances[inst].useTransparency;
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-//-----------------------------------------------------------------------------
-// instance visibility
-setInstanceVisibilityByName : function (name, newState, redraw) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL) {
- for (var inst in instances)
- instances[inst].visible = newState;
- }
- else {
- if(instances[name]) // if an instance with that name exists
- instances[name].visible = newState;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-setInstanceVisibility : function (tag, newState, redraw) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL) {
- instances[inst].visible = newState;
- }
- else {
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag)
- instances[inst].visible = newState;
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceVisibilityByName : function (name, redraw) {
- var instances = this._scene.modelInstances;
-
- if(name == HOP_ALL) {
- for (var inst in instances)
- instances[inst].visible = !instances[inst].visible;
- }
- else {
- if(instances[name]) // if an instance with that name exists
- instances[name].visible = !instances[name].visible;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleInstanceVisibility : function (tag, redraw) {
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(tag == HOP_ALL)
- {
- instances[inst].visible = !instances[inst].visible;
- }
- else
- {
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag)
- instances[inst].visible = !instances[inst].visible;
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-isInstanceVisibilityEnabledByName : function (name) {
- var visibility = false;
- var instances = this._scene.modelInstances;
-
- if(!name || name==HOP_ALL) {
- for (var inst in instances) {
- if(instances[inst].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- else {
- if(instances[name]) { // if an instance with that name exists
- if(instances[name].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- return visibility;
-},
-
-isInstanceVisibilityEnabled : function (tag) {
- var visibility = false;
- var instances = this._scene.modelInstances;
-
- for (var inst in instances) {
- if(!tag || tag==HOP_ALL){
- if(instances[inst].visible){
- visibility = true;
- return visibility;
- }
- }
- else{
- for (var tg in instances[inst].tags){
- if(instances[inst].tags[tg] == tag){
- if(instances[inst].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- }
- }
- return visibility;
-},
-
-//-----------------------------------------------------------------------------
-// spot visibility
-setSpotVisibilityByName : function (name, newState, redraw) {
- var spots = this._scene.spots;
-
- if(name == HOP_ALL) {
- for (var spt in spots)
- spots[spt].visible = newState;
- }
- else {
- if(spots[name]) // if an hotspot with that name exists
- spots[name].visible = newState;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-setSpotVisibility : function (tag, newState, redraw) {
- var spots = this._scene.spots;
- for (var spt in spots) {
- if(tag == HOP_ALL)
- {
- spots[spt].visible = newState;
- }
- else
- {
- for (var tg in spots[spt].tags){
- if(spots[spt].tags[tg] == tag)
- spots[spt].visible = newState;
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleSpotVisibilityByName : function (name, redraw) {
- var spots = this._scene.spots;
- if(name == HOP_ALL) {
- for (var spt in spots)
- spots[spt].visible = !spots[spt].visible;
- }
- else {
- if(spots[name]) // if an hotspot with that name exists
- spots[name].visible = !spots[name].visible;
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-toggleSpotVisibility : function (tag, redraw) {
- var spots = this._scene.spots;
- for (var spt in spots) {
- if(tag == HOP_ALL)
- {
- spots[spt].visible = !spots[spt].visible;
- }
- else
- {
- for (var tg in spots[spt].tags){
- if(spots[spt].tags[tg] == tag)
- spots[spt].visible = !spots[spt].visible;
- }
- }
- }
- if(redraw)
- this.ui.postDrawEvent();
-},
-
-isSpotVisibilityEnabledByName : function (name) {
- var visibility = false;
- var spots = this._scene.spots;
-
- if(!name || name==HOP_ALL) {
- for (var spt in spots) {
- if(spots[spt].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- else {
- if(spots[name]) { // if an hotspot with that name exists
- if(spots[name].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- return visibility;
-},
-
-isSpotVisibilityEnabled : function (tag) {
- var visibility = false;
- var spots = this._scene.spots;
-
- for (var spt in spots) {
- if(!tag || tag==HOP_ALL){
- if(spots[spt].visible){
- visibility = true;
- return visibility;
- }
- }
- else{
- for (var tg in spots[spt].tags){
- if(spots[spt].tags[tg] == tag){
- if(spots[spt].visible){
- visibility = true;
- return visibility;
- }
- }
- }
- }
- }
- return visibility;
-},
-
-//-----------------------------------------------------------------------------
-// sections
-resetClippingXYZ: function() {
- this._calculateBounding();
- this._clipAxis = [0.0, 0.0, 0.0];
- this._clipPoint = [0.0, 0.0, 0.0];
- this.ui.postDrawEvent();
-},
-
-setClippingXYZ: function(cx, cy, cz) {
- this._calculateBounding();
- this._clipAxis = [cx,cy,cz];
- this.ui.postDrawEvent();
-},
-
-setClippingX: function(cx) {
- this._calculateBounding();
- this._clipAxis[0] = cx;
- this.ui.postDrawEvent();
-},
-setClippingY: function(cy) {
- this._calculateBounding();
- this._clipAxis[1] = cy;
- this.ui.postDrawEvent();
-},
-setClippingZ: function(cz) {
- this._calculateBounding();
- this._clipAxis[2] = cz;
- this.ui.postDrawEvent();
-},
-
-getClippingX : function () {
- return this._clipAxis[0];
-},
-getClippingY : function () {
- return this._clipAxis[1];
-},
-getClippingZ : function () {
- return this._clipAxis[2];
-},
-
-setClippingPointXYZabs: function(clx, cly, clz) {
- this._calculateBounding();
- this._clipPoint = [clx, cly, clz];
- this.ui.postDrawEvent();
-},
-
-setClippingPointXabs: function(clx) {
- this._calculateBounding();
- this._clipPoint[0] = clx;
- this.ui.postDrawEvent();
-},
-setClippingPointYabs: function(cly) {
- this._calculateBounding();
- this._clipPoint[1] = cly;
- this.ui.postDrawEvent();
-},
-setClippingPointZabs: function(clz) {
- this._calculateBounding();
- this._clipPoint[2] = clz;
- this.ui.postDrawEvent();
-},
-
-setClippingPointXYZ: function(clx, cly, clz) {
- var nClipPoint = [0.0, 0.0, 0.0];
-
- this._calculateBounding();
-
- if(clx<0.0) clx=0.0; else if(clx>1.0) clx=1.0;
- if(cly<0.0) cly=0.0; else if(cly>1.0) cly=1.0
- if(clz<0.0) clz=0.0; else if(clz>1.0) clz=1.0;
-
- nClipPoint[0] = this._sceneBboxMin[0] + clx * (this._sceneBboxMax[0] - this._sceneBboxMin[0]);
- nClipPoint[1] = this._sceneBboxMin[1] + cly * (this._sceneBboxMax[1] - this._sceneBboxMin[1]);
- nClipPoint[2] = this._sceneBboxMin[2] + clz * (this._sceneBboxMax[2] - this._sceneBboxMin[2]);
-
- this._clipPoint = nClipPoint;
- this.ui.postDrawEvent();
-},
-
-setClippingPointX: function(clx) {
- var nClipPoint = 0.0;
- this._calculateBounding();
- if(clx<0.0) clx=0.0; else if(clx>1.0) clx=1.0;
- nClipPoint = this._sceneBboxMin[0] + clx * (this._sceneBboxMax[0] - this._sceneBboxMin[0]);
- this._clipPoint[0] = nClipPoint;
- this.ui.postDrawEvent();
-},
-setClippingPointY: function(cly) {
- var nClipPoint = 0.0;
- this._calculateBounding();
- if(cly<0.0) cly=0.0; else if(cly>1.0) cly=1.0;
- nClipPoint = this._sceneBboxMin[1] + cly * (this._sceneBboxMax[1] - this._sceneBboxMin[1]);
- this._clipPoint[1] = nClipPoint;
- this.ui.postDrawEvent();
-},
-setClippingPointZ: function(clz) {
- var nClipPoint = 0.0;
- this._calculateBounding();
- if(clz<0.0) clz=0.0; else if(clz>1.0) clz=1.0;
- nClipPoint = this._sceneBboxMin[2] + clz * (this._sceneBboxMax[2] - this._sceneBboxMin[2]);
- this._clipPoint[2] = nClipPoint;
- this.ui.postDrawEvent();
-},
-
-_calculateBounding: function() {
var meshes = this._scene.meshes;
- var instances = this._scene.modelInstances;
- this._sceneBboxMin = SglVec3.maxNumber();
- this._sceneBboxMax = SglVec3.minNumber();
- this._sceneBboxCenter = [0.0, 0.0, 0.0];
- var imin = [0.0, 0.0, 0.0];
- var imax = [0.0, 0.0, 0.0];
-
- for (var inst in instances) {
- var mesh = meshes[instances[inst].mesh];
- if((mesh)&&(mesh.renderable)&&(instances[inst].clippable)){
- var instCenter = SglVec3.to4(mesh.renderable.datasetCenter,1);
- instCenter = SglMat4.mul4(mesh.transform.matrix, instCenter);
- instCenter = SglMat4.mul4(instances[inst].transform.matrix, instCenter);
- instCenter = SglMat4.mul4(this._scene.space.transform.matrix, instCenter);
- instCenter = SglVec4.to3(instCenter);
-
- var radius = mesh.renderable.datasetRadius;
- var vector111 = SglVec3.one();
- vector111 = SglMat3.mul3(SglMat4.to33(mesh.transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(instances[inst].transform.matrix), vector111);
- vector111 = SglMat3.mul3(SglMat4.to33(this._scene.space.transform.matrix), vector111);
- var scalefactor = SglVec3.length(vector111) / SglVec3.length([1,1,1]);
- radius = radius*scalefactor;
-
- imin[0] = instCenter[0] - radius;
- imin[1] = instCenter[1] - radius;
- imin[2] = instCenter[2] - radius;
- imax[0] = instCenter[0] + radius;
- imax[1] = instCenter[1] + radius;
- imax[2] = instCenter[2] + radius;
-
- if(imin[0] < this._sceneBboxMin[0]) this._sceneBboxMin[0] = imin[0];
- if(imin[1] < this._sceneBboxMin[1]) this._sceneBboxMin[1] = imin[1];
- if(imin[2] < this._sceneBboxMin[2]) this._sceneBboxMin[2] = imin[2];
- if(imax[0] > this._sceneBboxMax[0]) this._sceneBboxMax[0] = imax[0];
- if(imax[1] > this._sceneBboxMax[1]) this._sceneBboxMax[1] = imax[1];
- if(imax[2] > this._sceneBboxMax[2]) this._sceneBboxMax[2] = imax[2];
- }
- }
-
- this._sceneBboxCenter[0] = (this._sceneBboxMin[0] + this._sceneBboxMax[0]) / 2.0;
- this._sceneBboxCenter[1] = (this._sceneBboxMin[1] + this._sceneBboxMax[1]) / 2.0;
- this._sceneBboxCenter[2] = (this._sceneBboxMin[2] + this._sceneBboxMax[2]) / 2.0;
-},
-
-setClippingRendermode: function(showPlanes, showBorder, borderSize, borderColor) {
- this._calculateBounding();
- this._scene.config.showClippingPlanes = showPlanes;
- this._scene.config.showClippingBorder = showBorder;
- if(borderSize>0.0)
- this._scene.config.clippingBorderSize = borderSize;
- if(borderColor)
- this._scene.config.clippingBorderColor = borderColor;
- this.ui.postDrawEvent();
-},
-
-getClippingRendermode: function() {
- var rendermode = [this._scene.config.showClippingPlanes, this._scene.config.showClippingBorder, this._scene.config.clippingBorderSize, this._scene.config.clippingBorderColor];
- return rendermode;
-},
-
-//-----------------------------------------------------------------------------
-zoomIn: function() {
- this.onMouseWheel(1);
-},
-
-zoomOut: function() {
- this.onMouseWheel(-1);
-},
-
-//-----------------------------------------------------------------------------
-rotateLight: function(x, y) {
- x *= 2;
- y *= 2;
- var r = Math.sqrt(x*x + y*y);
- if(r >= 1) {
- x /= r;
- y /= r;
- r = 0.999;
- }
- var z = Math.sqrt(1 - r*r);
- this._lightDirection = [-x, -y, -z];
- this.ui.postDrawEvent();
-},
-
-enableLightTrackball: function(on) {
- this._movingLight = on;
-},
-
-isLightTrackballEnabled: function() {
- return this._movingLight;
-},
-
-//-----------------------------------------------------------------------------
-enableOnHover: function(on) {
- this._onHover = on;
-},
-
-isOnHoverEnabled: function() {
- return this._onHover;
-},
-
-//-----------------------------------------------------------------------------
-enableMeasurementTool: function(on) {
- if(on)
- this._startMeasurement();
- else
- this._stopMeasurement();
-},
-
-isMeasurementToolEnabled: function() {
- return this._isMeasuringDistance;
-},
-
-//-----------------------------------------------------------------------------
-enablePickpointMode: function(on) {
- if(on)
- this._startPickPoint();
- else
- this._stopPickPoint();
-},
-
-isPickpointModeEnabled: function() {
- return this._isMeasuringPickpoint;
-},
-
-//-----------------------------------------------------------------------------
-isAnyMeasurementEnabled: function() {
- return this._isMeasuring;
-},
-
-//-----------------------------------------------------------------------------
-toggleCameraType: function() {
- if(this._scene.space.cameraType == "ortho")
- this._scene.space.cameraType = "perspective"
- else
- this._scene.space.cameraType = "ortho"
-
- this.ui.postDrawEvent();
-},
-
-setCameraPerspective() {
- this._scene.space.cameraType = "perspective";
- this.ui.postDrawEvent();
-},
-setCameraOrthographic() {
- this._scene.space.cameraType = "ortho";
- this.ui.postDrawEvent();
-},
-
-//-----------------------------------------------------------------------------
-repaint() {
- this.ui.postDrawEvent();
-},
-
-}; // Presenter.prototype END
diff --git a/all_tools/js/spidergl.js b/all_tools/js/spidergl.js
deleted file mode 100644
index 211be7a..0000000
--- a/all_tools/js/spidergl.js
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
-SpiderGL Computer Graphics Library
-Copyright (c) 2010, Marco Di Benedetto - Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
- * Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
- * Neither the name of SpiderGL nor the
- names of its contributors may be used to endorse or promote products
- derived from this software without specific prior written permission.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL PAUL BRUNT BE LIABLE FOR ANY
-DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
-ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
-SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-var SpiderGL={};SpiderGL.TAG=0,SpiderGL.openNamespace=function(a){function c(a){return b.test(a)}function e(a){return d.test(a)&&!c(a)}function g(a){return f.test(a)}function h(a){return a.substr(0,1).toUpperCase()+a.substr(1)}function l(a){if(a)for(var b in a)if("_"!=b.substr(0,1)){var d=a[b];e(b)?i[b]=d:g(b)?j[b]=d:c(b)&&(k[b]=d)}}a=SpiderGL.Utility.getDefaultObject({globalObject:SpiderGL.openNamespace.DEFAULT_GLOBAL_OBJECT,constantPrefix:SpiderGL.openNamespace.DEFAULT_CONSTANT_PREFIX,functionPrefix:SpiderGL.openNamespace.DEFAULT_FUNCTION_PREFIX,classPrefix:SpiderGL.openNamespace.DEFAULT_CLASS_PREFIX},a);var b=new RegExp("^(([_$0-9A-Z])+)$"),d=new RegExp("^([A-Z])"),f=new RegExp("^(([a-z])+([_$0-9A-Za-z])*)$"),i={},j={},k={},m=["Core","DOM","IO","Math","Mesh","Model","Semantic","Space","Type","UserInterface","Utility","Version","WebGL"];for(var n in m)l(SpiderGL[m[n]]);for(var n in i){var o=a.classPrefix+h(n);a.globalObject[o]=i[n]}for(var n in j){var o=a.functionPrefix+h(n);a.globalObject[o]=j[n]}for(var n in k){var o=a.constantPrefix+h(n);a.globalObject[o]=k[n]}},SpiderGL.openNamespace.DEFAULT_GLOBAL_OBJECT=window,SpiderGL.openNamespace.DEFAULT_CONSTANT_PREFIX="SGL_",SpiderGL.openNamespace.DEFAULT_FUNCTION_PREFIX="sgl",SpiderGL.openNamespace.DEFAULT_CLASS_PREFIX="Sgl",SpiderGL.Version={},SpiderGL.Version.VERSION_MAJOR=0,SpiderGL.Version.VERSION_MINOR=2,SpiderGL.Version.VERSION_REVISION=1,SpiderGL.Version.VERSION_STRING=SpiderGL.Version.VERSION_MAJOR+"."+SpiderGL.Version.VERSION_MINOR+"."+SpiderGL.Version.VERSION_REVISION,SpiderGL.Core={},SpiderGL.Core.DEFAULT={},SpiderGL.Core.DONT_CARE={},SpiderGL.Core.EMPTY_STRING="",SpiderGL.Core.EMPTY_OBJECT={},SpiderGL.Core.EMPTY_ARRAY=[],SpiderGL.Core.EMPTY_FUNCTION=function(){},SpiderGL.Core.generateUID=function(){return SpiderGL.Core.generateUID._lastUID++,SpiderGL.Core.generateUID._lastUID},SpiderGL.Core.generateUID._lastUID=0,SpiderGL.Core.ObjectBase=function(){this._uid=SpiderGL.Core.generateUID()},SpiderGL.Core.ObjectBase.prototype={get uid(){return this._uid}},SpiderGL.Type={},SpiderGL.Type.LITTLE_ENDIAN=function(){var a=new Uint8Array([18,52]),b=new Uint16Array(a.buffer);return 13330==b[0]}(),SpiderGL.Type.BIG_ENDIAN=!SpiderGL.Type.BIG_ENDIAN,SpiderGL.Type.NO_TYPE=0,SpiderGL.Type.INT8=1,SpiderGL.Type.UINT8=2,SpiderGL.Type.INT16=3,SpiderGL.Type.UINT16=4,SpiderGL.Type.INT32=5,SpiderGL.Type.UINT32=6,SpiderGL.Type.FLOAT32=7,SpiderGL.Type.SIZEOF_INT8=Int8Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_UINT8=Uint8Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_INT16=Int16Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_UINT16=Uint16Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_INT32=Int32Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_UINT32=Uint32Array.BYTES_PER_ELEMENT,SpiderGL.Type.SIZEOF_FLOAT32=Float32Array.BYTES_PER_ELEMENT,SpiderGL.Type.typeSize=function(){var a={};return a[SpiderGL.Type.NO_TYPE]=0,a[SpiderGL.Type.INT8]=SpiderGL.Type.SIZEOF_INT8,a[SpiderGL.Type.UINT8]=SpiderGL.Type.SIZEOF_UINT8,a[SpiderGL.Type.INT16]=SpiderGL.Type.SIZEOF_INT16,a[SpiderGL.Type.UINT16]=SpiderGL.Type.SIZEOF_UINT16,a[SpiderGL.Type.INT32]=SpiderGL.Type.SIZEOF_INT32,a[SpiderGL.Type.UINT32]=SpiderGL.Type.SIZEOF_UINT32,a[SpiderGL.Type.FLOAT32]=SpiderGL.Type.SIZEOF_FLOAT32,function(b){return a[b]}}(),SpiderGL.Type.typeToGL=function(){var a={};return a[SpiderGL.Type.NO_TYPE]=WebGLRenderingContext.prototype.NONE,a[SpiderGL.Type.INT8]=WebGLRenderingContext.prototype.BYTE,a[SpiderGL.Type.UINT8]=WebGLRenderingContext.prototype.UNSIGNED_BYTE,a[SpiderGL.Type.INT16]=WebGLRenderingContext.prototype.SHORT,a[SpiderGL.Type.UINT16]=WebGLRenderingContext.prototype.UNSIGNED_SHORT,a[SpiderGL.Type.INT32]=WebGLRenderingContext.prototype.INT,a[SpiderGL.Type.UINT32]=WebGLRenderingContext.prototype.UNSIGNED_INT,a[SpiderGL.Type.FLOAT32]=WebGLRenderingContext.prototype.FLOAT,function(b){return a[b]}}(),SpiderGL.Type.typeFromGL=function(){var a={};return a[WebGLRenderingContext.prototype.NONE]=SpiderGL.Type.NO_TYPE,a[WebGLRenderingContext.prototype.BYTE]=SpiderGL.Type.INT8,a[WebGLRenderingContext.prototype.UNSIGNED_BYTE]=SpiderGL.Type.UINT8,a[WebGLRenderingContext.prototype.SHORT]=SpiderGL.Type.INT16,a[WebGLRenderingContext.prototype.UNSIGNED_SHORT]=SpiderGL.Type.UINT16,a[WebGLRenderingContext.prototype.INT]=SpiderGL.Type.INT32,a[WebGLRenderingContext.prototype.UNSIGNED_INT]=SpiderGL.Type.UINT32,a[WebGLRenderingContext.prototype.FLOAT]=SpiderGL.Type.FLOAT32,function(b){return a[b]}}(),SpiderGL.Type.typeSizeFromGL=function(a){var b=SpiderGL.Type.typeFromGL(a);return SpiderGL.Type.typeSize(b)},SpiderGL.Type.typeToTypedArrayConstructor=function(){var a={};return a[SpiderGL.Type.NO_TYPE]=ArrayBuffer,a[SpiderGL.Type.INT8]=Int8Array,a[SpiderGL.Type.UINT8]=Uint8Array,a[SpiderGL.Type.INT16]=Int16Array,a[SpiderGL.Type.UINT16]=Uint16Array,a[SpiderGL.Type.INT32]=Int32Array,a[SpiderGL.Type.UINT32]=Uint32Array,a[SpiderGL.Type.FLOAT32]=Float32Array,function(b){return a[b]}}(),SpiderGL.Type.POINTS=0,SpiderGL.Type.LINES=1,SpiderGL.Type.LINE_LOOP=2,SpiderGL.Type.LINE_STRIP=3,SpiderGL.Type.TRIANGLES=4,SpiderGL.Type.TRIANGLE_FAN=5,SpiderGL.Type.TRIANGLE_STRIP=6,SpiderGL.Type.primitiveToGL=function(){var a={};return a[SpiderGL.Type.POINTS]=WebGLRenderingContext.prototype.POINTS,a[SpiderGL.Type.LINES]=WebGLRenderingContext.prototype.LINES,a[SpiderGL.Type.LINE_LOOP]=WebGLRenderingContext.prototype.LINE_LOOP,a[SpiderGL.Type.LINE_STRIP]=WebGLRenderingContext.prototype.LINE_STRIP,a[SpiderGL.Type.TRIANGLES]=WebGLRenderingContext.prototype.TRIANGLES,a[SpiderGL.Type.TRIANGLE_FAN]=WebGLRenderingContext.prototype.TRIANGLE_FAN,a[SpiderGL.Type.TRIANGLE_STRIP]=WebGLRenderingContext.prototype.TRIANGLE_STRIP,function(b){return a[b]}}(),SpiderGL.Type.instanceOf=function(a,b){return a instanceof b},SpiderGL.Type.isNumber=function(a){return"number"==typeof a},SpiderGL.Type.isString=function(a){return"string"==typeof a},SpiderGL.Type.isFunction=function(a){return"function"==typeof a},SpiderGL.Type.isArray=function(a){return a&&a.constructor===Array},SpiderGL.Type.isTypedArray=function(a){return a&&"undefined"!=typeof a.buffer&&a.buffer instanceof ArrayBuffer},SpiderGL.Type.extend=function(a,b){function c(){}c.prototype=b.prototype;var d=a.prototype,e=new c;e.constructor=a;var f=null,g=null;for(var h in d)f=d.__lookupGetter__(h),f&&e.__defineGetter__(h,f),g=d.__lookupSetter__(h),g&&e.__defineSetter__(h,g),f||g||(e[h]=d[h]);a.prototype=e},SpiderGL.Type.defineClassGetter=function(a,b,c){a.prototype.__defineGetter__(b,c)},SpiderGL.Type.defineClassSetter=function(a,b,c){a.prototype.__defineSetter__(b,c)},SpiderGL.Type.defineObjectGetter=function(a,b,c){a.__defineGetter__(b,c)},SpiderGL.Type.defineObjectSetter=function(a,b,c){a.__defineSetter__(b,c)},SpiderGL.Utility={},SpiderGL.Utility.getDefaultValue=function(a,b){return void 0===a||a===SpiderGL.Core.DEFAULT?b:a},SpiderGL.Utility.getDefaultObject=function(a,b){if(b){var c=SpiderGL.Core.DEFAULT;for(var d in b)b[d]!=c&&(a[d]=b[d])}return a},SpiderGL.Utility.setDefaultValues=function(a,b){if(!b)return a;var c=SpiderGL.Core.DEFAULT;for(var d in b)b[d]==c&&"undefined"!=typeof a[d]&&(b[d]=a[d]);for(var d in a)"undefined"==typeof b[d]&&(b[d]=a[d]);return b},SpiderGL.Utility.getAttrib4fv=function(a){return SpiderGL.Type.isNumber(a)?[a,0,0,1]:a?[void 0!=a[0]?a[0]:0,void 0!=a[1]?a[1]:0,void 0!=a[2]?a[2]:0,void 0!=a[3]?a[3]:1]:[0,0,0,1]},SpiderGL.Utility.getTime=function(){return(new Date).getTime()},SpiderGL.Utility.Timer=function(){this._tStart=-1,this._tElapsed=0},SpiderGL.Utility.Timer.prototype={_accumElapsed:function(){this._tElapsed+=this.now-this._tStart},get now(){return Date.now()},start:function(){this.isStarted||this.isPaused||(this._tStart=this.now,this._tElapsed=0)},restart:function(){var a=this.elapsed;return this._tStart=this.now,this._tElapsed=0,a},stop:function(){this.isStarted&&(this.isPaused||(this._accumElapsed(),this._tStart=-1))},get isStarted(){return this._tStart>=0},pause:function(){this.isStarted&&(this.isPaused||(this._accumElapsed(),this._tStart=-2))},resume:function(){this.isStarted&&this.isPaused&&(this._tStart=this.now)},get isPaused(){return this._tStart==-2},get elapsed(){return this.isStarted?this._tElapsed+(this.now-this._tStart):this._tElapsed}},SpiderGL.DOM={},SpiderGL.DOM.getElementById=function(a){return document.getElementById(a)},SpiderGL.DOM.getElementText=function(a){var b=document.getElementById(a);if(!b)return null;var c="";for(b=b.firstChild;b;)3==b.nodeType&&(c+=b.textContent),b=b.nextSibling;return c},SpiderGL.IO={},SpiderGL.IO.Request=function(a,b){SpiderGL.Core.ObjectBase.call(this),b=SpiderGL.Utility.getDefaultObject({async:SpiderGL.IO.Request.DEFAULT_ASYNC,send:SpiderGL.IO.Request.DEFAULT_SEND,onProgress:null,onCancel:null,onError:null,onSuccess:null,onFinish:null},b),this._url=a,this._async=b.async,this._status=SpiderGL.IO.Request.NONE,this._sent=!1,this._aborted=!1,this._data=null,this._loaded=0,this._total=0,this._events={progress:{main:null,listeners:[]},cancel:{main:null,listeners:[]},error:{main:null,listeners:[]},success:{main:null,listeners:[]},finish:{main:null,listeners:[]}},this.onProgress=b.onProgress,this.onCancel=b.onCancel,this.onError=b.onError,this.onSuccess=b.onSuccess,this.onFinish=b.onFinish},SpiderGL.IO.Request.NONE=0,SpiderGL.IO.Request.ONGOING=1,SpiderGL.IO.Request.CANCELLED=2,SpiderGL.IO.Request.FAILED=3,SpiderGL.IO.Request.SUCCEEDED=4,SpiderGL.IO.Request.DEFAULT_ASYNC=!0,SpiderGL.IO.Request.DEFAULT_SEND=!0,SpiderGL.IO.Request.prototype={_indexOf:function(a,b){for(var c=0,d=a.length;c=0||c.listeners.push(b)}}},removeEventListener:function(a,b){var c=this._events[a];if(c){var d=this._indexOf(c.listeners,b);d<0||c.listeners.splice(d,1)}},get onProgress(){return this._events.progress.main},set onProgress(a){this._setMainListener("progress",a)},get onCancel(){return this._events.cancel.main},set onCancel(a){this._setMainListener("cancel",a)},get onError(){return this._events.error.main},set onError(a){this._setMainListener("error",a)},get onSuccess(){return this._events.success.main},set onSuccess(a){this._setMainListener("success",a)},get onFinish(){return this._events.finish.main},set onFinish(a){this._setMainListener("finish",a)},cancel:function(){if(!this.ongoing)return!1;this._status=SpiderGL.IO.Request.CANCELLED,this._aborted=!0;var a=this._doCancel();return this._finishTime=SpiderGL.Utility.getTime(),a},send:function(){if(!this.canSend)return!1;this._data=null,this._status=SpiderGL.IO.Request.ONGOING,this._aborted=!1,this._sent=!0,this._finishTime=-1,this._startTime=SpiderGL.Utility.getTime();var a=this._doSend();return a||(this._startTime=-1,this._status=SpiderGL.IO.Request.NONE,this._sent=!1),a}},SpiderGL.Type.extend(SpiderGL.IO.Request,SpiderGL.Core.ObjectBase),SpiderGL.IO.XHRRequestBase=function(a,b){b=b||{},SpiderGL.IO.Request.call(this,a,b);var c=this,d=new XMLHttpRequest;if(this._xhr=d,d.onprogress=function(a){c._xhrOnProgress(a)},d.onabort=function(){c._doOnCancel(),c._doOnFinish()},d.onerror=function(){c._doOnError(),c._doOnFinish()},d.onload=function(){var a=d.status;0===a||200===a||c._range&&206==a?c._doOnSuccess():c._doOnError(),c._doOnFinish()},this._range=null,this._xhr.open("GET",this._url,this._async),"range"in b){this._range=[b.range[0],b.range[1]];var e="bytes="+b.range[0]+"-"+b.range[1];d.setRequestHeader("Range",e)}this._prepareXHR();var f=SpiderGL.Utility.getDefaultValue(b.send,SpiderGL.IO.Request.DEFAULT_SEND);f&&this.send()},SpiderGL.IO.XHRRequestBase.prototype={_prepareXHR:function(){},_doCancel:function(){return this._xhr.abort(),this._xhr=new XMLHttpRequest,this._xhr.open("GET",this._url,this._async),this._prepareXHR(),!0},_doSend:function(){return this._xhr.send(),!0},_xhrOnProgress:function(a){var b=0,c=0;a&&a.lengthComputable&&(b=a.loaded,c=a.total),this._doOnProgress(b,c)}},SpiderGL.Type.extend(SpiderGL.IO.XHRRequestBase,SpiderGL.IO.Request),SpiderGL.IO.XHRRequest=function(a,b){SpiderGL.IO.XHRRequestBase.call(this,a,b)},SpiderGL.IO.XHRRequest.prototype={_doPostSuccess:function(){this._data=this._xhr.responseText},get xhr(){return this._xhr},get response(){return this.data}},SpiderGL.Type.extend(SpiderGL.IO.XHRRequest,SpiderGL.IO.XHRRequestBase),SpiderGL.IO.TextRequest=function(a,b){SpiderGL.IO.XHRRequestBase.call(this,a,b)},SpiderGL.IO.TextRequest.prototype={_doPostSuccess:function(){this._data=this._xhr.responseText},get text(){return this.data}},SpiderGL.Type.extend(SpiderGL.IO.TextRequest,SpiderGL.IO.XHRRequestBase),SpiderGL.IO.readText=function(a){var b=new SpiderGL.IO.TextRequest(a,{async:!1});return b.text},SpiderGL.IO.requestText=function(a,b){b=SpiderGL.Utility.getDefaultObject({},b),b.async=!0,b.send=!0;var c=new SpiderGL.IO.TextRequest(a,b);return c},SpiderGL.IO.JSONRequest=function(a,b){SpiderGL.IO.XHRRequestBase.call(this,a,b)},SpiderGL.IO.JSONRequest.prototype={_doPostSuccess:function(){this._data=JSON.parse(this._xhr.responseText)},get text(){return this._xhr.responseText},get json(){return this.data}},SpiderGL.Type.extend(SpiderGL.IO.JSONRequest,SpiderGL.IO.XHRRequestBase),SpiderGL.IO.readJSON=function(a){var b=new SpiderGL.IO.JSONRequest(a,{async:!1});return b.json},SpiderGL.IO.requestJSON=function(a,b){b=SpiderGL.Utility.getDefaultObject({},b),b.async=!0,b.send=!0;var c=new SpiderGL.IO.JSONRequest(a,b);return c},SpiderGL.IO.BinaryRequest=function(a,b){SpiderGL.IO.XHRRequestBase.call(this,a,b)},SpiderGL.IO.BinaryRequest.prototype={_prepareXHR:function(){var a=this._xhr,b=!1;b&&a.overrideMimeType("text/plain; charset=x-user-defined"),a.responseType="arraybuffer"},_setArrayBuffer:function(){var a=this._xhr;if("arraybuffer"==a.responseType)this._data=a.response;else if(null!=a.mozResponseArrayBuffer)this._data=a.mozResponseArrayBuffer;else if(null!=a.responseText){for(var b=new String(a.responseText),c=new Array(b.length),d=0,e=b.length;d0?this._doOnError():this._doOnSuccess()),this._eventReq=null)},_reqOnFinish:function(a){var b=this._indexOf(this._requests,a);b<0||(this._uninstallProxies(a),this._eventReq=a,this._requestsFinished&&(this._eventReq=this,this._doOnFinish()),this._eventReq=null)},get eventSenderRequest(){return this._eventReq},get requests(){return this._requests.slice()},get requests$(){return this._requests},get startTime(){return this._aggrStartTime},get finishTime(){return this._aggrFinishTime},get elapsedTime(){return this._aggrStartTime<0?0:this._aggrFinishTime<0?SpiderGL.Utility.getTime()-this._aggrStartTime:this._aggrFinishTime-this._aggrStartTime},addRequest:function(a){if(a&&!this._sent){var b=this._indexOf(this._requests,a);b>=0||this._requests.push(a)}},removeRequest:function(a){if(a&&!this._sent){var b=this._indexOf(this._requests,a);b<0||this._requests.splice(b,1)}}},SpiderGL.Type.extend(SpiderGL.IO.AggregateRequest,SpiderGL.IO.Request),SpiderGL.Math={},SpiderGL.Math.DEG_TO_RAD=Math.PI/180,SpiderGL.Math.E=Math.E,SpiderGL.Math.LN2=Math.LN2,SpiderGL.Math.LN10=Math.LN10,SpiderGL.Math.LOG2E=Math.LOG2E,SpiderGL.Math.LOG10E=Math.LOG10E,SpiderGL.Math.PI=Math.PI,SpiderGL.Math.RAD_TO_DEG=180/Math.PI,SpiderGL.Math.SQRT2=Math.SQRT2,SpiderGL.Math.MAX_VALUE=Number.MAX_VALUE,SpiderGL.Math.MIN_VALUE=Number.MIN_VALUE,SpiderGL.Math.MAX_NUMBER=SpiderGL.Math.MAX_VALUE,SpiderGL.Math.MIN_NUMBER=-SpiderGL.Math.MAX_VALUE,SpiderGL.Math.NAN=Number.NaN,SpiderGL.Math.INFINITY=1/0,SpiderGL.Math.abs=function(a){return Math.abs(a)},SpiderGL.Math.acos=function(a){return Math.acos(a)},SpiderGL.Math.asin=function(a){return Math.asin(a)},SpiderGL.Math.atan=function(a){return Math.atan(a)},SpiderGL.Math.atan2=function(a,b){return Math.atan2(a,b)},SpiderGL.Math.ceil=function(a){return Math.ceil(a)},SpiderGL.Math.clamp=function(a,b,c){return a<=b?b:a>=c?c:a},SpiderGL.Math.cos=function(a){return Math.cos(a)},SpiderGL.Math.degToRad=function(a){return a*SpiderGL.Math.DEG_TO_RAD},SpiderGL.Math.exp=function(a){return Math.exp(a)},SpiderGL.Math.floor=function(a){return Math.floor(a)},SpiderGL.Math.lerp=function(a,b,c){return a+c*(b-a)},SpiderGL.Math.ln=function(a){return Math.log(a)},SpiderGL.Math.log=function(a){return Math.log(a)},SpiderGL.Math.log2=function(a){return SpiderGL.Math.log(a)/SpiderGL.Math.LN2},SpiderGL.Math.log10=function(a){return SpiderGL.Math.log(a)/SpiderGL.Math.LN10},SpiderGL.Math.max=function(a){return Math.max.apply(Math,arguments)},SpiderGL.Math.min=function(a){return Math.min.apply(Math,arguments)},SpiderGL.Math.pow=function(a,b){return Math.pow(a,b)},SpiderGL.Math.radToDeg=function(a){return a*SpiderGL.Math.RAD_TO_DEG},SpiderGL.Math.random=function(){return Math.random()},SpiderGL.Math.random01=function(){return SpiderGL.Math.random()},SpiderGL.Math.random11=function(){return 2*SpiderGL.Math.random()-1},SpiderGL.Math.randomRange=function(a,b){return a+SpiderGL.Math.random()*(b-a)},SpiderGL.Math.round=function(a){return Math.sqrt(a)},SpiderGL.Math.sin=function(a){return Math.sin(a)},SpiderGL.Math.sqrt=function(a){return Math.sqrt(a)},SpiderGL.Math.tan=function(a){return Math.tan(a)},SpiderGL.Math.Vec2={},SpiderGL.Math.Vec2.dup=function(a){return a.slice(0,2)},SpiderGL.Math.Vec2.scalar=function(a){return[a,a]},SpiderGL.Math.Vec2.zero=function(){return[0,0]},SpiderGL.Math.Vec2.one=function(){return[1,1]},SpiderGL.Math.Vec2.maxNumber=function(){return[SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER]},SpiderGL.Math.Vec2.minNumber=function(){return[SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER]},SpiderGL.Math.Vec2.to3=function(a,b){return[a[0],a[1],void 0!=b?b:0]},SpiderGL.Math.Vec2.to4=function(a,b,c){return[a[0],a[1],a[2],void 0!=b?b:0,void 0!=c?c:1]},SpiderGL.Math.Vec2.neg=function(a){return[-a[0],-a[1]]},SpiderGL.Math.Vec2.add=function(a,b){return[a[0]+b[0],a[1]+b[1]]},SpiderGL.Math.Vec2.adds=function(a,b){return[a[0]+b,a[1]+b]},SpiderGL.Math.Vec2.sub=function(a,b){return[a[0]-b[0],a[1]-b[1]]},SpiderGL.Math.Vec2.subs=function(a,b){return[a[0]-b,a[1]-b]},SpiderGL.Math.Vec2.ssub=function(a,b){return[a-b[0],a-b[1]]},SpiderGL.Math.Vec2.mul=function(a,b){return[a[0]*b[0],a[1]*b[1]]},SpiderGL.Math.Vec2.muls=function(a,b){return[a[0]*b,a[1]*b]},SpiderGL.Math.Vec2.div=function(a,b){return[a[0]/b[0],a[1]/b[1]]},SpiderGL.Math.Vec2.divs=function(a,b){return[a[0]/b,a[1]/b]},SpiderGL.Math.Vec2.sdiv=function(a,b){return[a/b[0],a/b[1]]},SpiderGL.Math.Vec2.rcp=function(a){return[1/a[0],1/a[1]]},SpiderGL.Math.Vec2.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]},SpiderGL.Math.Vec2.cross=function(a,b){return a[0]*b[1]-a[1]*b[0]},SpiderGL.Math.Vec2.perp=function(a){return[a[1],-a[0]]},SpiderGL.Math.Vec2.sqLength=function(a){return SpiderGL.Math.Vec2.dot(a,a)},SpiderGL.Math.Vec2.length=function(a){return SpiderGL.Math.sqrt(SpiderGL.Math.Vec2.sqLength(a))},SpiderGL.Math.Vec2.normalize=function(a){var b=1/SpiderGL.Math.Vec2.length(a);return SpiderGL.Math.Vec2.muls(a,b)},SpiderGL.Math.Vec2.abs=function(a){return[SpiderGL.Math.abs(a[0]),SpiderGL.Math.abs(a[1])]},SpiderGL.Math.Vec2.acos=function(a){return[SpiderGL.Math.acos(a[0]),SpiderGL.Math.acos(a[1])]},SpiderGL.Math.Vec2.asin=function(a){return[SpiderGL.Math.asin(a[0]),SpiderGL.Math.asin(a[1])]},SpiderGL.Math.Vec2.atan=function(a){return[SpiderGL.Math.atan(a[0]),SpiderGL.Math.atan(a[1])]},SpiderGL.Math.Vec2.atan2=function(a,b){return[SpiderGL.Math.atan2(a[0],b[0]),SpiderGL.Math.atan2(a[1],b[1])]},SpiderGL.Math.Vec2.ceil=function(a){return[SpiderGL.Math.ceil(a[0]),SpiderGL.Math.ceil(a[1])]},SpiderGL.Math.Vec2.clamp=function(a,b,c){return[SpiderGL.Math.clamp(a[0],b[0],c[0]),SpiderGL.Math.clamp(a[1],b[1],c[1])]},SpiderGL.Math.Vec2.cos=function(a){return[SpiderGL.Math.cos(a[0]),SpiderGL.Math.cos(a[1])]},SpiderGL.Math.Vec2.degToRad=function(a){return[SpiderGL.Math.degToRad(a[0]),SpiderGL.Math.degToRad(a[1])]},SpiderGL.Math.Vec2.exp=function(a){return[SpiderGL.Math.exp(a[0]),SpiderGL.Math.exp(a[1])]},SpiderGL.Math.Vec2.floor=function(a){return[SpiderGL.Math.floor(a[0]),SpiderGL.Math.floor(a[1])]},SpiderGL.Math.Vec2.lerp=function(a,b,c){return[SpiderGL.Math.lerp(a[0],b[0],c),SpiderGL.Math.lerp(a[1],b[1],c)]},SpiderGL.Math.Vec2.ln=function(a){return[SpiderGL.Math.ln(a[0]),SpiderGL.Math.ln(a[1])]},SpiderGL.Math.Vec2.log=function(a){return[SpiderGL.Math.log(a[0]),SpiderGL.Math.log(a[1])]},SpiderGL.Math.Vec2.log2=function(a){return[SpiderGL.Math.log2(a[0]),SpiderGL.Math.log2(a[1])]};SpiderGL.Math.Vec2.log10=function(a){return[SpiderGL.Math.log10(a[0]),SpiderGL.Math.log10(a[1])]};SpiderGL.Math.Vec2.max=function(a,b){return[SpiderGL.Math.max(a[0],b[0]),SpiderGL.Math.max(a[1],b[1])]},SpiderGL.Math.Vec2.min=function(a,b){return[SpiderGL.Math.min(a[0],b[0]),SpiderGL.Math.min(a[1],b[1])]},SpiderGL.Math.Vec2.pow=function(a,b){return[SpiderGL.Math.pow(a[0],b[0]),SpiderGL.Math.pow(a[1],b[1])]},SpiderGL.Math.Vec2.radToDeg=function(a){return[SpiderGL.Math.radToDeg(a[0]),SpiderGL.Math.radToDeg(a[1])]},SpiderGL.Math.Vec2.random=function(){return[SpiderGL.Math.random(),SpiderGL.Math.random()]},SpiderGL.Math.Vec2.random01=function(){return[SpiderGL.Math.random01(),SpiderGL.Math.random01()]},SpiderGL.Math.Vec2.random11=function(){return[SpiderGL.Math.random11(),SpiderGL.Math.random11()]},SpiderGL.Math.Vec2.randomRange=function(a,b){return[SpiderGL.Math.randomRange(a[0],b[0]),SpiderGL.Math.randomRange(a[1],b[1])]},SpiderGL.Math.Vec2.round=function(a){return[SpiderGL.Math.round(a[0]),SpiderGL.Math.round(a[1])]},SpiderGL.Math.Vec2.sin=function(a){return[SpiderGL.Math.sin(a[0]),SpiderGL.Math.sin(a[1])]},SpiderGL.Math.Vec2.sqrt=function(a){return[SpiderGL.Math.sqrt(a[0]),SpiderGL.Math.sqrt(a[1])]},SpiderGL.Math.Vec2.tan=function(a){return[SpiderGL.Math.tan(a[0]),SpiderGL.Math.tan(a[1])]},SpiderGL.Math.Vec2.copy$=function(a,b){return a[0]=b[0],a[1]=b[1],a},SpiderGL.Math.Vec2.neg$=function(a){return a[0]=-a[0],a[1]=-a[1],a},SpiderGL.Math.Vec2.add$=function(a,b){return a[0]+=b[0],a[1]+=b[1],a},SpiderGL.Math.Vec2.adds$=function(a,b){return a[0]+=b,a[1]+=b,a},SpiderGL.Math.Vec2.sub$=function(a,b){return a[0]-=b[0],a[1]-=b[1],a},SpiderGL.Math.Vec2.subs$=function(a,b){return a[0]-=b,a[1]-=b,a},SpiderGL.Math.Vec2.ssub$=function(a,b){return b[0]=a-b[0],b[1]=a-b[1],b},SpiderGL.Math.Vec2.mul$=function(a,b){return a[0]*=b[0],a[1]*=b[1],a},SpiderGL.Math.Vec2.muls$=function(a,b){return a[0]*=b,a[1]*=b,a},SpiderGL.Math.Vec2.div$=function(a,b){return a[0]/=b[0],a[1]/=b[1],a},SpiderGL.Math.Vec2.divs$=function(a,b){return a[0]/=b,a[1]/=b,a},SpiderGL.Math.Vec2.sdiv$=function(a,b){return a[0]=b/a[0],a[1]=b/a[1],a},SpiderGL.Math.Vec2.perp$=function(a){var b=a[0];return a[0]=a[1],a[1]=-b,a},SpiderGL.Math.Vec2.normalize$=function(a){var b=1/SpiderGL.Math.Vec2.length(a);return SpiderGL.Math.Vec2.muls$(a,b)},SpiderGL.Math.Vec3={},SpiderGL.Math.Vec3.dup=function(a){return a.slice(0,3)},SpiderGL.Math.Vec3.scalar=function(a){return[a,a,a]},SpiderGL.Math.Vec3.zero=function(){return[0,0,0]},SpiderGL.Math.Vec3.one=function(){return[1,1,1]},SpiderGL.Math.Vec3.maxNumber=function(){return[SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER]},SpiderGL.Math.Vec3.minNumber=function(){return[SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER]},SpiderGL.Math.Vec3.to2=function(a){return[a[0],a[1]]},SpiderGL.Math.Vec3.to4=function(a,b){return[a[0],a[1],a[2],void 0!=b?b:1]},SpiderGL.Math.Vec3.neg=function(a){return[-a[0],-a[1],-a[2]]},SpiderGL.Math.Vec3.add=function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2]]},SpiderGL.Math.Vec3.adds=function(a,b){return[a[0]+b,a[1]+b,a[2]+b]},SpiderGL.Math.Vec3.sub=function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2]]},SpiderGL.Math.Vec3.subs=function(a,b){return[a[0]-b,a[1]-b,a[2]-b]},SpiderGL.Math.Vec3.ssub=function(a,b){return[a-b[0],a-b[1],a-b[2]]},SpiderGL.Math.Vec3.mul=function(a,b){return[a[0]*b[0],a[1]*b[1],a[2]*b[2]]},SpiderGL.Math.Vec3.muls=function(a,b){return[a[0]*b,a[1]*b,a[2]*b]},SpiderGL.Math.Vec3.div=function(a,b){return[a[0]/b[0],a[1]/b[1],a[2]/b[2]]},SpiderGL.Math.Vec3.divs=function(a,b){return[a[0]/b,a[1]/b,a[2]/b]},SpiderGL.Math.Vec3.sdiv=function(a,b){return[a/b[0],a/b[1],a/b[2]]},SpiderGL.Math.Vec3.rcp=function(a){return[1/a[0],1/a[1],1/a[2]]},SpiderGL.Math.Vec3.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]},SpiderGL.Math.Vec3.cross=function(a,b){return[a[1]*b[2]-a[2]*b[1],a[2]*b[0]-a[0]*b[2],a[0]*b[1]-a[1]*b[0]]},SpiderGL.Math.Vec3.sqLength=function(a){return SpiderGL.Math.Vec3.dot(a,a)},SpiderGL.Math.Vec3.length=function(a){return SpiderGL.Math.sqrt(SpiderGL.Math.Vec3.sqLength(a))},SpiderGL.Math.Vec3.normalize=function(a){var b=1/SpiderGL.Math.Vec3.length(a);return SpiderGL.Math.Vec3.muls(a,b)},SpiderGL.Math.Vec3.abs=function(a){return[SpiderGL.Math.abs(a[0]),SpiderGL.Math.abs(a[1]),SpiderGL.Math.abs(a[2])]},SpiderGL.Math.Vec3.acos=function(a){return[SpiderGL.Math.acos(a[0]),SpiderGL.Math.acos(a[1]),SpiderGL.Math.acos(a[2])]},SpiderGL.Math.Vec3.asin=function(a){return[SpiderGL.Math.asin(a[0]),SpiderGL.Math.asin(a[1]),SpiderGL.Math.asin(a[2])]},SpiderGL.Math.Vec3.atan=function(a){return[SpiderGL.Math.atan(a[0]),SpiderGL.Math.atan(a[1]),SpiderGL.Math.atan(a[2])]},SpiderGL.Math.Vec3.atan2=function(a,b){return[SpiderGL.Math.atan2(a[0],b[0]),SpiderGL.Math.atan2(a[1],b[1]),SpiderGL.Math.atan2(a[2],b[2])]},SpiderGL.Math.Vec3.ceil=function(a){return[SpiderGL.Math.ceil(a[0]),SpiderGL.Math.ceil(a[1]),SpiderGL.Math.ceil(a[2])]},SpiderGL.Math.Vec3.clamp=function(a,b,c){return[SpiderGL.Math.clamp(a[0],b[0],c[0]),SpiderGL.Math.clamp(a[1],b[1],c[1]),SpiderGL.Math.clamp(a[2],b[2],c[2])];
-},SpiderGL.Math.Vec3.cos=function(a){return[SpiderGL.Math.cos(a[0]),SpiderGL.Math.cos(a[1]),SpiderGL.Math.cos(a[2])]},SpiderGL.Math.Vec3.degToRad=function(a){return[SpiderGL.Math.degToRad(a[0]),SpiderGL.Math.degToRad(a[1]),SpiderGL.Math.degToRad(a[2])]},SpiderGL.Math.Vec3.exp=function(a){return[SpiderGL.Math.exp(a[0]),SpiderGL.Math.exp(a[1]),SpiderGL.Math.exp(a[2])]},SpiderGL.Math.Vec3.floor=function(a){return[SpiderGL.Math.floor(a[0]),SpiderGL.Math.floor(a[1]),SpiderGL.Math.floor(a[2])]},SpiderGL.Math.Vec3.lerp=function(a,b,c){return[SpiderGL.Math.lerp(a[0],b[0],c),SpiderGL.Math.lerp(a[1],b[1],c),SpiderGL.Math.lerp(a[2],b[2],c)]},SpiderGL.Math.Vec3.ln=function(a){return[SpiderGL.Math.ln(a[0]),SpiderGL.Math.ln(a[1]),SpiderGL.Math.ln(a[2])]},SpiderGL.Math.Vec3.log=function(a){return[SpiderGL.Math.log(a[0]),SpiderGL.Math.log(a[1]),SpiderGL.Math.log(a[2])]},SpiderGL.Math.Vec3.log2=function(a){return[SpiderGL.Math.log2(a[0]),SpiderGL.Math.log2(a[1]),SpiderGL.Math.log2(a[2])]},SpiderGL.Math.Vec3.log10=function(a){return[SpiderGL.Math.log10(a[0]),SpiderGL.Math.log10(a[1]),SpiderGL.Math.log10(a[2])]},SpiderGL.Math.Vec3.max=function(a,b){return[SpiderGL.Math.max(a[0],b[0]),SpiderGL.Math.max(a[1],b[1]),SpiderGL.Math.max(a[2],b[2])]},SpiderGL.Math.Vec3.min=function(a,b){return[SpiderGL.Math.min(a[0],b[0]),SpiderGL.Math.min(a[1],b[1]),SpiderGL.Math.min(a[2],b[2])]},SpiderGL.Math.Vec3.pow=function(a,b){return[SpiderGL.Math.pow(a[0],b[0]),SpiderGL.Math.pow(a[1],b[1]),SpiderGL.Math.pow(a[2],b[2])]},SpiderGL.Math.Vec3.radToDeg=function(a){return[SpiderGL.Math.radToDeg(a[0]),SpiderGL.Math.radToDeg(a[1]),SpiderGL.Math.radToDeg(a[2])]},SpiderGL.Math.Vec3.random=function(){return[SpiderGL.Math.random(),SpiderGL.Math.random(),SpiderGL.Math.random()]},SpiderGL.Math.Vec3.random01=function(){return[SpiderGL.Math.random01(),SpiderGL.Math.random01(),SpiderGL.Math.random01()]},SpiderGL.Math.Vec3.random11=function(){return[SpiderGL.Math.random11(),SpiderGL.Math.random11(),SpiderGL.Math.random11()]},SpiderGL.Math.Vec3.randomRange=function(a,b){return[SpiderGL.Math.randomRange(a[0],b[0]),SpiderGL.Math.randomRange(a[1],b[1]),SpiderGL.Math.randomRange(a[2],b[2])]},SpiderGL.Math.Vec3.round=function(a){return[SpiderGL.Math.round(a[0]),SpiderGL.Math.round(a[1]),SpiderGL.Math.round(a[2])]},SpiderGL.Math.Vec3.sin=function(a){return[SpiderGL.Math.sin(a[0]),SpiderGL.Math.sin(a[1]),SpiderGL.Math.sin(a[2])]},SpiderGL.Math.Vec3.sqrt=function(a){return[SpiderGL.Math.sqrt(a[0]),SpiderGL.Math.sqrt(a[1]),SpiderGL.Math.sqrt(a[2])]},SpiderGL.Math.Vec3.tan=function(a){return[SpiderGL.Math.tan(a[0]),SpiderGL.Math.tan(a[1]),SpiderGL.Math.tan(a[2])]},SpiderGL.Math.Vec3.copy$=function(a,b){return a[0]=b[0],a[1]=b[1],a[2]=b[2],a},SpiderGL.Math.Vec3.neg$=function(a){return a[0]=-a[0],a[1]=-a[1],a[2]=-a[2],a},SpiderGL.Math.Vec3.add$=function(a,b){return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a},SpiderGL.Math.Vec3.adds$=function(a,b){return a[0]+=b,a[1]+=b,a[2]+=b,a},SpiderGL.Math.Vec3.sub$=function(a,b){return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a},SpiderGL.Math.Vec3.subs$=function(a,b){return a[0]-=b,a[1]-=b,a[2]-=b,a},SpiderGL.Math.Vec3.ssub$=function(a,b){return b[0]=a-b[0],b[1]=a-b[1],b[2]=a-b[2],b},SpiderGL.Math.Vec3.mul$=function(a,b){return a[0]*=b[0],a[1]*=b[1],a[2]*=b[2],a},SpiderGL.Math.Vec3.muls$=function(a,b){return a[0]*=b,a[1]*=b,a[2]*=b,a},SpiderGL.Math.Vec3.div$=function(a,b){return a[0]/=b[0],a[1]/=b[1],a[2]/=b[2],a},SpiderGL.Math.Vec3.divs$=function(a,b){return a[0]/=b,a[1]/=b,a[2]/=b,a},SpiderGL.Math.Vec3.sdiv$=function(a,b){return a[0]=b/a[0],a[1]=b/a[1],a[2]=b/a[2],a},SpiderGL.Math.Vec3.normalize$=function(a){var b=1/SpiderGL.Math.Vec3.length(a);return SpiderGL.Math.Vec3.muls$(a,b)},SpiderGL.Math.Vec4={},SpiderGL.Math.Vec4.dup=function(a){return a.slice(0,4)},SpiderGL.Math.Vec4.scalar=function(a){return[a,a,a,a]},SpiderGL.Math.Vec4.zero=function(){return[0,0,0,0]},SpiderGL.Math.Vec4.one=function(){return[1,1,1,1]},SpiderGL.Math.Vec4.maxNumber=function(){return[SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER,SpiderGL.Math.MAX_NUMBER]},SpiderGL.Math.Vec4.minNumber=function(){return[SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER,SpiderGL.Math.MIN_NUMBER]},SpiderGL.Math.Vec4.to2=function(a){return[a[0],a[1]]},SpiderGL.Math.Vec4.to3=function(a){return[a[0],a[1],a[2]]},SpiderGL.Math.Vec4.neg=function(a){return[-a[0],-a[1],-a[2],-a[3]]},SpiderGL.Math.Vec4.add=function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]]},SpiderGL.Math.Vec4.adds=function(a,b){return[a[0]+b,a[1]+b,a[2]+b,a[3]+b]},SpiderGL.Math.Vec4.sub=function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]]},SpiderGL.Math.Vec4.subs=function(a,b){return[a[0]-b,a[1]-b,a[2]-b,a[3]-b]},SpiderGL.Math.Vec4.ssub=function(a,b){return[a-b[0],a-b[1],a-b[2],a-b[3]]},SpiderGL.Math.Vec4.mul=function(a,b){return[a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3]]},SpiderGL.Math.Vec4.muls=function(a,b){return[a[0]*b,a[1]*b,a[2]*b,a[3]*b]},SpiderGL.Math.Vec4.div=function(a,b){return[a[0]/b[0],a[1]/b[1],a[2]/b[2],a[3]/b[3]]},SpiderGL.Math.Vec4.divs=function(a,b){return[a[0]/b,a[1]/b,a[2]/b,a[3]/b]},SpiderGL.Math.Vec4.sdiv=function(a,b){return[a/b[0],a/b[1],a/b[2],a/b[3]]},SpiderGL.Math.Vec4.rcp=function(a){return[1/a[0],1/a[1],1/a[2],1/a[3]]},SpiderGL.Math.Vec4.dot=function(a,b){return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3]},SpiderGL.Math.Vec4.cross=function(a,b,c){var d=b[0]*c[1]-b[1]*c[0],e=b[0]*c[2]-b[2]*c[0],f=b[0]*c[3]-b[3]*c[0],g=b[1]*c[2]-b[2]*c[1],h=b[1]*c[3]-b[3]*c[1],i=b[2]*c[3]-b[3]*c[2];return[a[1]*i-a[2]*h+a[3]*g,a[0]*i+a[2]*f-a[3]*e,a[0]*h-a[1]*f+a[3]*d,a[0]*g+a[1]*e-a[2]*d]},SpiderGL.Math.Vec4.sqLength=function(a){return SpiderGL.Math.Vec4.dot(a,a)},SpiderGL.Math.Vec4.length=function(a){return SpiderGL.Math.sqrt(SpiderGL.Math.Vec4.sqLength(a))},SpiderGL.Math.Vec4.normalize=function(a){var b=1/SpiderGL.Math.Vec4.length(a);return SpiderGL.Math.Vec4.muls(a,b)},SpiderGL.Math.Vec4.project=function(a){var b=1/a[3];return[a[0]*b,a[1]*b,a[2]*b,1]},SpiderGL.Math.Vec4.abs=function(a){return[SpiderGL.Math.abs(a[0]),SpiderGL.Math.abs(a[1]),SpiderGL.Math.abs(a[2]),SpiderGL.Math.abs(a[3])]},SpiderGL.Math.Vec4.acos=function(a){return[SpiderGL.Math.acos(a[0]),SpiderGL.Math.acos(a[1]),SpiderGL.Math.acos(a[2]),SpiderGL.Math.acos(a[3])]},SpiderGL.Math.Vec4.asin=function(a){return[SpiderGL.Math.asin(a[0]),SpiderGL.Math.asin(a[1]),SpiderGL.Math.asin(a[2]),SpiderGL.Math.asin(a[3])]},SpiderGL.Math.Vec4.atan=function(a){return[SpiderGL.Math.atan(a[0]),SpiderGL.Math.atan(a[1]),SpiderGL.Math.atan(a[2]),SpiderGL.Math.atan(a[3])]},SpiderGL.Math.Vec4.atan2=function(a,b){return[SpiderGL.Math.atan2(a[0],b[0]),SpiderGL.Math.atan2(a[1],b[1]),SpiderGL.Math.atan2(a[2],b[2]),SpiderGL.Math.atan2(a[3],b[3])]},SpiderGL.Math.Vec4.ceil=function(a){return[SpiderGL.Math.ceil(a[0]),SpiderGL.Math.ceil(a[1]),SpiderGL.Math.ceil(a[2]),SpiderGL.Math.ceil(a[3])]},SpiderGL.Math.Vec4.clamp=function(a,b,c){return[SpiderGL.Math.clamp(a[0],b[0],c[0]),SpiderGL.Math.clamp(a[1],b[1],c[1]),SpiderGL.Math.clamp(a[2],b[2],c[2]),SpiderGL.Math.clamp(a[3],b[3],c[3])]},SpiderGL.Math.Vec4.cos=function(a){return[SpiderGL.Math.cos(a[0]),SpiderGL.Math.cos(a[1]),SpiderGL.Math.cos(a[2]),SpiderGL.Math.cos(a[3])]},SpiderGL.Math.Vec4.degToRad=function(a){return[SpiderGL.Math.degToRad(a[0]),SpiderGL.Math.degToRad(a[1]),SpiderGL.Math.degToRad(a[2]),SpiderGL.Math.degToRad(a[3])]},SpiderGL.Math.Vec4.exp=function(a){return[SpiderGL.Math.exp(a[0]),SpiderGL.Math.exp(a[1]),SpiderGL.Math.exp(a[2]),SpiderGL.Math.exp(a[3])]},SpiderGL.Math.Vec4.floor=function(a){return[SpiderGL.Math.floor(a[0]),SpiderGL.Math.floor(a[1]),SpiderGL.Math.floor(a[2]),SpiderGL.Math.floor(a[3])]},SpiderGL.Math.Vec4.lerp=function(a,b,c){return[SpiderGL.Math.lerp(a[0],b[0],c),SpiderGL.Math.lerp(a[1],b[1],c),SpiderGL.Math.lerp(a[2],b[2],c),SpiderGL.Math.lerp(a[3],b[3],c)]},SpiderGL.Math.Vec4.ln=function(a){return[SpiderGL.Math.ln(a[0]),SpiderGL.Math.ln(a[1]),SpiderGL.Math.ln(a[2]),SpiderGL.Math.ln(a[3])]},SpiderGL.Math.Vec4.log=function(a){return[SpiderGL.Math.log(a[0]),SpiderGL.Math.log(a[1]),SpiderGL.Math.log(a[2]),SpiderGL.Math.log(a[3])]},SpiderGL.Math.Vec4.log2=function(a){return[SpiderGL.Math.log2(a[0]),SpiderGL.Math.log2(a[1]),SpiderGL.Math.log2(a[2]),SpiderGL.Math.log2(a[3])]},SpiderGL.Math.Vec4.log10=function(a){return[SpiderGL.Math.log10(a[0]),SpiderGL.Math.log10(a[1]),SpiderGL.Math.log10(a[2]),SpiderGL.Math.log10(a[3])]},SpiderGL.Math.Vec4.max=function(a,b){return[SpiderGL.Math.max(a[0],b[0]),SpiderGL.Math.max(a[1],b[1]),SpiderGL.Math.max(a[2],b[2]),SpiderGL.Math.max(a[3],b[3])]},SpiderGL.Math.Vec4.min=function(a,b){return[SpiderGL.Math.min(a[0],b[0]),SpiderGL.Math.min(a[1],b[1]),SpiderGL.Math.min(a[2],b[2]),SpiderGL.Math.min(a[3],b[3])]},SpiderGL.Math.Vec4.pow=function(a,b){return[SpiderGL.Math.pow(a[0],b[0]),SpiderGL.Math.pow(a[1],b[1]),SpiderGL.Math.pow(a[2],b[2]),SpiderGL.Math.pow(a[3],b[3])]},SpiderGL.Math.Vec4.radToDeg=function(a){return[SpiderGL.Math.radToDeg(a[0]),SpiderGL.Math.radToDeg(a[1]),SpiderGL.Math.radToDeg(a[2]),SpiderGL.Math.radToDeg(a[3])]},SpiderGL.Math.Vec4.random=function(){return[SpiderGL.Math.random(),SpiderGL.Math.random(),SpiderGL.Math.random(),SpiderGL.Math.random()]},SpiderGL.Math.Vec4.random01=function(){return[SpiderGL.Math.random01(),SpiderGL.Math.random01(),SpiderGL.Math.random01(),SpiderGL.Math.random01()]},SpiderGL.Math.Vec4.random11=function(){return[SpiderGL.Math.random11(),SpiderGL.Math.random11(),SpiderGL.Math.random11(),SpiderGL.Math.random11()]},SpiderGL.Math.Vec4.randomRange=function(a,b){return[SpiderGL.Math.randomRange(a[0],b[0]),SpiderGL.Math.randomRange(a[1],b[1]),SpiderGL.Math.randomRange(a[2],b[2]),SpiderGL.Math.randomRange(a[3],b[3])]},SpiderGL.Math.Vec4.round=function(a){return[SpiderGL.Math.round(a[0]),SpiderGL.Math.round(a[1]),SpiderGL.Math.round(a[2]),SpiderGL.Math.round(a[3])]},SpiderGL.Math.Vec4.sin=function(a){return[SpiderGL.Math.sin(a[0]),SpiderGL.Math.sin(a[1]),SpiderGL.Math.sin(a[2]),SpiderGL.Math.sin(a[3])]},SpiderGL.Math.Vec4.sqrt=function(a){return[SpiderGL.Math.sqrt(a[0]),SpiderGL.Math.sqrt(a[1]),SpiderGL.Math.sqrt(a[2]),SpiderGL.Math.sqrt(a[3])]},SpiderGL.Math.Vec4.tan=function(a){return[SpiderGL.Math.tan(a[0]),SpiderGL.Math.tan(a[1]),SpiderGL.Math.tan(a[2]),SpiderGL.Math.tan(a[3])]},SpiderGL.Math.Vec4.copy$=function(a,b){return a[0]=b[0],a[1]=b[1],a[2]=b[2],a[3]=b[3],a},SpiderGL.Math.Vec4.neg$=function(a){return a[0]=-a[0],a[1]=-a[1],a[2]=-a[2],a[3]=-a[3],a},SpiderGL.Math.Vec4.add$=function(a,b){return a[0]+=b[0],a[1]+=b[1],a[2]+=b[2],a[3]+=b[3],a},SpiderGL.Math.Vec4.adds$=function(a,b){return a[0]+=b,a[1]+=b,a[2]+=b,a[3]+=b,a},SpiderGL.Math.Vec4.sub$=function(a,b){return a[0]-=b[0],a[1]-=b[1],a[2]-=b[2],a[3]-=b[3],a},SpiderGL.Math.Vec4.subs$=function(a,b){return a[0]-=b,a[1]-=b,a[2]-=b,a[3]-=b,a},SpiderGL.Math.Vec4.ssub$=function(a,b){return b[0]=a-b[0],b[1]=a-b[1],b[2]=a-b[2],b[3]=a-b[3],b},SpiderGL.Math.Vec4.mul$=function(a,b){return a[0]*=b[0],a[1]*=b[1],a[2]*=b[2],a[3]*=b[3],a},SpiderGL.Math.Vec4.muls$=function(a,b){return a[0]*=b,a[1]*=b,a[2]*=b,a[3]*=b,a},SpiderGL.Math.Vec4.div$=function(a,b){return a[0]/=b[0],a[1]/=b[1],a[2]/=b[2],a[3]/=b[3],a},SpiderGL.Math.Vec4.divs$=function(a,b){return a[0]/=b,a[1]/=b,a[2]/=b,a[3]/=b,a},SpiderGL.Math.Vec4.sdiv$=function(a,b){return a[0]=b/a[0],a[1]=b/a[1],a[2]=b/a[2],a[3]=b/a[3],a},SpiderGL.Math.Vec4.normalize$=function(a){var b=1/SpiderGL.Math.Vec4.length(a);return SpiderGL.Math.Vec4.muls$(a,b)},SpiderGL.Math.Mat3={},SpiderGL.Math.Mat3.dup=function(a){return a.slice(0,9)},SpiderGL.Math.Mat3.scalar=function(a){return[a,a,a,a,a,a,a,a,a]},SpiderGL.Math.Mat3.zero=function(){return[0,0,0,0,0,0,0,0,0]},SpiderGL.Math.Mat3.one=function(){return[1,1,1,1,1,1,1,1,1]},SpiderGL.Math.Mat3.diag=function(a){return[a[0],0,0,0,a[0],0,0,0,a[0]]},SpiderGL.Math.Mat3.identity=function(){return[1,0,0,0,1,0,0,0,1]},SpiderGL.Math.Mat3.to44=function(a){return[a[0],a[1],a[2],0,a[3],a[4],a[5],0,a[6],a[7],a[8],0,0,0,0,1]},SpiderGL.Math.Mat3.mul2=function(a,b,c){return c=void 0==c?0:c,[a[0]*b[0]+a[3]*b[1]+a[6]*c,a[1]*b[0]+a[4]*b[1]+a[7]*c]},SpiderGL.Math.Mat3.mul3=function(a,b){return[a[0]*b[0]+a[3]*b[1]+a[6]*b[2],a[1]*b[0]+a[4]*b[1]+a[7]*b[2],a[2]*b[0]+a[5]*b[1]+a[8]*b[2]]},SpiderGL.Math.Mat3.transpose=function(a){return[a[0],a[3],a[6],a[1],a[4],a[7],a[2],a[5],a[8]]},SpiderGL.Math.Mat4={},SpiderGL.Math.Mat4.dup=function(a){return a.slice(0,16)},SpiderGL.Math.Mat4.scalar=function(a){return[a,a,a,a,a,a,a,a,a,a,a,a,a,a,a,a]},SpiderGL.Math.Mat4.zero=function(){return[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]},SpiderGL.Math.Mat4.one=function(){return[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]},SpiderGL.Math.Mat4.diag=function(a){return[a[0],0,0,0,0,a[0],0,0,0,0,a[0],0,0,0,0,a[0]]},SpiderGL.Math.Mat4.identity=function(){return[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]},SpiderGL.Math.Mat4.to33=function(a){return[a[0],a[1],a[2],a[4],a[5],a[6],a[8],a[9],a[10]]},SpiderGL.Math.Mat4.elem=function(a,b,c){return a[b+4*c]},SpiderGL.Math.Mat4.elem$=function(a,b,c,d){a[b+4*c]=d},SpiderGL.Math.Mat4.row=function(a,b){return[a[b+0],a[b+4],a[b+8],a[b+12]]},SpiderGL.Math.Mat4.row$=function(a,b,c){a[b+0]=c[0],a[b+4]=c[1],a[b+8]=c[2],a[b+12]=c[3]},SpiderGL.Math.Mat4.col=function(a,b){var c=4*b;return[a[c+0],a[c+1],a[c+2],a[c+3]]},SpiderGL.Math.Mat4.col$=function(a,b,c){var d=4*b;a[d+0]=c[0],a[d+1]=c[1],a[d+2]=c[2],a[d+3]=c[3]},SpiderGL.Math.Mat4.isIdentity=function(a){return 1===a[0]&&0===a[1]&&0===a[2]&&0===a[3]&&0===a[4]&&1===a[5]&&0===a[6]&&0===a[7]&&0===a[8]&&0===a[9]&&1===a[10]&&0===a[11]&&0===a[12]&&0===a[13]&&0===a[14]&&1===a[15]},SpiderGL.Math.Mat4.neg=function(a){return[-a[0],-a[1],-a[2],-a[3],-a[4],-a[5],-a[6],-a[7],-a[8],-a[9],-a[10],-a[11],-a[12],-a[13],-a[14],-a[15]]},SpiderGL.Math.Mat4.add=function(a,b){return[a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3],a[4]+b[4],a[5]+b[5],a[6]+b[6],a[7]+b[7],a[8]+b[8],a[9]+b[9],a[10]+b[10],a[11]+b[11],a[12]+b[12],a[13]+b[13],a[14]+b[14],a[15]+b[15]]},SpiderGL.Math.Mat4.sub=function(a,b){return[a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3],a[4]-b[4],a[5]-b[5],a[6]-b[6],a[7]-b[7],a[8]-b[8],a[9]-b[9],a[10]-b[10],a[11]-b[11],a[12]-b[12],a[13]-b[13],a[14]-b[14],a[15]-b[15]]},SpiderGL.Math.Mat4.mul=function(a,b){var c=a[0],d=a[1],e=a[2],f=a[3],g=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],m=a[10],n=a[11],o=a[12],p=a[13],q=a[14],r=a[15],s=b[0],t=b[1],u=b[2],v=b[3],w=b[4],x=b[5],y=b[6],z=b[7],A=b[8],B=b[9],C=b[10],D=b[11],E=b[12],F=b[13],G=b[14],H=b[15];return[c*s+g*t+k*u+o*v,d*s+h*t+l*u+p*v,e*s+i*t+m*u+q*v,f*s+j*t+n*u+r*v,c*w+g*x+k*y+o*z,d*w+h*x+l*y+p*z,e*w+i*x+m*y+q*z,f*w+j*x+n*y+r*z,c*A+g*B+k*C+o*D,d*A+h*B+l*C+p*D,e*A+i*B+m*C+q*D,f*A+j*B+n*C+r*D,c*E+g*F+k*G+o*H,d*E+h*F+l*G+p*H,e*E+i*F+m*G+q*H,f*E+j*F+n*G+r*H]},SpiderGL.Math.Mat4.muls=function(a,b){return[a[0]*b,a[1]*b,a[2]*b,a[3]*b,a[4]*b,a[5]*b,a[6]*b,a[7]*b,a[8]*b,a[9]*b,a[10]*b,a[11]*b,a[12]*b,a[13]*b,a[14]*b,a[15]*b]},SpiderGL.Math.Mat4.mul3=function(a,b,c){return c=void 0==c?1:c,[a[0]*b[0]+a[4]*b[1]+a[8]*b[2]+a[12]*c,a[1]*b[0]+a[5]*b[1]+a[9]*b[2]+a[13]*c,a[2]*b[0]+a[6]*b[1]+a[10]*b[2]+a[14]*c]},SpiderGL.Math.Mat4.mul4=function(a,b){return[a[0]*b[0]+a[4]*b[1]+a[8]*b[2]+a[12]*b[3],a[1]*b[0]+a[5]*b[1]+a[9]*b[2]+a[13]*b[3],a[2]*b[0]+a[6]*b[1]+a[10]*b[2]+a[14]*b[3],a[3]*b[0]+a[7]*b[1]+a[11]*b[2]+a[15]*b[3]]},SpiderGL.Math.Mat4.rcp=function(a){return[1/a[0],1/a[1],1/a[2],1/a[3],1/a[4],1/a[5],1/a[6],1/a[7],1/a[8],1/a[9],1/a[10],1/a[11],1/a[12],1/a[13],1/a[14],1/a[15]]},SpiderGL.Math.Mat4.compMul=function(a,b){return[a[0]*b[0],a[1]*b[1],a[2]*b[2],a[3]*b[3],a[4]*b[4],a[5]*b[5],a[6]*b[6],a[7]*b[7],a[8]*b[8],a[9]*b[9],a[10]*b[10],a[11]*b[11],a[12]*b[12],a[13]*b[13],a[14]*b[14],a[15]*b[15]]},SpiderGL.Math.Mat4.compDiv=function(a,b){return[a[0]/b[0],a[1]/b[1],a[2]/b[2],a[3]/b[3],a[4]/b[4],a[5]/b[5],a[6]/b[6],a[7]/b[7],a[8]/b[8],a[9]/b[9],a[10]/b[10],a[11]/b[11],a[12]/b[12],a[13]/b[13],a[14]/b[14],a[15]/b[15]]},SpiderGL.Math.Mat4.transpose=function(a){return[a[0],a[4],a[8],a[12],a[1],a[5],a[9],a[13],a[2],a[6],a[10],a[14],a[3],a[7],a[11],a[15]]},SpiderGL.Math.Mat4.determinant=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],m=a[11],n=a[12],o=a[13],p=a[14],q=a[15];return n*k*h*e-j*o*h*e-n*g*l*e+f*o*l*e+j*g*p*e-f*k*p*e-n*k*d*i+j*o*d*i+n*c*l*i-b*o*l*i-j*c*p*i+b*k*p*i+n*g*d*m-f*o*d*m-n*c*h*m+b*o*h*m+f*c*p*m-b*g*p*m-j*g*d*q+f*k*d*q+j*c*h*q-b*k*h*q-f*c*l*q+b*g*l*q},SpiderGL.Math.Mat4.inverse=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],m=a[11],n=a[12],o=a[13],p=a[14],q=a[15],r=1/(n*k*h*e-j*o*h*e-n*g*l*e+f*o*l*e+j*g*p*e-f*k*p*e-n*k*d*i+j*o*d*i+n*c*l*i-b*o*l*i-j*c*p*i+b*k*p*i+n*g*d*m-f*o*d*m-n*c*h*m+b*o*h*m+f*c*p*m-b*g*p*m-j*g*d*q+f*k*d*q+j*c*h*q-b*k*h*q-f*c*l*q+b*g*l*q);return[r*(k*p*i-o*l*i+o*h*m-g*p*m-k*h*q+g*l*q),r*(o*l*e-k*p*e-o*d*m+c*p*m+k*d*q-c*l*q),r*(g*p*e-o*h*e+o*d*i-c*p*i-g*d*q+c*h*q),r*(k*h*e-g*l*e-k*d*i+c*l*i+g*d*m-c*h*m),r*(n*l*i-j*p*i-n*h*m+f*p*m+j*h*q-f*l*q),r*(j*p*e-n*l*e+n*d*m-b*p*m-j*d*q+b*l*q),r*(n*h*e-f*p*e-n*d*i+b*p*i+f*d*q-b*h*q),r*(f*l*e-j*h*e+j*d*i-b*l*i-f*d*m+b*h*m),r*(j*o*i-n*k*i+n*g*m-f*o*m-j*g*q+f*k*q),r*(n*k*e-j*o*e-n*c*m+b*o*m+j*c*q-b*k*q),r*(f*o*e-n*g*e+n*c*i-b*o*i-f*c*q+b*g*q),r*(j*g*e-f*k*e-j*c*i+b*k*i+f*c*m-b*g*m),r*(n*k*h-j*o*h-n*g*l+f*o*l+j*g*p-f*k*p),r*(j*o*d-n*k*d+n*c*l-b*o*l-j*c*p+b*k*p),r*(n*g*d-f*o*d-n*c*h+b*o*h+f*c*p-b*g*p),r*(f*k*d-j*g*d+j*c*h-b*k*h-f*c*l+b*g*l)]};SpiderGL.Math.Mat4.inverseTranspose33=function(a){var b=a[0],c=a[1],d=a[2],e=a[4],f=a[5],g=a[6],h=a[8],i=a[9],j=a[10],k=1/(b*(j*f-g*i)-c*(j*e-g*h)+d*(i*e-f*h));return[k*(j*f-g*i),k*(g*h-j*e),k*(i*e-f*h),k*(d*i-j*c),k*(j*b-d*h),k*(c*h-i*b),k*(g*c-d*f),k*(d*e-g*b),k*(f*b-c*e)]};SpiderGL.Math.Mat4.trace=function(a){return a[0]+a[5]+a[10]+a[15]},SpiderGL.Math.Mat4.translation=function(a){return[1,0,0,0,0,1,0,0,0,0,1,0,a[0],a[1],a[2],1]},SpiderGL.Math.Mat4.rotationAngleAxis=function(a,b){var j,k,l,m,n,o,p,q,r,c=SpiderGL.Math.Vec3.normalize(b),d=SpiderGL.Math.sin(a),e=SpiderGL.Math.cos(a),f=1-e,g=c[0],h=c[1],i=c[2];return j=g*g,k=h*h,l=i*i,m=g*h,n=h*i,o=i*g,p=g*d,q=h*d,r=i*d,[f*j+e,f*m+r,f*o-q,0,f*m-r,f*k+e,f*n+p,0,f*o+q,f*n-p,f*l+e,0,0,0,0,1]},SpiderGL.Math.Mat4.scaling=function(a){return[a[0],0,0,0,0,a[1],0,0,0,0,a[2],0,0,0,0,1]},SpiderGL.Math.Mat4.lookAt=function(a,b,c){var d=SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.sub(b,a)),e=SpiderGL.Math.Vec3.normalize(c),f=SpiderGL.Math.Vec3.normalize(SpiderGL.Math.Vec3.cross(d,e));e=SpiderGL.Math.Vec3.cross(f,d);var g=[f[0],e[0],-d[0],0,f[1],e[1],-d[1],0,f[2],e[2],-d[2],0,0,0,0,1];return SpiderGL.Math.Mat4.translate$(g,SpiderGL.Math.Vec3.neg(a))},SpiderGL.Math.Mat4.ortho=function(a,b){var c=SpiderGL.Math.Vec3.add(b,a),d=SpiderGL.Math.Vec3.sub(b,a);return[2/d[0],0,0,0,0,2/d[1],0,0,0,0,-2/d[2],0,-c[0]/d[0],-c[1]/d[1],-c[2]/d[2],1]},SpiderGL.Math.Mat4.frustum=function(a,b){var c=SpiderGL.Math.Vec3.add(b,a),d=SpiderGL.Math.Vec3.sub(b,a),e=2*a[2];return[e/d[0],0,0,0,0,e/d[1],0,0,c[0]/d[0],c[1]/d[1],-c[2]/d[2],-1,0,0,-e*b[2]/d[2],0]},SpiderGL.Math.Mat4.perspective=function(a,b,c,d){var e=c*SpiderGL.Math.tan(a/2),f=e*b;return SpiderGL.Math.Mat4.frustum([-f,-e,c],[f,e,d])},SpiderGL.Math.Mat4.copy$=function(a,b){for(var c=0;c<16;++c)a[c]=b[c];return a},SpiderGL.Math.Mat4.identity$=function(a){return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},SpiderGL.Math.Mat4.neg$=function(a){for(var b=0;b<16;++b)a[b]=-a[b];return a},SpiderGL.Math.Mat4.add$=function(a,b){for(var c=0;c<16;++c)a[c]+=b[c];return a},SpiderGL.Math.Mat4.sub$=function(a,b){for(var c=0;c<16;++c)a[c]-=b[c];return a},SpiderGL.Math.Mat4.mul$=function(a,b){var c=a[0],d=a[1],e=a[2],f=a[3],g=a[4],h=a[5],i=a[6],j=a[7],k=a[8],l=a[9],m=a[10],n=a[11],o=a[12],p=a[13],q=a[14],r=a[15],s=b[0],t=b[1],u=b[2],v=b[3],w=b[4],x=b[5],y=b[6],z=b[7],A=b[8],B=b[9],C=b[10],D=b[11],E=b[12],F=b[13],G=b[14],H=b[15];return a[0]=c*s+g*t+k*u+o*v,a[1]=d*s+h*t+l*u+p*v,a[2]=e*s+i*t+m*u+q*v,a[3]=f*s+j*t+n*u+r*v,a[4]=c*w+g*x+k*y+o*z,a[5]=d*w+h*x+l*y+p*z,a[6]=e*w+i*x+m*y+q*z,a[7]=f*w+j*x+n*y+r*z,a[8]=c*A+g*B+k*C+o*D,a[9]=d*A+h*B+l*C+p*D,a[10]=e*A+i*B+m*C+q*D,a[11]=f*A+j*B+n*C+r*D,a[12]=c*E+g*F+k*G+o*H,a[13]=d*E+h*F+l*G+p*H,a[14]=e*E+i*F+m*G+q*H,a[15]=f*E+j*F+n*G+r*H,a},SpiderGL.Math.Mat4.muls$=function(a,b){for(var c=0;c<16;++c)a[c]*=b;return a},SpiderGL.Math.Mat4.compMul$=function(a,b){for(var c=0;c<16;++c)a[c]*=b[c];return a},SpiderGL.Math.Mat4.compDiv$=function(a,b){for(var c=0;c<16;++c)a[c]/=b[c];return a},SpiderGL.Math.Mat4.transpose$=function(a){var b;return b=a[1],a[1]=a[4],a[4]=b,b=a[2],a[2]=a[8],a[8]=b,b=a[3],a[3]=a[12],a[12]=b,b=a[6],a[6]=a[9],a[9]=b,b=a[7],a[7]=a[13],a[13]=b,b=a[11],a[11]=a[14],a[14]=b,a},SpiderGL.Math.Mat4.invert$=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],j=a[8],k=a[9],l=a[10],m=a[11],n=a[12],o=a[13],p=a[14],q=a[15],r=1/(n*k*h*e-j*o*h*e-n*g*l*e+f*o*l*e+j*g*p*e-f*k*p*e-n*k*d*i+j*o*d*i+n*c*l*i-b*o*l*i-j*c*p*i+b*k*p*i+n*g*d*m-f*o*d*m-n*c*h*m+b*o*h*m+f*c*p*m-b*g*p*m-j*g*d*q+f*k*d*q+j*c*h*q-b*k*h*q-f*c*l*q+b*g*l*q);return a[0]=r*(k*p*i-o*l*i+o*h*m-g*p*m-k*h*q+g*l*q),a[1]=r*(o*l*e-k*p*e-o*d*m+c*p*m+k*d*q-c*l*q),a[2]=r*(g*p*e-o*h*e+o*d*i-c*p*i-g*d*q+c*h*q),a[3]=r*(k*h*e-g*l*e-k*d*i+c*l*i+g*d*m-c*h*m),a[4]=r*(n*l*i-j*p*i-n*h*m+f*p*m+j*h*q-f*l*q),a[5]=r*(j*p*e-n*l*e+n*d*m-b*p*m-j*d*q+b*l*q),a[6]=r*(n*h*e-f*p*e-n*d*i+b*p*i+f*d*q-b*h*q),a[7]=r*(f*l*e-j*h*e+j*d*i-b*l*i-f*d*m+b*h*m),a[8]=r*(j*o*i-n*k*i+n*g*m-f*o*m-j*g*q+f*k*q),a[9]=r*(n*k*e-j*o*e-n*c*m+b*o*m+j*c*q-b*k*q),a[10]=r*(f*o*e-n*g*e+n*c*i-b*o*i-f*c*q+b*g*q),a[11]=r*(j*g*e-f*k*e-j*c*i+b*k*i+f*c*m-b*g*m),a[12]=r*(n*k*h-j*o*h-n*g*l+f*o*l+j*g*p-f*k*p),a[13]=r*(j*o*d-n*k*d+n*c*l-b*o*l-j*c*p+b*k*p),a[14]=r*(n*g*d-f*o*d-n*c*h+b*o*h+f*c*p-b*g*p),a[15]=r*(f*k*d-j*g*d+j*c*h-b*k*h-f*c*l+b*g*l),a},SpiderGL.Math.Mat4.translate$=function(a,b){var c=b[0],d=b[1],e=b[2];return a[12]=a[0]*c+a[4]*d+a[8]*e+a[12],a[13]=a[1]*c+a[5]*d+a[9]*e+a[13],a[14]=a[2]*c+a[6]*d+a[10]*e+a[14],a[15]=a[3]*c+a[7]*d+a[11]*e+a[15],a},SpiderGL.Math.Mat4.rotateAngleAxis$=function(a,b,c){var d=SpiderGL.Math.Mat4.rotationAngleAxis(b,c);return SpiderGL.Math.Mat4.mul$(a,d)},SpiderGL.Math.Mat4.scale$=function(a,b){var c=b[0],d=b[1],e=b[2];return a[0]*=c,a[1]*=c,a[2]*=c,a[3]*=c,a[4]*=d,a[5]*=d,a[6]*=d,a[7]*=d,a[8]*=e,a[9]*=e,a[10]*=e,a[11]*=e,a},SpiderGL.Math.Quat={},SpiderGL.Math.Quat.dup=function(a){return a.slice(0,4)},SpiderGL.Math.Quat.identity=function(){return[0,0,0,1]},SpiderGL.Math.Quat.inverse=function(a){return[-a[0],-a[1],-a[2],a[3]]},SpiderGL.Math.Quat.mul=function(a,b){var c=a[0],d=a[1],e=a[2],f=a[3],g=b[0],h=b[1],i=b[2],j=b[3];return[c*j+f*g+e*h-d*i,d*j+f*h+c*i-e*g,e*j+f*i+d*g-c*h,f*j-c*g-d*h-e*i]},SpiderGL.Math.Quat.muls=function(a,b){return[a[0]*b,a[1]*b,a[2]*b,a[3]*b]},SpiderGL.Math.Quat.normalize=function(a){var b=1/SpiderGL.Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]);return SpiderGL.Math.Quat.muls(a,b)},SpiderGL.Math.Quat.from33=function(a){var l,b=a[0],c=a[1],d=a[2],e=a[3],f=a[4],g=a[5],h=a[6],i=a[7],j=a[8],k=b+f+j;return k>0?(k+=1,l=.5/SpiderGL.Math.sqrt(k),[(g-i)*l,(h-d)*l,(c-e)*l,k*l]):b>f&&b>j?(k=b-f-j+1,l=.5/SpiderGL.Math.sqrt(k),[k*l,(c+e)*l,(h+d)*l,(g-i)*l]):f>j?(k=-b+f-j+1,l=.5/SpiderGL.Math.sqrt(k),[(c+e)*l,k*l,(g+i)*l,(h-d)*l]):(k=-b-f+j+1,l=.5/SpiderGL.Math.sqrt(k),[(h+d)*l,(g+i)*l,k*l,(c-e)*l])},SpiderGL.Math.Quat.to33=function(a){var b=a[0],c=a[1],d=a[2],e=a[3],f=b*b,g=b*c,h=b*d,i=b*e,j=c*c,k=c*d,l=c*e,m=d*d,n=d*e;return[1-2*(j+m),2*(g+n),2*(h-l),2*(g-n),1-2*(f+m),2*(k+i),2*(h+l),2*(k-i),1-2*(f+j)]},SpiderGL.Math.Quat.from44=function(a){return SpiderGL.Math.Quat.from33(SpiderGL.Math.Mat4.to33(a))},SpiderGL.Math.Quat.to44=function(a){return SpiderGL.Math.Mat3.to44(SpiderGL.Math.Quat.to33(a))},SpiderGL.Math.Quat.fromAngleAxis=function(a,b){return[0,0,0,1]},SpiderGL.Math.Quat.toAngleAxis=function(a){return[0,0,0,1]},SpiderGL.Math.Quat.fromEulerAngles=function(a,b,c){return[0,0,0,1]},SpiderGL.Math.Quat.toEulerAngles=function(a){return[0,0,0,1]},SpiderGL.Math.Quat.copy$=function(a,b){return a[0]=b[0],a[1]=b[1],a[2]=b[2],a[3]=b[3],a},SpiderGL.Math.Quat.identity$=function(a){return a[0]=0,a[1]=0,a[2]=0,a[3]=1,a},SpiderGL.Math.Quat.invert$=function(a){return a[0]=-a[0],a[1]=-a[1],a[2]=-a[2],a},SpiderGL.Math.Quat.mul$=function(a){var b=p[0],c=p[1],d=p[2],e=p[3],f=a[0],g=a[1],h=a[2],i=a[3];return a[0]=b*i+e*f+d*g-c*h,a[1]=c*i+e*g+b*h-d*f,a[2]=d*i+e*h+c*f-b*g,a[3]=e*i-b*f-c*g-d*h,a},SpiderGL.Math.Quat.muls$=function(a,b){return a[0]*=b,a[1]*=b,a[2]*=b,a[3]*=b,a},SpiderGL.Math.Quat.normalize$=function(a){var b=1/SpiderGL.Math.sqrt(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3]);return SpiderGL.Math.Quat.muls$(a,b)},SpiderGL.Math.project=function(a,b,c,d){var e=SpiderGL.Math.Vec3,f=SpiderGL.Math.Mat4,g=f.mul4(b,a),h=1/g[3];return g[3]=h,e.muls$(g,h/2),e.adds$(g,.5),e.mul$(g,[c[2],c[3],d[1]-d[0]]),e.add$(g,[c[0],c[1],d[0]]),g},SpiderGL.Math.unproject=function(a,b,c,d){var e=SpiderGL.Math.Vec3,f=SpiderGL.Math.Mat4,g=e.to4(a,1);e.sub$(g,[c[0],c[1],d[0]]),e.div$(g,[c[2],c[3],d[1]-d[0]]),e.muls$(g,2),e.subs$(g,1),g=f.mul4(b,g);var h=1/g[3];return g[3]=h,e.muls$(g,h),g},SpiderGL.Space={},SpiderGL.Space.MatrixStack=function(a){SpiderGL.Core.ObjectBase.call(this),this._onChange=null,this.reset(),this._onChange=a},SpiderGL.Space.MatrixStack.prototype={_invalidate:function(){this._i=null,this._t=null,this._it=null,this._onChange&&this._onChange(this)},reset:function(){var a=SpiderGL.Math.Mat4.identity();this._s=[a],this._l=1,this._m=a,this._i=a,this._t=a,this._it=a,this._onChange&&this._onChange(this)},get onChange(){return this._onChange},set onChange(a){this._onChange=a},get size(){return this._l},get matrix$(){return this._m},get matrix(){return SpiderGL.Math.Mat4.dup(this.matrix$)},get top$(){return this.matrix$},get top(){return this.matrix},get inverse$(){return this._i||(this._i=SpiderGL.Math.Mat4.inverse(this._m))},get inverse(){return SpiderGL.Math.Mat4.dup(this.inverse$)},get transpose$(){return this._t||(this._t=SpiderGL.Math.Mat4.transpose(this._m))},get transpose(){return SpiderGL.Math.Mat4.dup(this.transpose$)},get inverseTranspose$(){return this._it||(this._it=SpiderGL.Math.Mat4.transpose(this.inverse$))},get inverseTranspose(){return SpiderGL.Math.Mat4.dup(this.inverseTranspose$)},push:function(){var a=SpiderGL.Math.Mat4.dup(this._m);this._s.push(a),this._l++,this._m=a},pop:function(){this._l<=1||(this._s.pop(),this._l--,this._m=this._s[this._l-1],this._invalidate())},load:function(a){a=SpiderGL.Math.Mat4.dup(a),this._s[this._l-1]=a,this._m=a,this._invalidate()},loadIdentity:function(){var a=SpiderGL.Math.Mat4.identity$(this._m);this._i=a,this._t=a,this._it=a},multiply:function(a){SpiderGL.Math.Mat4.mul$(this._m,a),this._invalidate()},ortho:function(a,b){SpiderGL.Math.Mat4.mul$(this._m,SpiderGL.Math.Mat4.ortho(a,b)),this._invalidate()},frustum:function(a,b){SpiderGL.Math.Mat4.mul$(this._m,SpiderGL.Math.Mat4.frustum(a,b)),this._invalidate()},perspective:function(a,b,c,d){SpiderGL.Math.Mat4.mul$(this._m,SpiderGL.Math.Mat4.perspective(a,b,c,d)),this._invalidate()},lookAt:function(a,b,c){SpiderGL.Math.Mat4.mul$(this._m,SpiderGL.Math.Mat4.lookAt(a,b,c)),this._invalidate()},translate:function(a){SpiderGL.Math.Mat4.translate$(this._m,a),this._invalidate()},rotate:function(a,b){SpiderGL.Math.Mat4.rotateAngleAxis$(this._m,a,b),this._invalidate()},scale:function(a){SpiderGL.Math.Mat4.scale$(this._m,a),this._invalidate()}},SpiderGL.Type.extend(SpiderGL.Space.MatrixStack,SpiderGL.Core.ObjectBase),SpiderGL.Space.ViewportStack=function(a){SpiderGL.Core.ObjectBase.call(this),this._onChange=null,this.reset(),this._onChange=a},SpiderGL.Space.ViewportStack.prototype={_invalidate:function(){this._onChange&&this._onChange(this)},reset:function(){var a=[0,0,1,1];this._s=[a],this._l=1,this._r=a,this._onChange&&this._onChange(this)},get onChange(){return this._onChange},set onChange(a){this._onChange=a},get size(){return this._l},get rect$(){return this._r},get rect(){return this.rect$.slice(0,4)},get top$(){return this.rect$},get top(){return this.rect},push:function(){var a=this._r.slice(0,4);this._s.push(a),this._l++,this._r=a},pop:function(){this._l<=1||(this._s.pop(),this._l--,this._r=this._s[this._l-1],this._invalidate())},load:function(a){a=a.slice(0,4),this._s[this._l-1]=a,this._r=a,this._invalidate()},loadIdentity:function(){var a=[0,0,1,1];this._r=a},inner:function(a){this._r[0]+=a[0],this._r[1]+=a[1],this._r[2]=a[2],this._r[3]=a[3],this._invalidate()}},SpiderGL.Type.extend(SpiderGL.Space.ViewportStack,SpiderGL.Core.ObjectBase),SpiderGL.Space.DepthRangeStack=function(a){SpiderGL.Core.ObjectBase.call(this),this._onChange=null,this.reset(),this._onChange=a},SpiderGL.Space.DepthRangeStack.prototype={_invalidate:function(){this._onChange&&this._onChange(this)},reset:function(){var a=[0,1];this._s=[a],this._l=1,this._r=a,this._onChange&&this._onChange(this)},get onChange(){return this._onChange},set onChange(a){this._onChange=a},get size(){return this._l},get range$(){return this._r},get range(){return this.range$.slice(0,2)},get top$(){return this.range$},get top(){return this.range},push:function(){var a=this._r.slice(0,2);this._s.push(a),this._l++,this._r=a},pop:function(){this._l<=1||(this._s.pop(),this._l--,this._r=this._s[this._l-1],this._invalidate())},load:function(a){a=a.slice(0,2),this._s[this._l-1]=a,this._r=a,this._invalidate()},loadIdentity:function(){var a=[0,1];this._r=a},inner:function(a){this._r[0]+=a[0],this._r[1]=a[1],this._invalidate()}},SpiderGL.Type.extend(SpiderGL.Space.DepthRangeStack,SpiderGL.Core.ObjectBase),SpiderGL.Space.TransformationStack=function(){SpiderGL.Core.ObjectBase.call(this);var a=this;this._mv={},this._vp={},this._mvp={},this._n={},this._c={},this._m=new SpiderGL.Space.MatrixStack(function(){a._mv={},a._mvp={},a._n={},a._c={}}),this._v=new SpiderGL.Space.MatrixStack(function(){a._mv={},a._vp={},a._mvp={},a._n={},a._c={}}),this._p=new SpiderGL.Space.MatrixStack(function(){a._vp={},a._mvp={}}),this._viewport=new SpiderGL.Space.ViewportStack(function(){}),this._depth=new SpiderGL.Space.DepthRangeStack(function(){})},SpiderGL.Space.TransformationStack.prototype={reset:function(){this._m.reset(),this._v.reset(),this._p.reset()},get viewport(){return this._viewport},get viewportRect$(){return this._viewport.rect$},get viewportRect(){return this._viewport.rect},get depth(){return this._depth},get depthRange$(){return this._depth.range$},get depthRange(){return this._depth.range},get model(){return this._m},get modelMatrix$(){return this._m.matrix$},get modelMatrix(){return this._m.matrix},get modelMatrixInverse$(){return this._m.inverse$},get modelMatrixInverse(){return this._m.inverse},get modelMatrixTranspose$(){return this._m.transpose$},get modelMatrixTranspose(){return this._m.transpose},get modelMatrixInverseTranspose$(){return this._m.inverseTranspose$},get modelMatrixInverseTranspose(){return this._m.inverseTranspose},get view(){return this._v},get viewMatrix$(){return this._v.matrix$},get viewMatrix(){return this._v.matrix},get viewMatrixInverse$(){return this._v.inverse$},get viewMatrixInverse(){return this._v.inverse},get viewMatrixTranspose$(){return this._v.transpose$},get viewMatrixTranspose(){return this._v.transpose},get viewMatrixInverseTranspose$(){return this._v.inverseTranspose$},get viewMatrixInverseTranspose(){return this._v.inverseTranspose},get projection(){return this._p},get projectionMatrix$(){return this._p.matrix$},get projectionMatrix(){return this._p.matrix},get projectionMatrixInverse$(){return this._p.inverse$},get projectionMatrixInverse(){return this._p.inverse},get projectionMatrixTranspose$(){return this._p.transpose$},get projectionMatrixTranspose(){return this._p.transpose},get projectionMatrixInverseTranspose$(){return this._p.inverseTranspose$},get projectionMatrixInverseTranspose(){return this._p.inverseTranspose},get modelViewMatrix$(){return this._mv.m||(this._mv.m=SpiderGL.Math.Mat4.mul(this.viewMatrix$,this.modelMatrix$))},get modelViewMatrix(){return SpiderGL.Math.Mat4.dup(this.modelViewMatrix$);
-},get modelViewMatrixInverse$(){return this._mv.i||(this._mv.i=SpiderGL.Math.Mat4.mul(this.modelMatrixInverse$,this.viewMatrixInverse$))},get modelViewMatrixInverse(){return SpiderGL.Math.Mat4.dup(this.modelViewMatrixInverse$)},get modelViewMatrixTranspose$(){return this._mv.t||(this._mv.t=SpiderGL.Math.Mat4.transpose(this.modelViewMatrix$))},get modelViewMatrixTranspose(){return SpiderGL.Math.Mat4.dup(this.modelViewMatrixTranspose$)},get modelViewMatrixInverseTranspose$(){return this._mv.it||(this._mv.it=SpiderGL.Math.Mat4.transpose(this.modelViewMatrixInverse$))},get modelViewMatrixInverseTranspose(){return SpiderGL.Math.Mat4.dup(this.modelViewMatrixInverseTranspose$)},get viewProjectionMatrix$(){return this._vp.m||(this._vp.m=SpiderGL.Math.Mat4.mul(this.projectionMatrix$,this.viewMatrix$))},get viewProjectionMatrix(){return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrix$)},get viewProjectionMatrixInverse$(){return this._vp.i||(this._vp.i=SpiderGL.Math.Mat4.mul(this.viewMatrixInverse$,this.projectionMatrixInverse$))},get viewProjectionMatrixInverse(){return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixInverse$)},get viewProjectionMatrixTranspose$(){return this._vp.t||(this._vp.t=SpiderGL.Math.Mat4.transpose(this.viewProjectionMatrix$))},get viewProjectionMatrixTranspose(){return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixTranspose$)},get viewProjectionMatrixInverseTranspose$(){return this._vp.it||(this._vp.it=SpiderGL.Math.Mat4.transpose(this.viewProjectionMatrixInverse$))},get viewProjectionMatrixInverseTranspose(){return SpiderGL.Math.Mat4.dup(this.viewProjectionMatrixInverseTranspose$)},get modelViewProjectionMatrix$(){return this._mvp.m||(this._mvp.m=SpiderGL.Math.Mat4.mul(this.viewProjectionMatrix$,this.modelMatrix$))},get modelViewProjectionMatrix(){return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrix$)},get modelViewProjectionMatrixInverse$(){return this._mvp.i||(this._mvp.i=SpiderGL.Math.Mat4.inverse(this.modelViewProjectionMatrix$))},get modelViewProjectionMatrixInverse(){return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixInverse$)},get modelViewProjectionMatrixTranspose$(){return this._mvp.t||(this._mvp.t=SpiderGL.Math.Mat4.transpose(this.modelViewProjectionMatrix$))},get modelViewProjectionMatrixTranspose(){return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixTranspose$)},get modelViewProjectionMatrixInverseTranspose$(){return this._mvp.it||(this._mvp.it=SpiderGL.Math.Mat4.transpose(this.modelViewProjectionMatrixInverse$))},get modelViewProjectionMatrixInverseTranspose(){return SpiderGL.Math.Mat4.dup(this.modelViewProjectionMatrixInverseTranspose$)},get worldSpaceNormalMatrix$(){return this._n.m||(this._n.m=SpiderGL.Math.Mat4.inverseTranspose33(this.modelMatrix$))},get worldSpaceNormalMatrix(){return SpiderGL.Math.Mat4.dup(this.worldSpaceNormalMatrix$)},get viewSpaceNormalMatrix$(){return this._n.v||(this._n.v=SpiderGL.Math.Mat4.inverseTranspose33(this.modelViewMatrix$))},get viewSpaceNormalMatrix(){return SpiderGL.Math.Mat4.dup(this.viewSpaceNormalMatrix$)},get modelSpaceViewerPosition$(){return this._c.mp||(this._c.mp=SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.col(this.modelViewMatrixInverse$,3)))},get modelSpaceViewerPosition(){return SpiderGL.Math.Vec3.dup(this.modelSpaceViewerPosition$)},get worldSpaceViewerPosition$(){return this._c.wp||(this._c.wp=SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.col(this.viewMatrixInverse$,3)))},get worldSpaceViewerPosition(){return SpiderGL.Math.Vec3.dup(this.worldSpaceViewerPosition$)},get modelSpaceViewDirection$(){return this._c.md||(this._c.md=SpiderGL.Math.Vec3.normalize$(SpiderGL.Math.Vec3.neg$(SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.row(this.modelViewMatrixInverse$,2)))))},get modelSpaceViewDirection(){return SpiderGL.Math.Vec3.dup(this.modelSpaceViewDirection$)},get worldSpaceViewDirection$(){return this._c.wd||(this._c.wd=SpiderGL.Math.Vec3.normalize$(SpiderGL.Math.Vec3.neg$(SpiderGL.Math.Vec4.to3(SpiderGL.Math.Mat4.row(this.viewMatrixInverse$,2)))))},get worldSpaceViewDirection(){return SpiderGL.Math.Vec3.dup(this.worldSpaceViewDirection$)},project:function(a){return SpiderGL.Math.project(a,this.modelViewProjectionMatrix$,this.viewportRect$,this.depthRange$)},unproject:function(a){return SpiderGL.Math.unproject(a,this.modelViewProjectionMatrixInverse$,this.viewportRect$,this.depthRange$)}},SpiderGL.Type.extend(SpiderGL.Space.TransformationStack,SpiderGL.Core.ObjectBase),SpiderGL.WebGL={},SpiderGL.WebGL.Context={},SpiderGL.WebGL.Context.WEBGL_STRING="experimental-webgl",SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y=!0,SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA=!1,SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.Context.get=function(a,b){var c=a;if(SpiderGL.Type.isString(c)&&(c=SpiderGL.DOM.getElementById(c)),!SpiderGL.Type.instanceOf(c,HTMLCanvasElement))return null;var d=c.getContext(SpiderGL.WebGL.Context.WEBGL_STRING,b);return d},SpiderGL.WebGL.Context._prepareContex=function(a){if(a){var b=a._spidergl;if(!b){b={},a._spidergl=b,b.TAG=0,b.gl=a;var c={};b.glFunctions=c;for(var d in a){var e=a[e];"function"==typeof e&&(c[d]=e)}}}},SpiderGL.WebGL.Context._addExtension=function(a,b,c,d){if(a){var e=a.getExtension;a.getExtension=function(f){if(f==b){var g=this._spidergl;if(!g)return null;var h=g[c];if(!h){h={},h.TAG=0;var i={};h._ext=i,i[c]=h,i.sgl=g,i.gl=a;var j={};if(i.glFunctions=j,!d(a,h))return null;g[c]=h}return h}return e.call(this,f)}}},SpiderGL.WebGL.Context._setup_SGL_current_binding=function(a,b){if(!a)return!1;if(!b)return!1;if(!a._spidergl)return!1;if(a._spidergl.cb)return!1;var c=b,d=c._ext,e=d.glFunctions;d.currentBuffer={},d.currentBuffer[a.ARRAY_BUFFER]=a.getParameter(a.ARRAY_BUFFER_BINDING),d.currentBuffer[a.ELEMENT_ARRAY_BUFFER]=a.getParameter(a.ELEMENT_ARRAY_BUFFER_BINDING),d.bufferStack={},d.bufferStack[a.ARRAY_BUFFER]=[],d.bufferStack[a.ELEMENT_ARRAY_BUFFER]=[],e.bindBuffer=a.bindBuffer,a.bindBuffer=function(a,b){var c=this._spidergl.cb._ext,d=c.currentBuffer[a];d!=b&&(c.currentBuffer[a]=b,c.glFunctions.bindBuffer.call(this,a,b))},c.getCurrentBuffer=function(a){return this._ext.currentBuffer[a]},c.pushBuffer=function(a){var b=this._ext,c=b.bufferStack[a],d=b.currentBuffer[a];c.push(d)},c.popBuffer=function(a){var b=this._ext,c=b.bufferStack[a];if(!(c.length<=0)){var d=c.pop();b.gl.bindBuffer(a,d)}},d.currentFramebuffer={},d.currentFramebuffer[a.FRAMEBUFFER]=a.getParameter(a.FRAMEBUFFER_BINDING),d.framebufferStack={},d.framebufferStack[a.FRAMEBUFFER]=[],e.bindFramebuffer=a.bindFramebuffer,a.bindFramebuffer=function(a,b){var c=this._spidergl.cb._ext,d=c.currentFramebuffer[a];d!=b&&(c.currentFramebuffer[a]=b,c.glFunctions.bindFramebuffer.call(this,a,b))},c.getCurrentFramebuffer=function(a){return this._ext.currentFramebuffer[a]},c.pushFramebuffer=function(a){var b=this._ext,c=b.framebufferStack[a],d=b.currentFramebuffer[a];c.push(d)},c.popFramebuffer=function(a){var b=this._ext,c=b.framebufferStack[a];if(!(c.length<=0)){var d=c.pop();b.gl.bindFramebuffer(a,d)}},d.currentProgram=a.getParameter(a.CURRENT_PROGRAM),d.programStack=[],e.useProgram=a.useProgram,a.useProgram=function(a){var b=this._spidergl.cb._ext,c=b.currentProgram;c!=a&&(b.currentProgram=a,b.glFunctions.useProgram.call(this,a))},c.getCurrentProgram=function(){return this._ext.currentProgram},c.pushProgram=function(){var a=this._ext,b=a.programStack,c=a.currentProgram;b.push(c)},c.popProgram=function(){var a=this._ext,b=a.programStack;if(!(b.length<=0)){var c=b.pop();a.gl.useProgram(c)}},d.currentRenderbuffer={},d.currentRenderbuffer[a.RENDERBUFFER]=a.getParameter(a.RENDERBUFFER_BINDING),d.renderbufferStack={},d.renderbufferStack[a.RENDERBUFFER]=[],e.bindRenderbuffer=a.bindRenderbuffer,a.bindRenderbuffer=function(a,b){var c=this._spidergl.cb._ext,d=c.currentRenderbuffer[a];d!=b&&(c.currentRenderbuffer[a]=b,c.glFunctions.bindRenderbuffer.call(this,a,b))},c.getCurrentRenderbuffer=function(a){return this._ext.currentRenderbuffer[a]},c.pushRenderbuffer=function(a){var b=this._ext,c=b.renderbufferStack[a],d=b.currentRenderbuffer[a];c.push(d)},c.popRenderbuffer=function(a){var b=this._ext,c=b.renderbufferStack[a];if(!(c.length<=0)){var d=c.pop();b.gl.bindRenderbuffer(a,d)}},d.currentShader={},d.currentShader[a.VERTEX_SHADER]=null,d.currentShader[a.FRAGMENT_SHADER]=null,d.shaderStack={},d.shaderStack[a.VERTEX_SHADER]=[],d.shaderStack[a.FRAGMENT_SHADER]=[],d.glFunctions.bindShader=function(a,b){},c.bindShader=function(a,b){var c=this._ext,d=c.currentShader[a];d!=b&&(c.currentShader[a]=b,c.glFunctions.bindShader.call(c.gl,a,b))},c.getCurrentShader=function(a){return this._ext.currentShader[a]},c.pushShader=function(a){var b=this._ext,c=b.shaderStack[a],d=b.currentShader[a];c.push(d)},c.popShader=function(a){var b=this._ext,c=b.shaderStack[a];if(!(c.length<=0)){var d=c.pop();b.gl.bindShader(a,d)}},d.currentTexture={};var f=a.getParameter(a.ACTIVE_TEXTURE),g=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS);d.currentTexture={},d.textureStack={},d.textureUnitStack=[];for(var h=0;h0},get size(){return this._size},get usage(){return this._usage},setSize:function(a,b){b=SpiderGL.Utility.getDefaultValue(b,SpiderGL.WebGL.Buffer.DEFAULT_USAGE),this._dsa.bufferData(this._h,this._t,a,b)},setData:function(a,b){b=SpiderGL.Utility.getDefaultValue(b,SpiderGL.WebGL.Buffer.DEFAULT_USAGE),this._dsa.bufferData(this._h,this._t,a,b)},setSubData:function(a,b){b=SpiderGL.Utility.getDefaultValue(b,SpiderGL.WebGL.Buffer.DEFAULT_SUB_DATA_OFFSET),this._dsa.bufferSubData(this._h,this._t,b,a)},destroy:function(){this._gl.deleteBuffer(this._h)},bind:function(){this._gl.bindBuffer(this._t,this._h)},unbind:function(){this._gl.bindBuffer(this._t,null)}},SpiderGL.Type.extend(SpiderGL.WebGL.Buffer,SpiderGL.WebGL.ObjectGL),SpiderGL.WebGL.VertexBuffer=function(a,b){return SpiderGL.WebGL.Context.isHijacked(a)?(SpiderGL.WebGL.Buffer.call(this,a,SpiderGL.WebGL.VertexBuffer.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this?this._h._spidergl:void 0):null},SpiderGL.WebGL.VertexBuffer.TARGET=WebGLRenderingContext.prototype.ARRAY_BUFFER,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX=0,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE=3,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE=WebGLRenderingContext.prototype.FLOAT,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED=!1,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE=0,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET=0,SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE=!0,SpiderGL.WebGL.VertexBuffer.unbind=function(a){a.bindBuffer(SpiderGL.WebGL.VertexBuffer.TARGET,null)},SpiderGL.WebGL.VertexBuffer.prototype={vertexAttribPointer:function(a){a=SpiderGL.Utility.getDefaultObject({index:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_INDEX,size:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_SIZE,glType:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_TYPE,normalized:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_NORMALIZED,stride:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_STRIDE,offset:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_OFFSET,enable:SpiderGL.WebGL.VertexBuffer.DEFAULT_ATTRIBUTE_ENABLE},a),this._dsa.vertexAttribPointer(this._h,a.index,a.size,a.glType,a.normalized,a.stride,a.offset),a.enable&&this._gl.enableVertexAttribArray(a.index)}},SpiderGL.Type.extend(SpiderGL.WebGL.VertexBuffer,SpiderGL.WebGL.Buffer),SpiderGL.WebGL.IndexBuffer=function(a,b){return SpiderGL.WebGL.Context.isHijacked(a)?(SpiderGL.WebGL.Buffer.call(this,a,SpiderGL.WebGL.IndexBuffer.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this?this._h._spidergl:void 0):null},SpiderGL.WebGL.IndexBuffer.TARGET=WebGLRenderingContext.prototype.ELEMENT_ARRAY_BUFFER,SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE=WebGLRenderingContext.prototype.TRIANGLES,SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT=-1,SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE=WebGLRenderingContext.prototype.UNSIGNED_SHORT,SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET=0,SpiderGL.WebGL.IndexBuffer.unbind=function(a){a.bindBuffer(SpiderGL.WebGL.IndexBuffer.TARGET,null)},SpiderGL.WebGL.IndexBuffer.prototype={drawElements:function(a){if(a=SpiderGL.Utility.getDefaultObject({glMode:SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_MODE,count:SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_COUNT,glType:SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_TYPE,offset:SpiderGL.WebGL.IndexBuffer.DEFAULT_DRAW_ELEMENTS_OFFSET},a),a.count<1){var b=SpiderGL.Type.typeSizeFromGL(a.glType);a.count=(this._size-a.offset)/b}this._dsa.drawElements(this._h,a.glMode,a.count,a.glType,a.offset)}},SpiderGL.Type.extend(SpiderGL.WebGL.IndexBuffer,SpiderGL.WebGL.Buffer),SpiderGL.WebGL.Framebuffer=function(a,b){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;SpiderGL.Type.instanceOf(b,WebGLFramebuffer)&&(b={handle:b}),b=SpiderGL.Utility.getDefaultObject({handle:null,autoViewport:SpiderGL.WebGL.Framebuffer.DEFAULT_AUTO_VIEWPORT},b);SpiderGL.WebGL.ObjectGL.call(this,a,SpiderGL.WebGL.Framebuffer.TARGET,b);if(this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;var a=this._gl,d=this._cb,f=(this._dsa,this._t),g=this._h,h=!1;if(g?h=!0:(g=a.createFramebuffer(),this._h=g),g._spidergl=this,this._attachments={},this._status=0,this._autoViewport=b.autoViewport,this._viewport=[0,0,1,1],d.pushFramebuffer(f),a.bindFramebuffer(f,g),h){var i=null,j=0,k=0,l=0;for(var m in SpiderGL.WebGL.Framebuffer._attachmentName)switch(i=a.getFramebufferAttachmentParameter(f,att,a.FRAMEBUFFER_ATTACHMENT_OBJECT_NAME),j=a.getFramebufferAttachmentParameter(f,att,a.FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE)){case a.RENDERBUFFER:l=a.RENDERBUFFER,this._importRenderbuffer(f,m,l,i);break;case a.TEXTURE:k=a.getFramebufferAttachmentParameter(f,att,a.FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL),l=a.getFramebufferAttachmentParameter(f,att,a.FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE),0==l&&(l=a.TEXTURE_2D),this._importTexture(f,m,l,i,k)}}this._status=a.checkFramebufferStatus(f),d.popFramebuffer(f),this.setAttachments(b)},SpiderGL.WebGL.Framebuffer.TARGET=WebGLRenderingContext.prototype.FRAMEBUFFER,SpiderGL.WebGL.Framebuffer.DEFAULT_AUTO_VIEWPORT=!0,SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL=0,SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE=WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_X,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X=0,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_Y=0,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_WIDTH=-1,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_HEIGHT=-1,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_FORMAT=WebGLRenderingContext.prototype.RGBA,SpiderGL.WebGL.Framebuffer.DEFAULT_CLEAR_MASK=WebGLRenderingContext.prototype.COLOR_BUFFER_BIT|WebGLRenderingContext.prototype.DEPTH_BUFFER_BIT|WebGLRenderingContext.prototype.STENCIL_BUFFER_BIT,SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_TYPE=WebGLRenderingContext.UNSIGNED_BYTE,SpiderGL.WebGL.Framebuffer.unbind=function(a){a.bindFramebuffer(SpiderGL.WebGL.Framebuffer.TARGET,null)},SpiderGL.WebGL.Framebuffer._attachmentName={},SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.prototype.COLOR_ATTACHMENT0]="color",SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.prototype.DEPTH_ATTACHMENT]="depth",SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.prototype.STENCIL_ATTACHMENT]="stencil",SpiderGL.WebGL.Framebuffer._attachmentName[WebGLRenderingContext.prototype.DEPTH_STENCIL_ATTACHMENT]="depthStencil",SpiderGL.WebGL.Framebuffer.prototype={_gl_deleteFramebuffer:function(a){this._h=null},_gl_isFramebuffer:function(a){},_gl_bindFramebuffer:function(a,b){},_gl_checkFramebufferStatus:function(a){},_gl_getFramebufferAttachmentParameter:function(a,b,c){},_gl_framebufferRenderbuffer:function(a,b,c,d){this._importRenderbuffer.apply(this,arguments),this._status=this._gl.checkFramebufferStatus(this._t)},_gl_framebufferTexture2D:function(a,b,c,d,e){this._importTexture.apply(this,arguments),this._status=this._gl.checkFramebufferStatus(this._t)},_gl_clear:function(a){},_gl_readPixels:function(a,b,c,d,e,f,g){},_importTexture:function(a,b,c,d,e){var f=SpiderGL.WebGL.Framebuffer._attachmentName[b];if(f){if(!d)return void delete this._attachments[f];var g=this._gl,h={attachment:b,resource:null,target:c,level:e,face:g.NONE};this._attachments[f]=h,c==g.TEXTURE_2D?h.resource=new SpiderGL.WebGL.Texture2D(g,{handle:d}):(h.resource=new SpiderGL.WebGL.TextureCubeMap(g,{handle:d}),h.face=c),this._viewport=[0,0,SpiderGL.Math.max(h.resource.width,1),SpiderGL.Math.max(h.resource.height,1)]}},_importRenderbuffer:function(a,b,c,d){var e=SpiderGL.WebGL.Framebuffer._attachmentName[b];if(e){if(!d)return void delete this._attachments[e];var f=this._gl,g={attachment:b,resource:null,target:c,level:0,face:f.NONE};this._attachments[e]=g,g.resource=new SpiderGL.WebGL.Renderbuffer(f,{handle:d}),this._viewport=[0,0,SpiderGL.Math.max(g.resource.width,1),SpiderGL.Math.max(g.resource.height,1)]}},_setAttachment:function(a,b){var c=SpiderGL.WebGL.Framebuffer._attachmentName[a];if(!c)return!1;var d=this._gl,e=!b||"resource"in b&&!b.resource;if(e){var f=this._attachments[c];return void(f&&(f.target===d.RENDERBUFFER?d.framebufferRenderbuffer(i,f.attachment,d.RENDERBUFFER,null):d.framebufferTexture2D(i,f.attachment,d.TEXTURE_2D,null,0)))}var g=d.NONE;SpiderGL.Type.instanceOf(b,WebGLTexture)?(b={resource:b},g=d.TEXTURE):SpiderGL.Type.instanceOf(b,WebGLRenderbuffer)?(b={resource:b},g=d.RENDERBUFFER):SpiderGL.Type.instanceOf(b,SpiderGL.WebGL.Texture)?(b={resource:b.handle},g=d.TEXTURE):SpiderGL.Type.instanceOf(b,SpiderGL.WebGL.Renderbuffer)&&(b={resource:b.handle},g=d.RENDERBUFFER);var h=!!b&&"undefined"!=typeof b.face;b=SpiderGL.Utility.getDefaultObject({resource:null,level:SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_TEXTURE_LEVEL,face:SpiderGL.WebGL.Framebuffer.DEFAULT_ATTACHMENT_CUBE_MAP_FACE},b);var i=this._t;switch(g){case d.TEXTURE:var j=SpiderGL.Type.instanceOf(b,SpiderGL.WebGL.TextureCubeMap)||h,k=j?b.face:d.TEXTURE_2D;d.framebufferTexture2D(i,a,k,b.resource,b.level);break;case d.RENDERBUFFER:d.framebufferRenderbuffer(i,a,d.RENDERBUFFER,b.resource)}return!0},get isReady(){return this.isComplete},get status(){return this._status},get isComplete(){return this._status===this._gl.FRAMEBUFFER_COMPLETE},get viewport(){return this._viewport.slice()},get width(){return this._viewport[2]},get height(){return this._viewport[3]},get autoViewport(){return this._autoViewport},set autoViewport(a){this._autoViewport=!!a},setAttachments:function(a){a=a||{};var b=this._gl,c=this._cb,d=this._t,e=this._h;return c.pushFramebuffer(d),b.bindFramebuffer(d,e),"color"in a&&this._setAttachment(b.COLOR_ATTACHMENT0,a.color),"depthStencil"in a?(this._setAttachment(b.DEPTH_ATTACHMENT,null),this._setAttachment(b.STENCIL_ATTACHMENT,null),this._setAttachment(b.DEPTH_STENCIL_ATTACHMENT,a.depthStencil)):"depth"in a?(this._setAttachment(b.DEPTH_STENCIL_ATTACHMENT,null),this._setAttachment(b.STENCIL_ATTACHMENT,null),this._setAttachment(b.DEPTH_ATTACHMENT,a.depth)):"stencil"in a&&(this._setAttachment(b.DEPTH_STENCIL_ATTACHMENT,null),this._setAttachment(b.DEPTH_ATTACHMENT,null),this._setAttachment(b.STENCIL_ATTACHMENT,a.stencil)),this._status=b.checkFramebufferStatus(d),c.popFramebuffer(d),this.isComplete},getAttachments:function(){var a={},b=null;for(var c in this._attachments)b=this._attachments[c],a[c]={attachment:b.attachment,resource:b.resource,target:b.target,level:b.level};return a},detachAll:function(){this.setAttachments({color:null,depthStencil:null})},get colorTarget(){var a=this._attachments.color;return a?a.resource:null},set colorTarget(a){this.setAttachments({color:a})},get depthTarget(){var a=this._attachments.depth;return a?a.resource:null},set depthTarget(a){this.setAttachments({depth:a})},get stencilTarget(){var a=this._attachments.stencil;return a?a.resource:null},set stencilTarget(a){this.setAttachments({stencil:a})},get depthStencilTarget(){var a=this._attachments.depthStencil;return a?a.resource:null},set depthStencilTarget(a){this.setAttachments({depthStencil:a})},clear:function(a){a=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Framebuffer.DEFAULT_CLEAR_MASK),this._dsa.clear(this._h,a)},readPixels:function(a,b){b=SpiderGL.Utility.getDefaultObject({x:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_X,y:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_Y,width:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_WIDTH,height:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_HEIGHT,format:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_FORMAT,type:SpiderGL.WebGL.Framebuffer.DEFAULT_READ_PIXELS_TYPE},b),b.width<0&&(b.width=this._viewport[2]),b.height<0&&(b.height=this._viewport[3]),this._dsa.readPixels(this._h,b.x,b.y,b.width,b.height,b.format,b.type,a)},applyViewport:function(){var a=this._gl,b=this._viewport;a.viewport(b[0],b[1],b[2],b[3])},destroy:function(){this._gl.deleteFramebuffer(this._h)},bind:function(a){var b=this._gl;b.bindFramebuffer(this._t,this._h);var c=SpiderGL.Utility.getDefaultValue(a,this._autoViewport);if(c){var d=this._viewport;b.viewport(d[0],d[1],d[2],d[3])}},unbind:function(){this._gl.bindFramebuffer(this._t,null)}},SpiderGL.Type.extend(SpiderGL.WebGL.Framebuffer,SpiderGL.WebGL.ObjectGL),SpiderGL.WebGL.Program=function(a,b){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;if(SpiderGL.Type.instanceOf(b,WebGLProgram)&&(b={handle:b}),b=SpiderGL.Utility.getDefaultObject({handle:null,autoLink:SpiderGL.WebGL.Program.DEFAULT_AUTO_LINK},b),SpiderGL.WebGL.ObjectGL.call(this,a,SpiderGL.WebGL.Program.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;var a=this._gl,e=(this._cb,this._dsa,this._h),f=!1,g="",h=!1;if(e?(h=!0,f=!!a.getProgramParameter(e,a.LINK_STATUS),g=a.getProgramInfoLog(e),g||(g="")):(e=a.createProgram(),this._h=e),e._spidergl=this,this._shaders=[],this._linked=f,this._log=g,this._autoLink=b.autoLink,this._attributes={},this._uniforms={},h)for(var i=a.getAttachedShaders(e),j=0,k=i.length;j=0)){var b=this._gl,c=a._spidergl;if(!c){var d=b.getShaderParameter(a,b.SHADER_TYPE);switch(d){case b.VERTEX_SHADER:c=new SpiderGL.WebGL.VertexShader(b,{handle:a});break;case b.FRAGMENT_SHADER:c=new SpiderGL.WebGL.FragmentShader(b,{handle:a});break;default:return}}this._shaders.push(c)}},_updateActiveInfo:function(){var a=this._gl,b=this._h,c=0,d=null,e=null,f=null,g={};c=a.getProgramParameter(b,a.ACTIVE_ATTRIBUTES);for(var h=0;h1){var j=e.lastIndexOf("[0]");if(j==e.length-3)for(var k=e.slice(0,j),l=1;l=0},getShaders:function(){return this._shaders.slice()},link:function(){return this._gl.linkProgram(this._h),this._linked},validate:function(){var a=this._gl,b=this._h;a.validateProgram(b);var c=!!a.getProgramParameter(b,a.VALIDATE_STATUS);return c},setAttributes:function(a){return!!this._setAttributes(a)&&(!this._autoLink||this.link())},getAttributesNames:function(){var a=this._attributes,b=[];for(var c in a)b.push(a[c].name);return b},getAttributesIndices:function(){var a=this._attributes,b={};for(var c in a)b[c]=a[c].location;return b},getAttributesInfo:function(){var a=this._attributes,b=null,c={};for(var d in a)b=a[d],c[d]={index:b.index,name:b.name,size:b.size,type:b.type,location:b.location};return c},setUniforms:function(a){if(!a)return!1;var b=this._gl,c=this._cb,d=this._dsa,e=this._h;c.pushProgram(),b.useProgram(e);var f=this._uniforms,g=null;for(var i in a)g=f[i],g&&g.setValue(d,e,a[i]);return c.popProgram(),!0},getUniformsNames:function(){var a=this._uniforms,b=[];for(var c in a)b.push(a[c].name);return b},getUniformsValues:function(){var a=this._gl,b=this._h,c=this._uniforms,d={};for(var e in c)d[e]=a.getUniform(b,c[e].location);return d},getUniformsInfo:function(){var a=this._uniforms,b=null,d={};for(var e in a)b=a[e],d[e]={index:b.index,name:b.name,size:b.size,type:b.type,location:b.location};return d},destroy:function(){this._gl.deleteProgram(this._h)},bind:function(){this._gl.useProgram(this._h)},unbind:function(){this._gl.useProgram(null)}},SpiderGL.Type.extend(SpiderGL.WebGL.Program,SpiderGL.WebGL.ObjectGL),SpiderGL.WebGL.Renderbuffer=function(a,b){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;if(SpiderGL.Type.instanceOf(f,WebGLRenderbuffer)&&(b={handle:b}),b=SpiderGL.Utility.getDefaultObject({handle:null},b),SpiderGL.WebGL.ObjectGL.call(this,a,SpiderGL.WebGL.Renderbuffer.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;var a=this._gl,c=this._cb,e=(this._dsa,this._t),f=this._h,g=a.NONE,h=0,i=0;f?(c.pushRenderbuffer(e),a.bindRenderbuffer(e,f),g=a.getRenderbufferParameter(e,a.RENDERBUFFER_INTERNAL_FORMAT),h=a.getRenderbufferParameter(e,a.RENDERBUFFER_WIDTH),i=a.getRenderbufferParameter(e,a.RENDERBUFFER_HEIGHT),c.popRenderbuffer(e)):(f=a.createRenderbuffer(),this._h=f),f._spidergl=this,this._width=h,this._height=i,this._format=g,SpiderGL.Type.isNumber(b.internalFormat)&&SpiderGL.Type.isNumber(b.width)&&SpiderGL.Type.isNumber(b.height)&&this.setStorage(b.internalFormat,b.width,b.height,b.format)},SpiderGL.WebGL.Renderbuffer.TARGET=WebGLRenderingContext.prototype.RENDERBUFFER,SpiderGL.WebGL.Renderbuffer.unbind=function(a){a.bindRenderbuffer(SpiderGL.WebGL.Renderbuffer.TARGET,null)},SpiderGL.WebGL.Renderbuffer.prototype={_gl_deleteRenderbuffer:function(a){this._h=null},_gl_isRenderbuffer:function(a){},_gl_bindRenderbuffer:function(a,b){},_gl_getRenderbufferParameter:function(a,b){},_gl_renderbufferStorage:function(a,b,c,d){this._format=b,this._width=c,this._height=d},get isReady(){return this._width>0&&this._height>0},get format(){return this._format},get width(){return this._width},get height(){return this._height},setStorage:function(a,b,c){this._dsa.renderbufferStorage(this._h,this._t,a,b,c)},destroy:function(){this._gl.deleteRenderbuffer(this._h)},bind:function(){this._gl.bindRenderbuffer(this._t,this._h)},unbind:function(){this._gl.bindRenderbuffer(this._t,null)}},SpiderGL.Type.extend(SpiderGL.WebGL.Renderbuffer,SpiderGL.WebGL.ObjectGL),
-SpiderGL.WebGL.Shader=function(a,b,c,d){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;if(SpiderGL.Type.instanceOf(d,WebGLShader)?d={handle:d}:SpiderGL.Type.isString(d)&&(d={source:d}),d=SpiderGL.Utility.getDefaultObject({handle:null,source:null,autoCompile:SpiderGL.WebGL.Shader.DEFAULT_AUTO_COMPILE},d),SpiderGL.WebGL.ObjectGL.call(this,a,b,d),this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;var a=this._gl,g=(this._cb,this._dsa,""),h=!1,i=!1,j="",k=this._h;k?(g=a.getShaderSource(k),g||(g=""),h=!!a.getShaderParameter(k,a.COMPILE_STATUS),i=!!a.getShaderParameter(k,a.DELETE_STATUS),j=a.getShaderInfoLog(k),j||(j="")):(k=a.createShader(c),this._h=k),k._spidergl=this,this._source=g,this._compiled=h,this._log=j,this._autoCompile=d.autoCompile,d.source&&this.setSource(d.source)},SpiderGL.WebGL.Shader.TARGET=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.Shader.DEFAULT_AUTO_COMPILE=!0,SpiderGL.WebGL.Shader.unbind=function(a){},SpiderGL.WebGL.Shader.prototype={_gl_deleteShader:function(a){this._h=null},_gl_isShader:function(a){},_gl_getShaderParameter:function(a,b){},_gl_getShaderInfoLog:function(a){},_gl_getShaderSource:function(a){},_gl_compileShader:function(a){this._postCompile()},_gl_shaderSource:function(a,b){this._source=b,this._source||(this._source="")},_postCompile:function(){var a=this._gl,b=this._h;this._compiled=!!a.getShaderParameter(b,a.COMPILE_STATUS),this._log=a.getShaderInfoLog(b),this._log||(this._log="")},get isReady(){return this.isCompiled},get isCompiled(){return this._compiled},get log(){return this._log},get autoCompile(){return this._autoCompile},set autoCompile(a){this._autoCompile=!!a},setSource:function(a,b){var c=this._gl,d=this._h;c.shaderSource(d,a);SpiderGL.Utility.getDefaultValue(b,this._autoCompile);return this.compile()},get source(){return this._source},set source(a){this.setSource(a)},compile:function(){return this._gl.compileShader(this._h),this._compiled},destroy:function(){this._gl.deleteShader(this._h)},bind:function(){},unbind:function(){}},SpiderGL.Type.extend(SpiderGL.WebGL.Shader,SpiderGL.WebGL.ObjectGL),SpiderGL.WebGL.VertexShader=function(a,b){return SpiderGL.WebGL.Context.isHijacked(a)?(SpiderGL.WebGL.Shader.call(this,a,SpiderGL.WebGL.VertexShader.TARGET,a.VERTEX_SHADER,b),this._h&&this._h._spidergl&&this._h._spidergl!=this?this._h._spidergl:void 0):null},SpiderGL.WebGL.VertexShader.TARGET=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.VertexShader.unbind=function(a){},SpiderGL.WebGL.VertexShader.prototype={},SpiderGL.Type.extend(SpiderGL.WebGL.VertexShader,SpiderGL.WebGL.Shader),SpiderGL.WebGL.FragmentShader=function(a,b){return SpiderGL.WebGL.Context.isHijacked(a)?(SpiderGL.WebGL.Shader.call(this,a,SpiderGL.WebGL.FragmentShader.TARGET,a.FRAGMENT_SHADER,b),this._h&&this._h._spidergl&&this._h._spidergl!=this?this._h._spidergl:void 0):null},SpiderGL.WebGL.FragmentShader.TARGET=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.FragmentShader.unbind=function(a){},SpiderGL.WebGL.FragmentShader.prototype={},SpiderGL.Type.extend(SpiderGL.WebGL.FragmentShader,SpiderGL.WebGL.Shader),SpiderGL.WebGL.Texture=function(a,b,c){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;if(SpiderGL.Type.instanceOf(c,WebGLTexture)?c={handle:c}:SpiderGL.Type.isString(c)&&(c={url:c}),c=SpiderGL.Utility.getDefaultObject({handle:null,magFilter:SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER,minFilter:SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER,wrapS:SpiderGL.WebGL.Texture.DEFAULT_WRAP_S,wrapT:SpiderGL.WebGL.Texture.DEFAULT_WRAP_T,flipYPolicy:SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y,premultiplyAlphaPolicy:SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA,colorspaceConversionPolicy:SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION,autoMipmap:SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP,format:a.NONE,width:0,height:0},c),SpiderGL.WebGL.ObjectGL.call(this,a,b,c),this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;var a=this._gl,d=this._cb,f=(this._dsa,this._t),g=this._h;g||(g=a.createTexture(),this._h=g),d.pushTexture(f),a.bindTexture(f,g),this._magFilter=a.getTexParameter(f,a.TEXTURE_MAG_FILTER),this._minFilter=a.getTexParameter(f,a.TEXTURE_MIN_FILTER),this._wrapS=a.getTexParameter(f,a.TEXTURE_WRAP_S),this._wrapT=a.getTexParameter(f,a.TEXTURE_WRAP_T),d.popTexture(f),g._spidergl=this,this._format=c.format,this._width=c.width,this._height=c.height,this._flipY=c.flipYPolicy,this._premultiplyAlpha=c.premultiplyAlphaPolicy,this._colorspaceConversion=c.colorspaceConversionPolicy,this._autoMipmap=c.autoMipmap,this._missingFaces=SpiderGL.WebGL.Texture._FACE_ALL_BITS,this.setSampler(c)},SpiderGL.WebGL.Texture.TARGET=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.Texture.DEFAULT_BORDER=0,SpiderGL.WebGL.Texture.DEFAULT_FORMAT=WebGLRenderingContext.prototype.RGBA,SpiderGL.WebGL.Texture.DEFAULT_AUTO_GENERATE_MIPMAP=!1,SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT=WebGLRenderingContext.prototype.RGBA,SpiderGL.WebGL.Texture.DEFAULT_LEVEL=0,SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER=WebGLRenderingContext.prototype.LINEAR,SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER=WebGLRenderingContext.prototype.LINEAR,SpiderGL.WebGL.Texture.DEFAULT_TYPE=WebGLRenderingContext.prototype.UNSIGNED_BYTE,SpiderGL.WebGL.Texture.DEFAULT_WRAP_S=WebGLRenderingContext.prototype.REPEAT,SpiderGL.WebGL.Texture.DEFAULT_WRAP_T=WebGLRenderingContext.prototype.REPEAT,SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET=0,SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET=0,SpiderGL.WebGL.Texture.DEFAULT_UNPACK_FLIP_Y=!0,SpiderGL.WebGL.Texture.DEFAULT_UNPACK_PREMULTIPLY_ALPHA=!1,SpiderGL.WebGL.Texture.DEFAULT_UNPACK_COLORSPACE_CONVERSION=WebGLRenderingContext.prototype.NONE,SpiderGL.WebGL.Texture.unbind=function(a){},SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT=1,SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT=2,SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT=4,SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT=8,SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT=16,SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT=32,SpiderGL.WebGL.Texture._FACE_ALL_BITS=SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT|SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT|SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT|SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT|SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT|SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT,SpiderGL.WebGL.Texture._faceBits={},SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_2D]=SpiderGL.WebGL.Texture._FACE_ALL_BITS,SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP]=SpiderGL.WebGL.Texture._FACE_ALL_BITS;SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_X]=SpiderGL.WebGL.Texture._FACE_POSITIVE_X_BIT;SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_X]=SpiderGL.WebGL.Texture._FACE_NEGATIVE_X_BIT,SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_Y]=SpiderGL.WebGL.Texture._FACE_POSITIVE_Y_BIT,SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_Y]=SpiderGL.WebGL.Texture._FACE_NEGATIVE_Y_BIT,SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_Z]=SpiderGL.WebGL.Texture._FACE_POSITIVE_Z_BIT,SpiderGL.WebGL.Texture._faceBits[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_Z]=SpiderGL.WebGL.Texture._FACE_NEGATIVE_Z_BIT,SpiderGL.WebGL.Texture.prototype={_gl_deleteTexture:function(a){this._h=null},_gl_isTexture:function(a){},_gl_bindTexture:function(a,b){},_gl_getTexParameter:function(a,b){},_gl_copyTexImage2D:function(a,b,c,d,e,f,g,h){0==b&&(this._format=c,this._width=f,this._height=g)},_gl_copyTexSubImage2D:function(a,b,c,d,e,f,g,h,i){},_gl_generateMipmap:function(a){},_gl_texImage2D:function(a){var b=arguments.length;6===b?0===arguments[1]&&(this._format=arguments[2],this._width=arguments[5].width,this._height=arguments[5].height):9===b&&0===arguments[1]&&(this._format=arguments[2],this._width=arguments[3],this._height=arguments[4])},_gl_texParameterf:function(a,b,c){this._setTexParameter(b,c)},_gl_texParameteri:function(a,b,c){this._setTexParameter(b,c)},_gl_texSubImage2D:function(a){},_setTexParameter:function(a,b){var c=this._gl;switch(a){case c.TEXTURE_MAG_FILTER:this._magFilter=b;break;case c.TEXTURE_MIN_FILTER:this._minFilter=b;break;case c.TEXTURE_WRAP_S:this._wrapS=b;break;case c.TEXTURE_WRAP_T:this._wrapT=b}},_setImageData:function(a,b,c){c=SpiderGL.Utility.getDefaultObject({internalFormat:SpiderGL.WebGL.Texture.DEFAULT_INTERNAL_FORMAT,border:SpiderGL.WebGL.Texture.DEFAULT_BORDER,xoffset:SpiderGL.WebGL.Texture.DEFAULT_X_OFFSET,yoffset:SpiderGL.WebGL.Texture.DEFAULT_Y_OFFSET,level:SpiderGL.WebGL.Texture.DEFAULT_LEVEL,format:SpiderGL.WebGL.Texture.DEFAULT_FORMAT,type:SpiderGL.WebGL.Texture.DEFAULT_TYPE,width:0,height:0,generateMipmap:this._autoMipmap,flipY:this._flipY,premultiplyAlpha:this._premultiplyAlpha,colorspaceConversion:this._colorspaceConversion,data:null,url:null,onCancel:null,onError:null,onProgress:null,onSuccess:null},c);var d=!!c.url,e=!1;d||(e=!c.data||SpiderGL.Type.isTypedArray(c.data));var f=!1;d||e||(f=SpiderGL.Type.instanceOf(c.data,HTMLImageElement)||SpiderGL.Type.instanceOf(c.data,HTMLCanvasElement)||SpiderGL.Type.instanceOf(c.data,HTMLVideoElement),f||"undefined"!=typeof ImageData&&(f=SpiderGL.Type.instanceOf(c.data,ImageData)));var g=this._gl,i=(this._cb,this._dsa),j=b,k=this._h,l=-1,m=-1,n=-1,o=-1,p=-1,q=-1;(e||f)&&(l=c.flipY,l!=SpiderGL.Core.DONT_CARE&&(m=g.getParameter(g.UNPACK_FLIP_Y_WEBGL),l==m?m=-1:g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,l)),n=c.premultiplyAlpha,n!=SpiderGL.Core.DONT_CARE&&(o=g.getParameter(g.UNPACK_PREMULTIPLY_ALPHA_WEBGL),n==o?o=-1:g.pixelStorei(g.UNPACK_PREMULTIPLY_ALPHA_WEBGL,n)),p=c.colorspaceConversion,p!=SpiderGL.Core.DONT_CARE&&(q=g.getParameter(g.UNPACK_COLORSPACE_CONVERSION_WEBGL),p==q?q=-1:g.pixelStorei(g.UNPACK_COLORSPACE_CONVERSION_WEBGL,p)));var r=!1;if(d){var s={internalFormat:c.internalFormat,border:c.border,xoffset:c.xoffset,yoffset:c.yoffset,level:c.level,format:c.format,type:c.type,generateMipmap:c.generateMipmap,flipY:c.flipY,premultiplyAlpha:c.premultiplyAlpha,colorspaceConversion:c.colorspaceConversion,data:null},t=this,u=c.onSuccess,v=new SpiderGL.IO.ImageRequest(c.url,{onCancel:c.onCancel,onError:c.onError,onProgress:c.onProgress,onSuccess:function(){s.data=v.image,a?t._setImage(b,s):t._setSubImage(b,s),u&&u()},send:!0});return!0}if(e){if(c.width<=0||c.height<=0)return!1;a?(i.texImage2D(k,j,c.level,c.internalFormat,c.width,c.height,c.border,c.format,c.type,c.data),r=!0):i.texSubImage2D(k,j,c.level,c.xoffset,c.yoffset,c.width,c.height,c.format,c.type,c.data)}else{if(!f)return!1;a?(i.texImage2D(k,j,c.level,c.internalFormat,c.format,c.type,c.data),r=!0):i.texSubImage2D(k,j,c.level,c.xoffset,c.yoffset,c.format,c.type,c.data)}return r&&(this._missingFaces&=~SpiderGL.WebGL.Texture._faceBits[j]),(e||f)&&(m!=-1&&g.pixelStorei(g.UNPACK_FLIP_Y_WEBGL,m),o!=-1&&g.pixelStorei(g.UNPACK_PREMULTIPLY_ALPHA_WEBGL,o),q!=-1&&g.pixelStorei(g.UNPACK_COLORSPACE_CONVERSION_WEBGL,q)),c.generateMipmap&&this.generateMipmap(),!0},_setImage:function(a,b){return this._setImageData(!0,a,b)},_setSubImage:function(a,b){return this._setImageData(!1,a,b)},get isReady(){return 0==this._missingFaces&&this._width>0&&this._height>0},get flipYPolicy(){return this._flipY},set flipYPolicy(a){this._flipY=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Context.DEFAULT_UNPACK_FLIP_Y)},get premultuplyAlphaPolicy(){return this._premultuplyAlpha},set premultuplyAlphaPolicy(a){this._premultuplyAlpha=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Context.DEFAULT_UNPACK_PREMULTIPLY_ALPHA)},get colorspaceConversionPolicy(){return this._colorspaceConversion},set colorspaceConversionPolicy(a){this._colorspaceConversion=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Context.DEFAULT_UNPACK_COLORSPACE_CONVERSION)},get autoMipmap(){return this._autoMipmap},set autoMipmap(a){this._autoMipmap=a},get format(){return this._format},get width(){return this._width},get height(){return this._height},get magFilter(){return this._magFilter},set magFilter(a){a=SpiderGL.Utility.getDefaultValue(w,SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER),this._dsa.texParameteri(this._h,this._t,gl.TEXTURE_MAG_FILTER,a)},get minFilter(){return this._minFilter},set minFilter(a){a=SpiderGL.Utility.getDefaultValue(w,SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER),this._dsa.texParameteri(this._h,this._t,gl.TEXTURE_MIN_FILTER,a)},get wrapS(){return this._wrapS},set wrapS(a){a=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Texture.DEFAULT_WRAP_S),this._dsa.texParameteri(this._h,this._t,gl.TEXTURE_WRAP_S,a)},get wrapT(){return this._wrapT},set wrapT(a){a=SpiderGL.Utility.getDefaultValue(a,SpiderGL.WebGL.Texture.DEFAULT_WRAP_T),this._dsa.texParameteri(this._h,this._t,gl.TEXTURE_WRAP_T,a)},setSampler:function(a){if(!a)return!1;var b=this._gl,c=this._cb,e=(this._dsa,this._t),f=this._h;c.pushTexture(e),b.bindTexture(e,f);var g=0;return"magFilter"in a&&(g=SpiderGL.Utility.getDefaultValue(a.magFilter,SpiderGL.WebGL.Texture.DEFAULT_MAG_FILTER),b.texParameteri(e,b.TEXTURE_MAG_FILTER,g)),"minFilter"in a&&(g=SpiderGL.Utility.getDefaultValue(a.minFilter,SpiderGL.WebGL.Texture.DEFAULT_MIN_FILTER),b.texParameteri(e,b.TEXTURE_MIN_FILTER,g)),"wrapS"in a&&(g=SpiderGL.Utility.getDefaultValue(a.wrapS,SpiderGL.WebGL.Texture.DEFAULT_WRAP_S),b.texParameteri(e,b.TEXTURE_WRAP_S,g)),"wrapT"in a&&(g=SpiderGL.Utility.getDefaultValue(a.wrapT,SpiderGL.WebGL.Texture.DEFAULT_WRAP_T),b.texParameteri(e,b.TEXTURE_WRAP_T,g)),c.popTexture(e),!0},getSampler:function(){return{magFilter:this._magFilter,minFilter:this._minFilter,wrapS:this._wrapS,wrapT:this._wrapT}},generateMipmap:function(){0==this._missingFaces&&this._dsa.generateMipmap(this._h,this._t)},destroy:function(){this._gl.deleteTexture(this._h)},bind:function(a){var b=this._gl,d=(this._cb,this._dsa);"undefined"==typeof a?b.bindTexture(this._t,this._h):d.bindTexture(b.TEXTURE0+a,this._t,this._h)},unbind:function(a){var b=this._gl,d=(this._cb,this._dsa);"undefined"==typeof a?b.bindTexture(this._t,null):d.bindTexture(b.TEXTURE0+a,this._t,null)}},SpiderGL.Type.extend(SpiderGL.WebGL.Texture,SpiderGL.WebGL.ObjectGL),SpiderGL.WebGL.Texture2D=function(a,b){return SpiderGL.WebGL.Context.isHijacked(a)?(SpiderGL.WebGL.Texture.call(this,a,SpiderGL.WebGL.Texture2D.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this?this._h._spidergl:(b=b||{},SpiderGL.Type.instanceOf(b,WebGLTexture)?b={handle:b}:SpiderGL.Type.isString(b)&&(b={url:b}),void(("url"in b||"data"in b||"width"in b&&"height"in b)&&this.setImage(b)))):null},SpiderGL.WebGL.Texture2D.TARGET=WebGLRenderingContext.prototype.TEXTURE_2D,SpiderGL.WebGL.Texture2D.unbind=function(a,b){var d=(a.getExtension("SGL_current_binding"),a.getExtension("SGL_direct_state_access"));"undefined"==typeof b?a.bindTexture(SpiderGL.WebGL.Texture2D.TARGET,null):d.bindTexture(a.TEXTURE0+b,SpiderGL.WebGL.Texture2D.TARGET,null)},SpiderGL.WebGL.Texture2D.prototype={setImage:function(a){return this._setImage(this._t,a)},setSubImage:function(a){return this._setSubImage(this._t,a)}},SpiderGL.Type.extend(SpiderGL.WebGL.Texture2D,SpiderGL.WebGL.Texture),SpiderGL.WebGL.TextureCubeMap=function(a,b){if(!SpiderGL.WebGL.Context.isHijacked(a))return null;if(SpiderGL.WebGL.Texture.call(this,a,SpiderGL.WebGL.TextureCubeMap.TARGET,b),this._h&&this._h._spidergl&&this._h._spidergl!=this)return this._h._spidergl;b=b||{},SpiderGL.Type.instanceOf(b,WebGLTexture)?b={handle:b}:SpiderGL.Type.isString(b)&&(b={url:b});var c=SpiderGL.WebGL.TextureCubeMap._faceTargets;if(b.url){var d=b.url,e=b.onSuccess;e&&(b.onSuccess=function(){var a=6;return function(){--a,0==a&&e.apply(b,null)}}());for(var f=0;f<6;++f)b.url=d[f],this.setImage(c[f],b);b.onSuccess=e}else if(b.data)for(var g=b.data,f=0;f<6;++f)b.data=g[f],this.setImage(c[f],b);else if(b.width>0&&b.height>0)for(var f=0;f<6;++f)this.setImage(c[f],b)},SpiderGL.WebGL.TextureCubeMap.TARGET=WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP,SpiderGL.WebGL.TextureCubeMap.unbind=function(a,b){var d=(a.getExtension("SGL_current_binding"),a.getExtension("SGL_direct_state_access"));"undefined"==typeof b?a.bindTexture(SpiderGL.WebGL.TextureCubeMap.TARGET,null):d.bindTexture(a.TEXTURE0+b,SpiderGL.WebGL.TextureCubeMap.TARGET,null)},SpiderGL.WebGL.TextureCubeMap._faceTargets=[WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_X,WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_X,WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_Y,WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_Y,WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_POSITIVE_Z,WebGLRenderingContext.prototype.TEXTURE_CUBE_MAP_NEGATIVE_Z],SpiderGL.WebGL.TextureCubeMap.prototype={setImage:function(a,b){return this._setImage(a,b)},setSubImage:function(a,b){return this._setSubImage(a,b)}},SpiderGL.Type.extend(SpiderGL.WebGL.TextureCubeMap,SpiderGL.WebGL.Texture),SpiderGL.Model={},SpiderGL.Model.Model=function(a,b,c){SpiderGL.Core.ObjectBase.call(this),c=SpiderGL.Utility.getDefaultObject({},c),b&&"vertices"in b&&(b=SpiderGL.Model.Model._createSimpleDescriptor(b)),this._descriptor=SpiderGL.Model.Model._fixDescriptor(b),this._gl=null,this._renderData={},a&&(this.updateGL(a,c),this.updateRenderData())},SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_SIZE=3,SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE=SpiderGL.Type.FLOAT32,SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_NORMALIZED=!1,SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_STRIDE=0,SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_OFFSET=0,SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_MODE=SpiderGL.Type.TRIANGLES,SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_FIRST=0,SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_COUNT=-1,SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE=SpiderGL.Type.UINT16,SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_OFFSET=0,SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP={},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.position={size:3,type:SpiderGL.Type.FLOAT32,normalized:!1,semantic:"POSITION",index:0,value:[0,0,0,1]},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.normal={size:3,type:SpiderGL.Type.FLOAT32,normalized:!1,semantic:"NORMAL",index:0,value:[0,0,1,0]},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.color={size:4,type:SpiderGL.Type.UINT8,normalized:!0,semantic:"COLOR",index:0,value:[0,0,0,255]},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.texcoord={size:2,type:SpiderGL.Type.FLOAT32,normalized:!1,semantic:"TEXCOORD",index:0,value:[0,0,0,1]},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.user={size:3,type:SpiderGL.Type.FLOAT32,normalized:!1,semantic:"USER",index:0,value:[0,0,0,1]},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP={},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.triangles={mode:SpiderGL.Type.TRIANGLES,type:SpiderGL.Type.UINT16,count:-1,semantic:"FILL"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.triangleStrip={mode:SpiderGL.Type.TRIANGLE_STRIP,type:SpiderGL.Type.UINT16,count:-1,semantic:"FILL"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.triangleFan={mode:SpiderGL.Type.TRIANGLE_FAN,type:SpiderGL.Type.UINT16,count:-1,semantic:"FILL"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.lines={mode:SpiderGL.Type.LINES,type:SpiderGL.Type.UINT16,count:-1,semantic:"LINE"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.lineStrip={mode:SpiderGL.Type.LINE_STRIP,type:SpiderGL.Type.UINT16,count:-1,semantic:"LINE"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.lineLoop={mode:SpiderGL.Type.LINE_LOOP,type:SpiderGL.Type.UINT16,count:-1,semantic:"LINE"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.points={mode:SpiderGL.Type.POINTS,type:SpiderGL.Type.UINT16,count:-1,semantic:"POINT"},SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_PRIMITIVE_MAP.user={mode:SpiderGL.Type.TRIANGLES,type:SpiderGL.Type.UINT16,count:-1,semantic:"FILL"},SpiderGL.Model.Model._fixDescriptor=function(a){return a=SpiderGL.Utility.getDefaultObject({version:"0.0.0.1 EXP",meta:null,data:null,access:null,semantic:null,logic:null},a),a.meta=SpiderGL.Model.Model._fixDescriptorMeta(a.meta),a.data=SpiderGL.Model.Model._fixDescriptorData(a.data),a.access=SpiderGL.Model.Model._fixDescriptorAccess(a.access),a.semantic=SpiderGL.Model.Model._fixDescriptorSemantic(a.semantic),a.logic=SpiderGL.Model.Model._fixDescriptorLogic(a.logic),a},SpiderGL.Model.Model._fixDescriptorMeta=function(a){return a=SpiderGL.Utility.getDefaultObject({author:null,date:null,description:null},a)},SpiderGL.Model.Model._fixDescriptorData=function(a){return a=SpiderGL.Utility.getDefaultObject({vertexBuffers:null,indexBuffers:null},a),a.vertexBuffers=SpiderGL.Model.Model._fixDescriptorDataVertexBuffers(a.vertexBuffers),a.indexBuffers=SpiderGL.Model.Model._fixDescriptorDataIndexBuffers(a.indexBuffers),a},SpiderGL.Model.Model._fixDescriptorDataVertexBuffers=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorDataVertexBuffer(a[b]);return a},SpiderGL.Model.Model._fixDescriptorDataVertexBuffer=function(a){return SpiderGL.Model.Model._fixDescriptorDataBuffer(a)},SpiderGL.Model.Model._fixDescriptorDataIndexBuffers=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorDataIndexBuffer(a[b]);return a},SpiderGL.Model.Model._fixDescriptorDataIndexBuffer=function(a){return SpiderGL.Model.Model._fixDescriptorDataBuffer(a)},SpiderGL.Model.Model._fixDescriptorDataBuffer=function(a){return a=SpiderGL.Utility.getDefaultObject({type:SpiderGL.Type.NO_TYPE,glType:WebGLRenderingContext.prototype.NONE,untypedArray:null,typedArray:null,glBuffer:null},a)},SpiderGL.Model.Model._fixDescriptorAccess=function(a){return a=SpiderGL.Utility.getDefaultObject({vertexStreams:null,primitiveStreams:null},a),a.vertexStreams=SpiderGL.Model.Model._fixDescriptorAccessVertexStreams(a.vertexStreams),a.primitiveStreams=SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStreams(a.primitiveStreams),a},SpiderGL.Model.Model._fixDescriptorAccessVertexStreams=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorAccessVertexStream(a[b]);return a},SpiderGL.Model.Model._fixDescriptorAccessVertexStream=function(a){return a=SpiderGL.Utility.getDefaultObject({buffer:null,size:SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_SIZE,type:SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE,glType:SpiderGL.Type.typeToGL(SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_TYPE),normalized:SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_NORMALIZED,stride:SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_STRIDE,offset:SpiderGL.Model.Model.DEFAULT_VERTEX_STREAM_OFFSET},a)},SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStreams=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStream(a[b]);return a},SpiderGL.Model.Model._fixDescriptorAccessPrimitiveStream=function(a){return a=SpiderGL.Utility.getDefaultObject({buffer:null,mode:SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_MODE,first:SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_FIRST,count:SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_COUNT,type:SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE,glType:SpiderGL.Type.typeToGL(SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_TYPE),offset:SpiderGL.Model.Model.DEFAULT_PRIMITIVE_STREAM_OFFSET},a)},SpiderGL.Model.Model._fixDescriptorSemantic=function(a){return a=SpiderGL.Utility.getDefaultObject({bindings:null,chunks:null},a),a.bindings=SpiderGL.Model.Model._fixDescriptorSemanticBindings(a.bindings),a.chunks=SpiderGL.Model.Model._fixDescriptorSemanticChunks(a.chunks),a},SpiderGL.Model.Model._fixDescriptorSemanticBindings=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorSemanticBinding(a[b]);return a},SpiderGL.Model.Model._fixDescriptorSemanticBinding=function(a){return a=SpiderGL.Utility.getDefaultObject({vertexStreams:null,primitiveStreams:null},a),a.vertexStreams=SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStreams(a.vertexStreams),a.primitiveStreams=SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStreams(a.primitiveStreams),a},SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStreams=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStream(a[b]);return a},SpiderGL.Model.Model._fixDescriptorSemanticBindingVertexStream=function(a){return a?SpiderGL.Type.isArray(a)?a.slice():[a]:null},SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStreams=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStream(a[b]);return a},SpiderGL.Model.Model._fixDescriptorSemanticBindingPrimitiveStream=function(a){return a?SpiderGL.Type.isArray(a)?a.slice():[a]:null},SpiderGL.Model.Model._fixDescriptorSemanticChunks=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorSemanticChunk(a[b]);return a},SpiderGL.Model.Model._fixDescriptorSemanticChunk=function(a){return a=SpiderGL.Utility.getDefaultObject({techniques:null},a),a.techniques=SpiderGL.Model.Model._fixDescriptorSemanticChunkTechniques(a.techniques),a},SpiderGL.Model.Model._fixDescriptorSemanticChunkTechniques=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorSemanticChunkTechnique(a[b]);return a},SpiderGL.Model.Model._fixDescriptorSemanticChunkTechnique=function(a){return a=SpiderGL.Utility.getDefaultObject({binding:null},a)},SpiderGL.Model.Model._fixDescriptorLogic=function(a){return a=SpiderGL.Utility.getDefaultObject({parts:null},a),a.parts=SpiderGL.Model.Model._fixDescriptorLogicParts(a.parts),a},SpiderGL.Model.Model._fixDescriptorLogicParts=function(a){a=SpiderGL.Utility.getDefaultObject({},a);for(var b in a)a[b]=SpiderGL.Model.Model._fixDescriptorLogicPart(a[b]);return a},SpiderGL.Model.Model._fixDescriptorLogicPart=function(a){return a=SpiderGL.Utility.getDefaultObject({chunks:null},a),a.chunks=SpiderGL.Model.Model._fixDescriptorLogicPartChunks(a.chunks),a},SpiderGL.Model.Model._fixDescriptorLogicPartChunks=function(a){return a?SpiderGL.Type.isArray(a)?a.slice():[a]:null},SpiderGL.Model.Model._createSimpleDescriptor=function(a){a=SpiderGL.Utility.getDefaultObject({vertices:null,primitives:null,options:null},a);var b="mainBinding",c="mainChunk",d="mainPart",e="VertexBuffer",f="IndexBuffer",g={data:{vertexBuffers:{},indexBuffers:{}},access:{vertexStreams:{},primitiveStreams:{}},semantic:{bindings:{},chunks:{}},logic:{parts:{}}},h={vertexStreams:{},primitiveStreams:{}};g.semantic.bindings[b]=h;var i={techniques:{common:{binding:b}}};g.semantic.chunks[c]=i;var j={chunks:[c]};g.logic.parts[d]=j;var k=-1,l=!1,m=!1;for(var n in a.vertices){var o=a.vertices[n];if(o){(SpiderGL.Type.isArray(o)||SpiderGL.Type.isTypedArray(o)||SpiderGL.Type.instanceOf(o,ArrayBuffer))&&(o={data:o});var p=SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP[n],q=null;p?q=p.semantic:(p=SpiderGL.Model.Model.DEFAULT_SIMPLE_MODEL_VERTEX_MAP.user,q=n.toUpperCase());var r=SpiderGL.Utility.getDefaultObject({size:p.size,type:p.type,normalized:p.normalized,semantic:q,index:p.index,data:null,value:p.value.slice()},o),s={buffer:null,size:r.size,type:r.type,normalized:r.normalized,stride:0,offset:0,value:r.value.slice()};if(r.data){var t={type:r.type},u=0;if(SpiderGL.Type.isArray(r.data))t.untypedArray=r.data,u=t.untypedArray.length/s.size;else{if(!SpiderGL.Type.isTypedArray(o)&&!SpiderGL.Type.instanceOf(o,ArrayBuffer))continue;t.typedArray=r.data,u=(t.typedArray.byteLength-s.offset)/(s.size*SpiderGL.Type.typeSize(s.type))}u=SpiderGL.Math.floor(u),l=!0,k=k>=0?SpiderGL.Math.min(k,u):u;var v=n+e;g.data.vertexBuffers[v]=t,s.buffer=v}else m=!0;var w=n;g.access.vertexStreams[w]=s;var x=new Array(r.index+1);x[r.index]=w,h.vertexStreams[r.semantic]=x}}var y=0;l?y=k:m&&(y=1);var z=a.primitives;if(SpiderGL.Type.isString(z)&&(z=[z]),SpiderGL.Type.isArray(z)){var A=z;z={};for(var B=0,C=A.length;B=0?p.count:y,semantic:p.semantic},o),s={buffer:null,mode:r.mode,first:0,count:r.count,type:r.type,offset:0};if(r.data){var t={type:r.type},u=0;if(SpiderGL.Type.isArray(r.data))t.untypedArray=r.data,u=t.untypedArray.length;else{if(!SpiderGL.Type.isTypedArray(o)&&!SpiderGL.Type.instanceOf(o,ArrayBuffer))continue;t.typedArray=r.data,u=(t.typedArray.byteLength-s.offset)/SpiderGL.Type.typeSize(s.type)}u=SpiderGL.Math.floor(u);var v=n+f;g.data.indexBuffers[v]=t,s.buffer=v,s.count=u}var w=n;g.access.primitiveStreams[w]=s;var x=new Array(1);x[0]=w,h.primitiveStreams[r.semantic]=x}}return g},SpiderGL.Model.Model.prototype={get descriptor(){return this._descriptor},get isReady(){return!!this._descriptor},get gl(){return this._gl},get renderData(){return this._renderData},updateTypedArrays:function(){var a=this._descriptor;if(!a)return!1;var b=null,c=null,d=a.data.vertexBuffers;for(var e in d)b=d[e],b.untypedArray&&(c=SpiderGL.Type.typeToTypedArrayConstructor(b.type),b.typedArray=new c(b.untypedArray));var f=a.data.indexBuffers;for(var e in f)b=f[e],b.untypedArray&&(c=SpiderGL.Type.typeToTypedArrayConstructor(b.type),b.typedArray=new c(b.untypedArray));return!0},updateGL:function(a,b){if(!a)return!1;var c=this._descriptor;if(!c)return!1;this._gl=a;var d=null,f=null,g=SpiderGL.Utility.getDefaultObject({data:null,usage:SpiderGL.Core.DEFAULT},b);g.data=null;for(var h in c.data.vertexBuffers)d=c.data.vertexBuffers[h],g.data=d.typedArray,g.data||(f=SpiderGL.Type.typeToTypedArrayConstructor(d.type),g.data=new f(d.untypedArray)),d.glBuffer&&(d.glBuffer.destroy(),d.glBuffer=null),d.glBuffer=new SpiderGL.WebGL.VertexBuffer(a,g);for(var h in c.data.indexBuffers)d=c.data.indexBuffers[h],g.data=d.typedArray,g.data||(f=SpiderGL.Type.typeToTypedArrayConstructor(d.type),g.data=new f(d.untypedArray)),d.glBuffer&&(d.glBuffer.destroy(),d.glBuffer=null),d.glBuffer=new SpiderGL.WebGL.IndexBuffer(a,g);var i=null;for(var h in c.access.vertexStreams)i=c.access.vertexStreams[h],i.glType=SpiderGL.Type.typeToGL(i.type);for(var h in c.access.primitiveStreams)i=c.access.primitiveStreams[h],i.glMode=SpiderGL.Type.primitiveToGL(i.mode),i.glType=SpiderGL.Type.typeToGL(i.type);return!0},destroyGL:function(){var a=this._descriptor;if(!a)return!1;var b=null;for(var c in a.data.vertexBuffers)b=a.data.vertexBuffers[c],b.glBuffer&&(b.glBuffer.destroy(),b.glBuffer=null);for(var c in a.data.indexBuffers)b=a.data.indexBuffers[c],b.glBuffer&&(b.glBuffer.destroy(),b.glBuffer=null)},updateRenderData:function(){var a=this._descriptor;if(!a)return!1;var b={partMap:{}};for(var c in a.logic.parts){var d=a.logic.parts[c],e=d.chunks,f={};b.partMap[c]=f;for(var g=0,h=e.length;g=0;--k){var l=h.charAt(k);if(c.indexOf(l,0)==-1){i=h.substring(0,k+1);break}j=l+j}var m=j.length>0?parseInt(j):0,n=i.length;if(n>=2&&"a"==i.charAt(0)){var l=i.charAt(1);"_"==l&&n>2?i=i.substring(2):l==i.charAt(1).toUpperCase()&&(i=i.substring(1))}var o=i.toUpperCase();e[h]={semantic:o,index:m,value:[0,0,0,1]}}var p={};for(var q in b){var r=e[q];if(r){var s=b[q];SpiderGL.Type.isString(s)?s={semantic:s}:SpiderGL.Type.isArray(s)||SpiderGL.Type.isTypedArray(s)?s={value:s}:SpiderGL.Type.isNumber(s)&&(s={value:[s,s,s,s]}),p[q]=SpiderGL.Utility.getDefaultObject({semantic:r.semantic,index:r.index,value:r.value},s)}}return b=SpiderGL.Utility.getDefaultObject(e,p)},SpiderGL.Model.Technique._fixGlobals=function(a,b){var c=a.getUniformsValues(),d={};for(var e in c){var f=e,g=f.length;if(g>=2&&"u"==f.charAt(0)){var h=f.charAt(1);"_"==h&&g>2?f=f.substring(2):h==f.charAt(1).toUpperCase()&&(f=f.substring(1))}var i=f.toUpperCase();d[e]={semantic:i,value:c[e]}}return b=SpiderGL.Utility.getDefaultObject(d,b)},SpiderGL.Model.Technique._createSimpleDescriptor=function(a,b){b=SpiderGL.Utility.getDefaultObject({name:"common",vertexShader:null,fragmentShader:null,attributes:null,uniforms:null,semantic:{},vertexStreams:null,globals:null,options:null},b),b.vertexStreams&&(b.semantic.vertexStreams=b.vertexStreams,delete b.vertexStreams),b.globals&&(b.semantic.globals=b.globals,delete b.globals);var c={name:b.name,program:null,semantic:b.semantic};if(!a)return c;var d=b.vertexShader,e=b.fragmentShader;if(!d||!e)return c;if(SpiderGL.Type.isString(d))d=new SpiderGL.WebGL.VertexShader(a,d);else if(!SpiderGL.Type.instanceOf(d,SpiderGL.WebGL.VertexShader))return c;if(SpiderGL.Type.isString(e))e=new SpiderGL.WebGL.FragmentShader(a,e);else if(!SpiderGL.Type.instanceOf(e,SpiderGL.WebGL.FragmentShader))return c;var f=new SpiderGL.WebGL.Program(a,{shaders:[d,e],attributes:b.attributes,uniforms:b.uniforms});return c.program=f,c},SpiderGL.Model.Technique.prototype={get descriptor(){return this._descriptor},get isReady(){return!!this._descriptor},get gl(){return this._gl},get name(){return this._descriptor.name},get renderData(){return this._renderData},get program(){return this._descriptor.program},setUniforms:function(a){this._descriptor.program.setUniforms(a)},updateRenderData:function(){var a=this._descriptor,b={};this._renderData=b;var c={};b.attributesMap=c;var d=a.program.getAttributesIndices();for(var e in a.semantic.vertexStreams){var f=a.semantic.vertexStreams[e],g=f.semantic,h=c[g];h||(h=[],c[g]=h),h[f.index]={index:d[e],value:f.value}}var i={};b.globalsMap=i;for(var j in a.semantic.globals){var f=a.semantic.globals[j];i[f.semantic]={name:j,value:f.value}}}},SpiderGL.Model.ModelRenderer=function(a){this._gl=a,this._vertexAttributesCount=a.getParameter(a.MAX_VERTEX_ATTRIBS),this._textureUnitsCount=a.getParameter(a.MAX_TEXTURE_IMAGE_UNITS),this._internalFramebuffer=new SpiderGL.WebGL.Framebuffer(a),this._reset()},SpiderGL.Model.ModelRenderer.prototype={_reset:function(){this._technique=null,this._model=null,this._partName=null,this._chunkName=null,this._primMode=null,this._framebuffer=null,this._inBegin=!1,this._enabledArrays=[],this._boundTextures=[],this._attribValues=[],this._primitiveStreams=[],this._techniqueDirty=!0,this._modelDirty=!0,this._modelPartDirty=!0,this._modelChunkDirty=!0,this._primModeDirty=!0,this._framebufferDirty=!0,this._viewportDirty=!0,this._dirty=!0},_resetContext:function(){for(var a=this._gl,b=0,c=this._vertexAttributesCount;b=0;--b)a.activeTexture(a.TEXTURE0+b),a.bindTexture(a.TEXTURE_2D,null),a.bindTexture(a.TEXTURE_CUBE_MAP,null);SpiderGL.WebGL.VertexBuffer.unbind(a),SpiderGL.WebGL.IndexBuffer.unbind(a),SpiderGL.WebGL.Program.unbind(a),SpiderGL.WebGL.Framebuffer.unbind(a)},_update:function(){if(!this._dirty)return!0;var a=this._gl;if(this._techniqueDirty){var b=this._technique;if(!b)return!1;var c=b.renderData,d=c.attributesMap,e=[];for(var f in d){var g=d[f];for(var h in g){var i=g[h],j=null;i&&(j={index:i.index,value:i.value}),e.push(j)}}this._attribValues=e,b.program.bind(),this._techniqueDirty=!1}if(this._modelDirty){var k=this._model;if(!k)return!1;for(var e=this._attribValues,h=0,l=e.length;h-1?(b=SpiderGL.UserInterface.CanvasHandler._multiTouch.touches,c=b[0]):(b=a.touches,c=a.changedTouches[0]),a.type){case"touchstart":case"pointerdown":f="mousedown";break;case"touchmove":case"pointermove":f="mousemove";break;case"touchend":case"pointerup":f="mouseup";break;default:return}var g=document.createEvent("MouseEvent");if(b.length>=2){if(navigator.userAgent.toLowerCase().indexOf("trident")<=-1&&("draw-canvas"!=b[0].target.id||"draw-canvas"!=b[1].target.id))return;var h=Math.sqrt(Math.pow(b[0].clientX-b[1].clientX,2)+Math.pow(b[0].clientY-b[1].clientY,2));if(d=h-SpiderGL.UserInterface.CanvasHandler._multiTouch.tmp,SpiderGL.UserInterface.CanvasHandler._multiTouch.tmp=h,"pointerup"==a.type)e=SpiderGL.UserInterface.CanvasHandler._multiTouch.btn,f="mousedown";else{if(!(d<-.995||d>.995))return;d=d>0?1:-1,f="mousewheel"}}else{if(!("pointerup"!=a.type&&"pointermove"!=a.type||c&&a.pointerId==c.pointerId))return;if(0!=SpiderGL.UserInterface.CanvasHandler._multiTouch.tmp&&"touchend"==a.type&&(e=SpiderGL.UserInterface.CanvasHandler._multiTouch.btn,f="mousedown"),"mousedown"==f)SpiderGL.UserInterface.CanvasHandler._multiTouch.evt=a;else if("mouseup"==f)SpiderGL.UserInterface.CanvasHandler._multiTouch.pan&&(e=1,SpiderGL.UserInterface.CanvasHandler._multiTouch.pan=!1,SpiderGL.UserInterface.CanvasHandler._multiTouch.phase=0,navigator.userAgent.toLowerCase().indexOf("firefox")>-1&&SpiderGL.UserInterface.CanvasHandler._touchHandler(a));else if("mousemove"==f)if(SpiderGL.UserInterface.CanvasHandler._multiTouch.pan)switch(SpiderGL.UserInterface.CanvasHandler._multiTouch.phase){case 0:d=-1,f=navigator.userAgent.toLowerCase().indexOf("firefox")>-1?"mousemove":"mouseup",SpiderGL.UserInterface.CanvasHandler._multiTouch.phase++;break;case 1:e=1,f="mousedown",SpiderGL.UserInterface.CanvasHandler._multiTouch.phase++;break;default:e=1}else{var j;j=navigator.userAgent.toLowerCase().indexOf("trident")>-1?SpiderGL.UserInterface.CanvasHandler._multiTouch.evt:SpiderGL.UserInterface.CanvasHandler._multiTouch.evt.touches[0],Math.sqrt(Math.pow(c.clientX-j.clientX,2)+Math.pow(c.clientY-j.clientY,2))<=2&&a.timeStamp-SpiderGL.UserInterface.CanvasHandler._multiTouch.evt.timeStamp>400&&(SpiderGL.UserInterface.CanvasHandler._multiTouch.pan=!0)}SpiderGL.UserInterface.CanvasHandler._multiTouch.tmp=0,SpiderGL.UserInterface.CanvasHandler._multiTouch.btn=e}if(c&&(g.initMouseEvent(f,!0,!0,window,d,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,e,null),c.target.dispatchEvent(g)),"pointerup"==a.type)for(i=0;i=a.pointerId&&(i+1==SpiderGL.UserInterface.CanvasHandler._multiTouch.touches.length?SpiderGL.UserInterface.CanvasHandler._multiTouch.touches.pop():SpiderGL.UserInterface.CanvasHandler._multiTouch.touches[i]=SpiderGL.UserInterface.CanvasHandler._multiTouch.touches[i+1]);a.preventDefault(),a.stopPropagation()},SpiderGL.UserInterface.CanvasHandler.prototype={_firstNotify:function(){this._onInitialize(),this._animateRate>0&&this._onAnimate(),this.postDrawEvent()},_dispatch:function(){var a=arguments[0],b=this._handler,c=b[a];if(c){var d=Array.prototype.slice.call(arguments,1);c.apply(b,d)}},_postDrawEvent:function(){this._postDrawCount=5,this._drawEventPending||(this._drawEventPending=!0,requestAnimationFrame(this._delegateDraw))},_getMouseClientPos:function(a){var b=this._canvas.getBoundingClientRect(),c=this._canvas.width,d=this._canvas.height,e=a.clientX-b.left,f=d-(a.clientY-b.top),g=e<0||e>=c||f<0||f>=d;return[e,f,g]},_onInitialize:function(){this._dispatch("onInitialize")},_onTerminate:function(){this._dispatch("onTerminate")},_onBlur:function(a){var c=(this._gl,this._keysDown);for(var d in c)c[d]&&(c[d]=!1,this._dispatch("onKeyUp",d,null))},_onKeyDown:function(a){var b=a.keyCode;if(b>=48&&b<=90){var c=String.fromCharCode(b);b=c.toUpperCase()}var d=this._keysDown[b];this._keysDown[b]=!0,d&&this._ignoreKeyRepeat||this._dispatch("onKeyDown",b,a)},_onKeyUp:function(a){var b=a.keyCode;if(b>=48&&b<=90){var c=String.fromCharCode(b);b=c.toUpperCase()}this._keysDown[b]=!1,this._dispatch("onKeyUp",b,a)},_onKeyPress:function(a){var b=a.keyCode;if(b>=48&&b<=90){var c=String.fromCharCode(b);b=c.toUpperCase()}this._dispatch("onKeyPress",b,a)},_onMouseButtonDown:function(a){this._canvas.focus();var b=this._getMouseClientPos(a);this._cursorPos=b;var c=a.button;this._mouseButtonsDown[c]=!0,this._dragStartPos[c]=[b[0],b[1]],this._dispatch("onMouseButtonDown",c,b[0],b[1],a),a.stopPropagation()},_onMouseButtonUp:function(a){var b=this._getMouseClientPos(a);this._cursorPos=b;var c=a.button;if(this._mouseButtonsDown[c]=!1,!(navigator.userAgent.toLowerCase().indexOf("firefox")>-1)||a.isTrusted){if(this._dispatch("onMouseButtonUp",c,b[0],b[1],a),this._dragging[c]){this._dragging[c]=!1;var d=this._dragStartPos[c],e=[b[0],b[1]];this._dragEndPos[c]=e,this._dragDeltaPos[c]=[e[0]-d[0],e[1]-d[1]],this._dispatch("onDragEnd",c,e[0],e[1])}a.stopPropagation()}},_onWindowMouseButtonUp:function(a){var b=this._getMouseClientPos(a);this._cursorPos=b;var c=a.button;if(this._mouseButtonsDown[c]&&(this._mouseButtonsDown[c]=!1,!(navigator.userAgent.toLowerCase().indexOf("firefox")>-1)||a.isTrusted)){if(this._dispatch("onMouseButtonUp",c,b[0],b[1],a),this._dragging[c]){this._dragging[c]=!1;var d=this._dragStartPos[c],e=[b[0],b[1]];this._dragEndPos[c]=e,this._dragDeltaPos[c]=[e[0]-d[0],e[1]-d[1]],this._dispatch("onDragEnd",c,e[0],e[1])}a.stopPropagation()}},_onMouseMove:function(a){this._cursorPrevPos=this._cursorPos;var b=this._getMouseClientPos(a);this._cursorPos=b,this._cursorDeltaPos=[this._cursorPos[0]-this._cursorPrevPos[0],this._cursorPos[1]-this._cursorPrevPos[1]];for(var c=0;c<3;++c)if(this._mouseButtonsDown[c]&&(0!=this._cursorDeltaPos[0]||0!=this._cursorDeltaPos[1])){var d=this._dragStartPos[c],e=[b[0],b[1]];this._dragEndPos[c]=e,this._dragDeltaPos[c]=[e[0]-d[0],e[1]-d[1]],this._dragging[c]?this._dispatch("onDrag",c,e[0],e[1]):(this._dragging[c]=!0,this._dispatch("onDragStart",c,d[0],d[1]))}this._dispatch("onMouseMove",b[0],b[1],a),a.stopPropagation()},_onWindowMouseMove:function(a){this._cursorPrevPos=this._cursorPos;var b=this._getMouseClientPos(a);this._cursorPos=b,this._cursorDeltaPos=[this._cursorPos[0]-this._cursorPrevPos[0],this._cursorPos[1]-this._cursorPrevPos[1]];for(var c=0;c<3;++c)if(this._dragging[c]){var d=this._dragStartPos[c],e=[b[0],b[1]];this._dragEndPos[c]=e,this._dragDeltaPos[c]=[e[0]-d[0],e[1]-d[1]],this._dispatch("onDrag",c,e[0],e[1])}b[2]||(this._dispatch("onMouseMove",b[0],b[1],a),a.stopPropagation())},_onMouseWheel:function(a){var b=this._getMouseClientPos(a),c=0;a||(a=window.event),a.wheelDelta?(c=a.wheelDelta/120,window.opera&&(c=-c)):a.detail&&(c=a.detail/3),c&&this._dispatch("onMouseWheel",c,b[0],b[1],a),a.preventDefault&&a.preventDefault(),a.stopPropagation()},_onMouseOut:function(a){var b=this._getMouseClientPos(a);this._dispatch("onMouseOut",b[0],b[1],a)},_onClick:function(a){var b=this._getMouseClientPos(a);this._dispatch("onClick",a.button,b[0],b[1],a)},_onDoubleClick:function(a){var b=this._getMouseClientPos(a);this._dispatch("onDoubleClick",a.button,b[0],b[1],a)},_onResize:function(a){this._dispatch("onResize",this._canvas.width,this._canvas.height,a)},_onAnimate:function(){this._animatePrevTime=this._animateTime,this._animateTime=Date.now(),this._animateDeltaTime=this._animateTime-this._animatePrevTime,this._dispatch("onAnimate",this._animateDeltaTime/1e3),this._animateMS>=0?this._animateWithTimeout&&setTimeout(this._animateEventHandler,this._animateMS):this._fastAnimate&&window.postMessage(SpiderGL.UserInterface.CanvasHandler._FAST_ANIMATE_MESSAGE_NAME,"*")},_onDraw:function(a){if(this._drawEventPending=!1,this._fpsTime&&5!=this.postDrawCount){this._fpsCount++;var b=a-this._fpsTime;this._fps=.8*this._fps+.2*(1e3/b)}else this._fpsCount=0;this._fpsTime=a,this._dispatch("onDraw"),this._postDrawCount-- >0&&(this._drawEventPending=!0,requestAnimationFrame(this._delegateDraw))},get gl(){return this._gl},get canvas(){return this._canvas},get width(){return this._canvas.width},get height(){return this._canvas.height},get postDrawEvent(){return this._postDrawEventFunction},get animateTime(){return this._animateTime},get animatePrevTime(){return this._animatePrevTime},get animateDeltaTime(){return this._animateDeltaTime},get animateRate(){return this._animateRate},set animateRate(a){a=SpiderGL.Utility.getDefaultValue(a,SpiderGL.UserInterface.CanvasHandler.DEFAULT_ANIMATE_RATE),this._animateRate!==a&&(this._fastAnimate=!1,this._animateMS=-1,this._animateTime=Date.now(),this._animatePrevTime=this._animateTime,this._animateDeltaTime=0,this._animateID&&(clearInterval(this._animateID),this._animateID=null),this._animateRate=a,a>0?(this._animateMS=SpiderGL.Math.floor(1e3/a),this._animateWithTimeout?setTimeout(this._animateEventHandler,this._animateMS):this._animateID=setInterval(this._animateEventHandler,this._animateMS)):a<0&&(this._fastAnimate=!0,window.postMessage(SpiderGL.UserInterface.CanvasHandler._FAST_ANIMATE_MESSAGE_NAME,"*")))},get framesPerSecond(){return this._fps},get ignoreKeyRepeat(){return this._ignoreKeyRepeat},set ignoreKeyRepeat(a){this._ignoreKeyRepeat=SpiderGL.Utility.getDefaultValue(a,SpiderGL.UserInterface.CanvasHandler.DEFAULT_IGNORE_KEY_REPEAT)},isKeyDown:function(a){return a.toUpperCase&&(a=a.toUpperCase()),this._keysDown[a]},isMouseButtonDown:function(a){return this._mouseButtonsDown[a]},isDragging:function(a){var b=!1;if(void 0!==a)b=this._dragging[a];else for(i=0;i<3;i++)if(this._dragging[i])return!0;return b},dragStartX:function(a){return this._dragStartPos[a][0]},dragStartY:function(a){return this._dragStartPos[a][1]},dragEndX:function(a){return this._dragEndPos[a][0]},dragEndY:function(a){return this._dragEndPos[a][1]},dragDeltaX:function(a){return this._dragDeltaPos[a][0]},dragDeltaY:function(a){return this._dragDeltaPos[a][1]},get cursorX(){return this._cursorPos[0]},get cursorY(){return this._cursorPos[1]},get cursorPrevX(){return this._cursorPrevPos[0]},get cursorPrevY(){return this._cursorPrevPos[1]},get cursorDeltaX(){return this._cursorDeltaPos[0]},get cursorDeltaY(){return this._cursorDeltaPos[1]},draw:function(){this._onDraw()}},SpiderGL.Type.extend(SpiderGL.UserInterface.CanvasHandler,SpiderGL.Core.ObjectBase),SpiderGL.UserInterface.handleCanvas=function(a,b,c){if(!a||!b)return!1;c=c||{};var d=SpiderGL.WebGL.Context.getHijacked(a,c);if(!d)return!1;var e=new SpiderGL.UserInterface.CanvasHandler(d,b,c);if(!e)return!1;var f=SpiderGL.Utility.getDefaultValue(c.uiName,SpiderGL.UserInterface.CanvasHandler.DEFAULT_PROPERTY_NAME);return b[f]=e,e._firstNotify(),!0},SpiderGL.UserInterface.handleCanvasOnLoad=function(a,b,c){function e(){SpiderGL.UserInterface.handleCanvas(a,b,c),d&&d()}if(!a||!b)return!1;c=c||{};var d=SpiderGL.Utility.getDefaultValue(c.onLoad,null);return window.addEventListener("load",e,!1),!0};
\ No newline at end of file
diff --git a/all_tools/js/trackball_pantilt.js b/all_tools/js/trackball_pantilt.js
deleted file mode 100644
index b0bd74d..0000000
--- a/all_tools/js/trackball_pantilt.js
+++ /dev/null
@@ -1,332 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/**
- * Constructs a PanTiltTrackball object.
- * @class Interactor which implements a pan-tilt trackball controller with bounds.
- */
-function PanTiltTrackball() {
-}
-
-PanTiltTrackball.prototype = {
-
- setup : function (options) {
- options = options || {};
- var opt = sglGetDefaultObject({
- startCenter : [ 0.0, 0.0, 0.0 ],
- startPanX : 0.0,
- startPanY : 0.0,
- startAngleX : 0.0,
- startAngleY : 0.0,
- startDistance : 2.0,
- minMaxDist : [0.2, 4.0],
- minMaxPanX : [-0.7, 0.7],
- minMaxPanY : [-0.7, 0.7],
- minMaxAngleX : [-70.0, 70.0],
- minMaxAngleY : [-70.0, 70.0],
- }, options);
-
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
-
- this._matrix = SglMat4.identity();
-
- // trackball center
- this._center = opt.startCenter;
-
- // starting/default parameters
- this._startPanX = opt.startPanX; //pan X
- this._startPanY = opt.startPanY; //pan Y
- this._startAngleX = sglDegToRad(opt.startAngleX); //angle X
- this._startAngleY = sglDegToRad(opt.startAngleY); //angle Y
- this._startDistance = opt.startDistance; //distance
-
- // current parameters
- this._panX = this._startPanX;
- this._panY = this._startPanY;
- this._angleX = this._startAngleX;
- this._angleY = this._startAngleY;
- this._distance = this._startDistance;
-
- // target paramenters
- this._targetPanX = this._startPanX;
- this._targetPanY = this._startPanY;
- this._targetAngleX = this._startAngleX;
- this._targetAngleY = this._startAngleY;
- this._targetDistance = this._startDistance;
-
- //animation data
- this._isAnimating = false;
- this._speedPanX = 0.0;
- this._speedPanY = 0.0;
- this._speedAngleX = 0.0;
- this._speedAngleY = 0.0;
- this._speedDistance = 0.0;
-
- //limits
- this._minMaxDist = opt.minMaxDist;
- this._minMaxPanX = opt.minMaxPanX;
- this._minMaxPanY = opt.minMaxPanY;
- this._minMaxAngleX = opt.minMaxAngleX;
- this._minMaxAngleX[0] = sglDegToRad(this._minMaxAngleX[0]);
- this._minMaxAngleX[1] = sglDegToRad(this._minMaxAngleX[1]);
- this._minMaxAngleY = opt.minMaxAngleY;
- this._minMaxAngleY[0] = sglDegToRad(this._minMaxAngleY[0]);
- this._minMaxAngleY[1] = sglDegToRad(this._minMaxAngleY[1]);
-
- this._start = [0.0, 0.0];
- this.reset();
- },
-
- clamp: function(value, low, high) {
- if(value < low) return low;
- if(value > high) return high;
- return value;
- },
-
- _computeMatrix: function() {
- var m = SglMat4.identity();
-
- // centering
- m = SglMat4.mul(m, SglMat4.translation([-this._center[0], -this._center[1], -this._center[2]]));
- // zoom
- m = SglMat4.mul(m, SglMat4.translation([0.0, 0.0, -this._distance]));
- // tilt
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._angleY, [1.0, 0.0, 0.0]));
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._angleX, [0.0, -1.0, 0.0]));
- // pan
- m = SglMat4.mul(m, SglMat4.translation([this._panX, this._panY, 0.0]));
-
- this._matrix = m;
-
- if(typeof onTrackballUpdate != "undefined")
- onTrackballUpdate(this.getState());
- },
-
- getState : function () {
- return [this._panX, this._panY, sglRadToDeg(this._angleX), sglRadToDeg(this._angleY), this._distance];
- },
-
- setState : function (newstate) {
- this._panX = newstate[0];
- this._panY = newstate[1];
- this._angleX = sglDegToRad(newstate[2]);
- this._angleY = sglDegToRad(newstate[3]);
- this._distance = newstate[4];
-
- //check limits
- this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._panY = this.clamp(this._panY, this._minMaxPanY[0], this._minMaxPanY[1]);
- this._angleX = this.clamp(this._angleX, this._minMaxAngleX[0], this._minMaxAngleX[1]);
- this._angleY = this.clamp(this._angleY, this._minMaxAngleY[0], this._minMaxAngleY[1]);
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
-
- this._computeMatrix();
- },
-
- animateToState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._targetPanX = newstate[0];
- this._targetPanY = newstate[1];
- this._targetAngleX = sglDegToRad(newstate[2]);
- this._targetAngleY = sglDegToRad(newstate[3]);
- this._targetDistance = newstate[4];
-
- //check limits
- this._targetPanX = this.clamp(this._targetPanX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._targetPanY = this.clamp(this._targetPanY, this._minMaxPanY[0], this._minMaxPanY[1]);
- this._targetAngleX = this.clamp(this._targetAngleX, this._minMaxAngleX[0], this._minMaxAngleX[1]);
- this._targetAngleY = this.clamp(this._targetAngleY, this._minMaxAngleY[0], this._minMaxAngleY[1]);
- this._targetDistance = this.clamp(this._targetDistance, this._minMaxDist[0], this._minMaxDist[1]);
-
- // setting base velocities
- this._speedPanX = 2.0;
- this._speedPanY = 2.0;
- this._speedAngleX = Math.PI;
- this._speedAngleY = Math.PI;
- this._speedDistance = 2.0;
-
- // find max animation time to set a time limit and then synchronize all movements
- var timePanX = Math.abs((this._targetPanX - this._panX) / this._speedPanX);
- var timePanY = Math.abs((this._targetPanY - this._panY) / this._speedPanY);
- var timeAngleX = Math.abs((this._targetAngleX - this._angleX) / this._speedAngleX);
- var timeAngleY = Math.abs((this._targetAngleY - this._angleY) / this._speedAngleY);
- var timeDistance = Math.abs((this._targetDistance - this._distance) / this._speedDistance);
-
- var maxtime = Math.max( timePanX, Math.max( timePanY, Math.max( timeAngleX, Math.max( timeAngleY, timeDistance ) ) ));
- maxtime = this.clamp(maxtime, 0.5, 2.0);
-
- this._speedPanX *= timePanX / maxtime;
- this._speedPanY *= timePanY / maxtime;
- this._speedAngleX *= timeAngleX / maxtime;
- this._speedAngleY *= timeAngleY / maxtime;
- this._speedDistance *= timeDistance / maxtime;
-
- // start animation
- this._isAnimating = true;
- },
-
- recenter : function (newpoint) {
- // stop animation
- this._isAnimating = false;
-
- var newpanX = -(newpoint[0]-presenter.sceneCenter[0]) * presenter.sceneRadiusInv;
- var newpanY = -(newpoint[1]-presenter.sceneCenter[1]) * presenter.sceneRadiusInv;
-
- this.animateToState([newpanX, newpanY, sglRadToDeg(this._angleX), sglRadToDeg(this._angleY), (this._distance * 0.8)]);
- },
-
- tick : function (dt) {
- if(!this._isAnimating) return false;
-
- var deltaPanX = this._speedPanX * dt;
- var deltaPanY = this._speedPanY * dt;
- var deltaAngleX = this._speedAngleX * dt;
- var deltaAngleY = this._speedAngleY * dt;
- var deltaDistance = this._speedDistance * dt;
-
- var diffPanX = this._targetPanX - this._panX;
- var diffPanY = this._targetPanY - this._panY;
- var diffAngleX = this._targetAngleX - this._angleX;
- var diffAngleY = this._targetAngleY - this._angleY;
- var diffDistance = this._targetDistance - this._distance;
-
- if (diffPanX > deltaPanX)
- this._panX += deltaPanX;
- else if (diffPanX < -deltaPanX)
- this._panX -= deltaPanX;
- else
- this._panX = this._targetPanX;
-
- if (diffPanY > deltaPanY)
- this._panY += deltaPanY;
- else if (diffPanY < -deltaPanY)
- this._panY -= deltaPanY;
- else
- this._panY = this._targetPanY;
-
- if (diffAngleX > deltaAngleX)
- this._angleX += deltaAngleX;
- else if (diffAngleX < -deltaAngleX)
- this._angleX -= deltaAngleX;
- else
- this._angleX = this._targetAngleX;
-
- if (diffAngleY > deltaAngleY)
- this._angleY += deltaAngleY;
- else if (diffAngleY < -deltaAngleY)
- this._angleY -= deltaAngleY;
- else
- this._angleY = this._targetAngleY;
-
- if (diffDistance > deltaDistance)
- this._distance += deltaDistance;
- else if (diffDistance < -deltaDistance)
- this._distance -= deltaDistance;
- else
- this._distance = this._targetDistance;
-
- if(this._panX == this._targetPanX)
- if(this._panX == this._targetPanX)
- if(this._angleX == this._targetAngleX)
- if(this._angleY == this._targetAngleY)
- if(this._distance == this._targetDistance)
- this._isAnimating = false;
-
- this._computeMatrix();
- return true;
- },
-
- get action() { return this._action; },
-
- set action(a) { if(this._action != a) this._new_action = true; this._action = a; },
-
- get matrix() { return this._matrix; },
-
- get distance() { return this._distance; },
-
- reset : function () {
- this._matrix = SglMat4.identity();
- this._action = SGL_TRACKBALL_NO_ACTION
-
- this._panX = this._startPanX;
- this._panY = this._startPanY;
- this._angleX = this._startAngleX;
- this._angleY = this._startAngleY;
- this._distance = this._startDistance;
-
- this._isAnimating = false;
- },
-
- track : function(m, x, y, z) {
- if(this._new_action) {
- this._start[0] = x;
- this._start[1] = y;
- this._new_action = false;
- }
-
- var dx = this._start[0] - x;
- var dy = this._start[1] - y;
- this._start[0] = x;
- this._start[1] = y;
-
- switch (this._action) {
- case SGL_TRACKBALL_ROTATE:
- this._isAnimating = false; //stopping animation
- this.rotate(m, dx, dy);
- break;
-
- case SGL_TRACKBALL_PAN:
- this._isAnimating = false; //stopping animation
- this.pan(m, dx, dy);
- break;
-
- case SGL_TRACKBALL_SCALE:
- this._isAnimating = false; //stopping animation
- this.scale(m, z);
- break;
-
- default:
- break;
- }
- return this._computeMatrix();
- },
-
- rotate: function(m, dx, dy) {
- this._angleX += dx;
- this._angleY += dy;
- this._angleX = this.clamp(this._angleX, this._minMaxAngleX[0], this._minMaxAngleX[1]);
- this._angleY = this.clamp(this._angleY, this._minMaxAngleY[0], this._minMaxAngleY[1]);
- },
-
- pan: function(m, dx, dy) {
- this._panX -= dx/2.0;
- this._panY -= dy/2.0;
- this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._panY = this.clamp(this._panY, this._minMaxPanY[0], this._minMaxPanY[1]);
- },
-
- scale : function(m, s) {
- this._distance *= s;
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- }
-};
-/***********************************************************************/
diff --git a/all_tools/js/trackball_rail.js b/all_tools/js/trackball_rail.js
deleted file mode 100644
index 721cca5..0000000
--- a/all_tools/js/trackball_rail.js
+++ /dev/null
@@ -1,534 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/**
- * Constructs a RailTrackball object.
- * @class Interactor which implements a rail-bound path controller.
- */
-function RailTrackball() {
-}
-
-RailTrackball.prototype = {
-
- setup : function (options) {
- options = options || {};
- var opt = sglGetDefaultObject({
- startPhi : 0.0,
- startTheta : 0.0,
- startOffset : 0.0,
- minMaxTheta : [-80.0, 80.0],
- pathPoints : [ [0.0, 0.0, 0.0] ],
- pathCircular : false,
- pathLocked : false,
- useSpaceTransform : true,
- stepLength : 0.01,
- lapTime : 60.0,
- }, options);
-
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
- this._matrix = SglMat4.identity();
-
- // path
- this._pathPoints = opt.pathPoints;
- this._pathCircular = opt.pathCircular;
- this._pathLocked = opt.pathLocked;
- this._useSpaceTransform = opt.useSpaceTransform;
- this._createPath();
- this._stepLength = opt.stepLength;
-
- // starting/default parameters
- this._startPhi = sglDegToRad(opt.startPhi); //phi (horizontal rotation)
- this._startTheta = sglDegToRad(opt.startTheta); //theta (vertical rotation)
- this._startDistance = 0.0;
- this._startOffset = opt.startOffset;
- if(this._startOffset < 0.0) this._startOffset = 0.0;
- if(this._startOffset > 1.0) this._startOffset = 1.0;
-
- // current parameters
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._distance = this._startDistance;
- this._pathOffset = this._startOffset;
-
- // target paramenters
- this._targetPhi = this._startPhi;
- this._targetTheta = this._startTheta;
- this._targetOffset = this._startOffset;
-
- //animation data
- this._isAnimating = false;
- this._speedPhi = 0.0;
- this._speedTheta = 0.0;
- this._speedOffset = 0.0;
- this._isAutoWalking = false;
- this._hasToGoLap = false;
- this._lapTime = opt.lapTime;
-
- // limits
- this._minMaxTheta = opt.minMaxTheta;
- this._minMaxTheta[0] = sglDegToRad(this._minMaxTheta[0]);
- this._minMaxTheta[1] = sglDegToRad(this._minMaxTheta[1]);
-
- // scene center/radius
- this._sceneRadiusInv = presenter.sceneRadiusInv;
- this._sceneCenter = presenter.sceneCenter;
-
- this._start = [0.0, 0.0];
- this.reset();
- },
-
- _createPath: function() {
- // if circular, add at the end of points a copy of the first one
- if(this._pathCircular)
- {
- this._pathPoints[this._pathPoints.length] = this._pathPoints[0];
- }
-
- this._pathPosNum = this._pathPoints.length;
- this._pathLen = 0.0;
-
- var pp = 1;
-
- // vector with base offset for each path point
- this._pathBaseOffs = [];
- this._pathBaseOffs[0] = 0.0;
-
- while(pp 1.0)
- if(this._pathCircular)
- this._pathOffset -= 1.0;
- else
- this._pathOffset = 1.0;
-
- this._computeMatrix();
- },
-
- stepBW: function() {
- this._pathOffset -= this._stepLength;
- if(this._pathOffset < 0.0)
- if(this._pathCircular)
- this._pathOffset += 1.0;
- else
- this._pathOffset = 0.0;
-
- this._computeMatrix();
- },
-
- clamp: function(value, low, high) {
- if(value < low) return low;
- if(value > high) return high;
- return value;
- },
-
- _computeMatrix: function() {
- var m = SglMat4.identity();
-
- // update currposition
- this._currPosition = this._computeCurrPoint();
- // zoom
- m = SglMat4.mul(m, SglMat4.translation([0.0, 0.0, -this._distance]));
- // rotation
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]));
- // tilt
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]));
- // centering
- m = SglMat4.mul(m, SglMat4.translation([-this._currPosition[0], -this._currPosition[1], -this._currPosition[2]]));
-
- this._matrix = m;
-
- if(typeof onTrackballUpdate != "undefined")
- onTrackballUpdate(this.getState());
- },
-
- getState : function () {
- return [sglRadToDeg(this._phi), sglRadToDeg(this._theta), this._pathOffset];
- },
-
- setState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._phi = sglDegToRad(newstate[0]);
- this._theta = sglDegToRad(newstate[1]);
- this._pathOffset = newstate[2];
-
- // avoid eternal accumulation of rotation, just for the sake of cleanliness
- if (this._phi > 20.0) this._phi = this._phi - 20.0;
- if (this._phi < -20.0) this._phi = this._phi + 20.0;
- //check limits
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- this._pathOffset = this._pathOffset % 1.0;
- if(this._pathOffset < 0.0) this._pathOffset = 1.0 - this._pathOffset;
-
- this._computeMatrix();
- },
-
- animateToState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- if(newstate)
- {
- this._isAutoWalking = false;
- this._targetPhi = sglDegToRad(newstate[0]);
- this._targetTheta = sglDegToRad(newstate[1]);
- this._targetOffset = newstate[2];
-
- //check limits
- this._targetTheta = this.clamp(this._targetTheta, this._minMaxTheta[0], this._minMaxTheta[1]);
- if(this._targetOffset < 0.0) this._targetOffset = 0.0;
- if(this._targetOffset > 1.0) this._targetOffset = 1.0;
-
- // setting base velocities
- this._speedPhi = Math.PI;
- this._speedTheta = Math.PI;
- this._speedOffset = 1.0/60.0;
-
- // clamp target phi angle
- while(this._targetPhi > 2*Math.PI)
- this._targetPhi -= 2*Math.PI;
- while(this._targetPhi < 0)
- this._targetPhi += 2*Math.PI;
-
- // clamp current phi angle, to prevent endless unwinding
- while(this._phi > 2*Math.PI)
- this._phi -= 2*Math.PI;
- while(this._phi < 0)
- this._phi += 2*Math.PI;
-
- // determine minimal, clamped target phi angle
- var clampedangle = this._targetPhi;
- while(clampedangle > 2*Math.PI)
- clampedangle -= 2*Math.PI;
- while(clampedangle < 0)
- clampedangle += 2*Math.PI;
-
- if(Math.abs(clampedangle - this._phi) < Math.PI) { // standard rotation
- if(clampedangle > this._phi){
- this.speedphi = Math.PI;
- }
- else{
- this.speedphi = -Math.PI;
- }
- }
- else{
- if(clampedangle > this._phi){
- clampedangle = (clampedangle - 2*Math.PI)
- this.speedphi = -Math.PI;
- }
- else{
- clampedangle = (clampedangle + 2*Math.PI)
- this.speedphi = Math.PI;
- }
- }
-
- this._targetPhi = clampedangle;
-
- // determine sign of offset motion
- var offdist = 0.0;
- if(this._pathCircular)
- {
- this._pathOffset = this._pathOffset % 1.0;
- if(this._pathOffset < 0.0) this._pathOffset = 1.0 - this._pathOffset;
-
- if(this._targetOffset >= this._pathOffset)
- {
- // if more than half path, reverse direction
- if((this._targetOffset - this._pathOffset)<=0.5)
- {
- this._speedOffset = 1.0/30.0;
- this._hasToGoLap = false;
- offdist = this._targetOffset - this._pathOffset;
- }
- else
- {
- this._speedOffset = -1.0/30.0;
- this._hasToGoLap = true;
- offdist = this._pathOffset + (1.0 - this._targetOffset);
- }
- }
- else
- {
- // if more than half path, reverse direction
- if((this._pathOffset - this._targetOffset)<=0.5)
- {
- this._speedOffset = -1.0/30.0;
- this._hasToGoLap = false;
- offdist = this._pathOffset - this._targetOffset;
- }
- else
- {
- this._speedOffset = 1.0/30.0;
- this._hasToGoLap = true;
- offdist = this._targetOffset + (1.0 - this._pathOffset);
- }
- }
- }
- else
- {
- offdist = this._targetOffset - this._pathOffset;
- this._hasToGoLap = false;
- if(this._targetOffset >= this._pathOffset)
- this._speedOffset = 1.0/30.0;
- else
- this._speedOffset = -1.0/30.0;
- }
-
- // theta direction
- if(this._targetTheta > this._theta)
- this.speedTheta = Math.PI;
- else
- this.speedTheta = -Math.PI;
-
- // find max animation time to set a time limit and then synchronize all movements
- var timePhi = Math.abs((this._targetPhi - this._phi) / this._speedPhi);
- var timeTheta = Math.abs((this._targetTheta - this._theta) / this._speedTheta);
- var timeOffset = Math.abs(offdist / this._speedOffset);
-
- var maxtime = Math.max( timePhi, Math.max( timeTheta, timeOffset ));
-
- maxtime = this.clamp(maxtime, 1.0, 3.0);
-
- this._speedPhi *= timePhi / maxtime;
- this._speedTheta *= timeTheta / maxtime;
- this._speedOffset *= timeOffset / maxtime;
- }
- else
- {
- this._isAutoWalking = true;
- }
-
- // start animation
- this._isAnimating = true;
- },
-
- tick : function (dt) {
- if(!this._isAnimating) return false;
-
- if(this._isAutoWalking)
- {
- this._pathOffset += (dt / this._lapTime);
- if(this._pathOffset > 1.0) {
- if(this._pathCircular)
- this._pathOffset -= 1.0;
- else
- this._pathOffset = 1.0;
- if(!this._pathCircular) this._isAutoWalking = this._isAnimating = false;
- }
- }
- else
- {
- var deltaPhi = this._speedPhi * dt / this._lapTime;
- var deltaTheta = this._speedTheta * dt / this._lapTime;
- var deltaOffset = this._speedOffset * dt / this._lapTime;
-
- var diffPhi = this._targetPhi - this._phi;
- var diffTheta = this._targetTheta - this._theta;
-
- if (diffPhi > deltaPhi)
- this._phi += deltaPhi;
- else if (diffPhi < -deltaPhi)
- this._phi -= deltaPhi;
- else
- this._phi = this._targetPhi;
-
- if (diffTheta > deltaTheta)
- this._theta += deltaTheta;
- else if (diffTheta < -deltaTheta)
- this._theta -= deltaTheta;
- else
- this._theta = this._targetTheta;
-
- if(this._hasToGoLap)
- {
- this._pathOffset = this._pathOffset + deltaOffset;
- if(this._pathOffset>1.0)
- {
- this._hasToGoLap = false;
- this._pathOffset = this._pathOffset % 1.0;
- if(this._pathOffset > this._targetOffset)
- this._pathOffset = this._targetOffset;
- }
- if(this._pathOffset<0.0)
- {
- this._hasToGoLap = false;
- this._pathOffset = this._pathOffset % 1.0;
- this._pathOffset = 1.0 - this._pathOffset;
- if(this._pathOffset < this._targetOffset)
- this._pathOffset = this._targetOffset;
- }
- }
- else
- {
- if (deltaOffset > 0.0)
- {
- if(this._pathOffset + deltaOffset > this._targetOffset)
- this._pathOffset = this._targetOffset;
- else
- this._pathOffset = this._pathOffset + deltaOffset;
- }
- else
- {
- if(this._pathOffset + deltaOffset < this._targetOffset)
- this._pathOffset = this._targetOffset;
- else
- this._pathOffset = this._pathOffset + deltaOffset;
- }
- }
-
- if(this._phi == this._targetPhi)
- if(this._theta == this._targetTheta)
- if(this._pathOffset == this._targetOffset)
- this._isAnimating = false;
- }
-
- this._computeMatrix();
-
- return true;
- },
-
- get action() { return this._action; },
-
- set action(a) { if(this._action != a) this._new_action = true; this._action = a; },
-
- get matrix() {
- this._computeMatrix();
- return this._matrix;
- },
-
- reset : function () {
- this._matrix = SglMat4.identity();
- this._action = SGL_TRACKBALL_NO_ACTION
-
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._pathOffset = this._startOffset;
-
- this._computeMatrix();
-
- this._isAnimating = false;
- this._isAutoWalking = false;
- this._hasToGoLap = false;
- },
-
- track : function(m, x, y, z) {
- if(this._new_action) {
- this._start[0] = x;
- this._start[1] = y;
- this._new_action = false;
- }
-
- var dx = this._start[0] - x;
- var dy = this._start[1] - y;
- this._start[0] = x;
- this._start[1] = y;
-
- switch (this._action) {
- case SGL_TRACKBALL_ROTATE:
- //this._isAnimating = false; //stopping animation
- this.rotate(m, dx, dy);
- break;
- case SGL_TRACKBALL_PAN:
- break;
- case SGL_TRACKBALL_SCALE:
- if(this._pathLocked) break;
- this._isAnimating = false; //stopping animation
- this.scale(m, z);
- break;
- default:
- break;
- }
- return this._computeMatrix();
- },
-
- rotate: function(m, dx, dy) {
- this._phi += dx;
- // avoid eternal accumulation of rotation, just for the sake of cleanliness
- if (this._phi > 10.0) this._phi = this._phi - 10.0;
- if (this._phi < -10.0) this._phi = this._phi + 10.0;
-
- this._theta += dy;
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- },
-
- scale : function(m, s) {
- if(s < 1.0)
- this.stepFW();
- else
- this.stepBW();
- }
-};
-/***********************************************************************/
diff --git a/all_tools/js/trackball_sphere.js b/all_tools/js/trackball_sphere.js
deleted file mode 100644
index 4e3c706..0000000
--- a/all_tools/js/trackball_sphere.js
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/**
- * Constructs a SphereTrackball object.
- * @class Interactor which implements a full spherical trackball controller.
- */
-function SphereTrackball() {
-}
-
-SphereTrackball.prototype = {
-
- setup : function (options) {
- options = options || {};
- var opt = sglGetDefaultObject({
- startCenter : [ 0.0, 0.0, 0.0 ],
- startDistance : 2.0,
- minMaxDist : [0.2, 4.0],
- }, options);
-
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
-
- // starting/default parameters
- this._startDistance = opt.startDistance; //distance
-
- // current parameters
- this._distance = this._startDistance;
-
- //limits
- this._minMaxDist = opt.minMaxDist;
-
- this._matrix = SglMat4.identity();
- this._sphereMatrix = SglMat4.identity();
-
- this._pts = [ [0.0, 0.0], [0.0, 0.0] ];
- this._start = [0.0, 0.0];
-
- this.reset();
- },
-
- clamp: function(value, low, high) {
- if(value < low) return low;
- if(value > high) return high;
- return value;
- },
-
- _computeMatrix: function() {
- var m = SglMat4.identity();
-
- // zoom
- m = SglMat4.mul(m, SglMat4.translation([0.0, 0.0, -this._distance]));
- // spheretrack
- m = SglMat4.mul(m, this._sphereMatrix);
-
- this._matrix = m;
-
- if(typeof onTrackballUpdate != "undefined")
- onTrackballUpdate(this.getState());
- },
-
- _projectOnSphere : function(x, y) {
- var r = 1.0;
-
- var z = 0.0;
- var d = sglSqrt(x*x + y*y);
- if (d < (r * 0.70710678118654752440)) {
- /* Inside sphere */
- z = sglSqrt(r*r - d*d);
- }
- else {
- /* On hyperbola */
- t = r / 1.41421356237309504880;
- z = t*t / d;
- }
- return z;
- },
-
- _transform : function(m, x, y, z) {
- return SglMat4.mul4(m, [x, y, z, 0.0]);
- },
-
- _transformOnSphere : function(m, x, y) {
- var z = this._projectOnSphere(x, y);
- return this._transform(m, x, y, z);
- },
-
- _translate : function(offset, f) {
- var invMat = SglMat4.inverse(this._sphereMatrix);
- var t = SglVec3.to4(offset, 0.0);
- t = SglMat4.mul4(invMat, t);
- t = SglVec4.muls(t, f);
- var trMat = SglMat4.translation(t);
- this._sphereMatrix = SglMat4.mul(this._sphereMatrix, trMat);
- },
-
- getState : function () {
- return this._sphereMatrix;
- },
-
- setState : function (newstate) {
- this._sphereMatrix = newstate;
- this._computeMatrix();
- },
-
- animateToState : function (newstate) {
- this._sphereMatrix = newstate;
- this._computeMatrix();
- },
-
- recenter : function (newpoint) {
- var newpanX = (newpoint[0]-presenter.sceneCenter[0]) * presenter.sceneRadiusInv;
- var newpanY = (newpoint[1]-presenter.sceneCenter[1]) * presenter.sceneRadiusInv;
- var newpanZ = (newpoint[2]-presenter.sceneCenter[2]) * presenter.sceneRadiusInv;
-
- this._sphereMatrix[12] = -newpanX;
- this._sphereMatrix[13] = -newpanY;
- this._sphereMatrix[14] = -newpanZ;
- this._distance *= 0.8;
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- this._computeMatrix();
- },
-
- tick : function (dt) {
- return false;
- },
-
- get action() { return this._action; },
-
- set action(a) { if(this._action != a) this._new_action = true; this._action = a; },
-
- get matrix() { return this._matrix; },
-
- get distance() { return this._distance; },
-
- reset : function () {
- this._matrix = SglMat4.identity();
- this._sphereMatrix = SglMat4.identity();
-
- this._distance = this._startDistance;
-
- this._pts = [ [0.0, 0.0], [0.0, 0.0] ];
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
-
- this._computeMatrix();
- },
-
- track : function(m, x, y, z) {
-
- if(this._new_action) {
- this._start[0] = x;
- this._start[1] = y;
- this._new_action = false;
- }
-
- var dx = this._start[0] - x;
- var dy = this._start[1] - y;
- this._start[0] = x;
- this._start[1] = y;
-
- this._pts[0][0] = this._pts[1][0] + dx;
- this._pts[0][1] = this._pts[1][1] + dy;
- this._pts[1][0] = dx;
- this._pts[1][1] = dy;
-
- switch (this._action) {
- case SGL_TRACKBALL_ROTATE:
- this.rotate(m);
- break;
-
- case SGL_TRACKBALL_PAN:
- this.pan(m);
- break;
-
- case SGL_TRACKBALL_DOLLY:
- this.dolly(m, z);
- break;
-
- case SGL_TRACKBALL_SCALE:
- this.scale(m, z);
- break;
-
- default:
- break;
- }
- },
-
- rotate : function(m) {
- if ((this._pts[0][0] == this._pts[1][0]) && (this._pts[0][1] == this._pts[1][1])) return;
-
- var mInv = SglMat4.inverse(m);
-
- var v0 = this._transformOnSphere(mInv, this._pts[0][0], this._pts[0][1]);
- var v1 = this._transformOnSphere(mInv, this._pts[1][0], this._pts[1][1]);
- var v1 = this._transformOnSphere(mInv, this._pts[1][0], this._pts[1][1]);
- var v1 = this._transformOnSphere(mInv, this._pts[1][0], this._pts[1][1]);
-
- var axis = SglVec3.cross(v0, v1);
- var angle = SglVec3.length(axis);
- var rotMat = SglMat4.rotationAngleAxis(angle, axis);
-
- this._sphereMatrix = SglMat4.mul(rotMat, this._sphereMatrix);
- this._computeMatrix();
- },
-
- pan : function(m) {
- var mInv = SglMat4.inverse(m);
- var v0 = this._transform(mInv, this._pts[0][0], this._pts[0][1], -1.0);
- var v1 = this._transform(mInv, this._pts[1][0], this._pts[1][1], -1.0);
- var offset = SglVec3.sub(v1, v0);
- this._translate(offset, 2.0);
- this._computeMatrix();
- },
-
- dolly : function(m, dz) {
- var mInv = SglMat4.inverse(m);
- var offset = this._transform(mInv, 0.0, 0.0, dz);
- this._translate(offset, 1.0);
- this._computeMatrix();
- },
-
- scale : function(m, s) {
- this._distance *= s;
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- this._computeMatrix();
- }
-};
-/***********************************************************************/
diff --git a/all_tools/js/trackball_turntable.js b/all_tools/js/trackball_turntable.js
deleted file mode 100644
index 615d943..0000000
--- a/all_tools/js/trackball_turntable.js
+++ /dev/null
@@ -1,309 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/**
- * Constructs a TurntableTrackball object.
- * @class Interactor which implements a Turntable controller with bounds.
- */
-function TurnTableTrackball() {
-}
-
-TurnTableTrackball.prototype = {
-
- setup : function (options) {
- options = options || {};
- var opt = sglGetDefaultObject({
- startCenter : [ 0.0, 0.0, 0.0 ],
- startPhi : 0.0,
- startTheta : 0.0,
- startDistance : 2.0,
- minMaxDist : [0.2, 4.0],
- minMaxPhi : [-180, 180],
- minMaxTheta : [-80.0, 80.0],
- }, options);
-
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
-
- this._matrix = SglMat4.identity();
-
- // trackball center
- this._center = opt.startCenter;
-
- // starting/default parameters
- this._startPhi = sglDegToRad(opt.startPhi); //phi (horizontal rotation)
- this._startTheta = sglDegToRad(opt.startTheta); //theta (vertical rotation)
- this._startDistance = opt.startDistance; //distance
-
- // current parameters
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._distance = this._startDistance;
-
- // target paramenters
- this._targetPhi = this._startPhi;
- this._targetTheta = this._startTheta;
- this._targetDistance = this._startDistance;
-
- //animation data
- this._isAnimating = false;
- this._speedPhi = 0.0;
- this._speedTheta = 0.0;
- this._speedDistance = 0.0;
-
- // limits
- this._minMaxDist = opt.minMaxDist;
- if((opt.minMaxPhi[0] == -180)&&(opt.minMaxPhi[1] == 180))
- this._limitPhi = false;
- else
- this._limitPhi = true;
- this._minMaxPhi = opt.minMaxPhi;
- this._minMaxPhi[0] = sglDegToRad(this._minMaxPhi[0]);
- this._minMaxPhi[1] = sglDegToRad(this._minMaxPhi[1]);
- this._minMaxTheta = opt.minMaxTheta;
- this._minMaxTheta[0] = sglDegToRad(this._minMaxTheta[0]);
- this._minMaxTheta[1] = sglDegToRad(this._minMaxTheta[1]);
-
- this._start = [0.0, 0.0];
- this.reset();
- },
-
- clamp: function(value, low, high) {
- if(value < low) return low;
- if(value > high) return high;
- return value;
- },
-
- _computeMatrix: function() {
- var m = SglMat4.identity();
-
- // centering
- m = SglMat4.mul(m, SglMat4.translation([-this._center[0], -this._center[1], -this._center[2]]));
- // zoom
- m = SglMat4.mul(m, SglMat4.translation([0.0, 0.0, -this._distance]));
- // rotation
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]));
- // tilt
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]));
-
- this._matrix = m;
-
- if(typeof onTrackballUpdate != "undefined")
- onTrackballUpdate(this.getState());
- },
-
- getState : function () {
- return [sglRadToDeg(this._phi), sglRadToDeg(this._theta), this._distance];
- },
-
- setState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._phi = sglDegToRad(newstate[0]);
- this._theta = sglDegToRad(newstate[1]);
- this._distance = newstate[2];
-
- //check limits
- if(this._limitPhi)
- this._phi = this.clamp(this._phi, this._minMaxPhi[0], this._minMaxPhi[1]);
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
-
- this._computeMatrix();
- },
-
- animateToState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._targetPhi = sglDegToRad(newstate[0]);
- this._targetTheta = sglDegToRad(newstate[1]);
- this._targetDistance = newstate[2];
-
- //check limits
- if(this._limitPhi)
- this._targetPhi = this.clamp(this._targetPhi, this._minMaxPhi[0], this._minMaxPhi[1]);
- this._targetPhi = this._targetPhi % (2*Math.PI);
- this._targetTheta = this.clamp(this._targetTheta, this._minMaxTheta[0], this._minMaxTheta[1]);
- this._targetDistance = this.clamp(this._targetDistance, this._minMaxDist[0], this._minMaxDist[1]);
-
- // setting base velocities
- this._speedPhi = Math.PI;
- this._speedTheta = Math.PI;
- this._speedDistance = 2.0;
-
- //if phi unconstrained rotation, it is necessary to find a good rotation direction
- if(!this._limitPhi){
- // normalize (-2pi 2pi) current phi angle, to prevent endless unwinding
- this._phi = this._phi % (2*Math.PI);
-
- // determine minimal, normalized target phi angle, to prevent endless unwinding
- var clampedangle = this._targetPhi;
- clampedangle = clampedangle % (2*Math.PI);
-
- if(Math.abs(clampedangle - this._phi) < Math.PI) { // standard rotation
- if(clampedangle > this._phi){
- this.speedphi = Math.PI;
- }
- else{
- this.speedphi = -Math.PI;
- }
- }
- else{
- if(clampedangle > this._phi){
- clampedangle = (clampedangle - 2*Math.PI)
- this.speedphi = -Math.PI;
- }
- else{
- clampedangle = (clampedangle + 2*Math.PI)
- this.speedphi = Math.PI;
- }
- }
-
- this._targetPhi = clampedangle;
- }
-
- // find max animation time to set a time limit and then synchronize all movements
- var timePhi = Math.abs((this._targetPhi - this._phi) / this._speedPhi);
- var timeTheta = Math.abs((this._targetTheta - this._theta) / this._speedTheta);
- var timeDistance = Math.abs((this._targetDistance - this._distance) / this._speedDistance);
-
- var maxtime = Math.max( timePhi, Math.max( timeTheta, timeDistance ));
- maxtime = this.clamp(maxtime, 0.5, 2.0);
-
- this._speedPhi *= timePhi / maxtime;
- this._speedTheta *= timeTheta / maxtime;
- this._speedDistance *= timeDistance / maxtime;
-
- // start animation
- this._isAnimating = true;
- },
-
- tick : function (dt) {
- if(!this._isAnimating) return false;
-
- var deltaPhi = this._speedPhi * dt;
- var deltaTheta = this._speedTheta * dt;
- var deltaDistance = this._speedDistance * dt;
-
- var diffPhi = this._targetPhi - this._phi;
- var diffTheta = this._targetTheta - this._theta;
- var diffDistance = this._targetDistance - this._distance;
-
- if (diffPhi > deltaPhi)
- this._phi += deltaPhi;
- else if (diffPhi < -deltaPhi)
- this._phi -= deltaPhi;
- else
- this._phi = this._targetPhi;
-
- if (diffTheta > deltaTheta)
- this._theta += deltaTheta;
- else if (diffTheta < -deltaTheta)
- this._theta -= deltaTheta;
- else
- this._theta = this._targetTheta;
-
- if (diffDistance > deltaDistance)
- this._distance += deltaDistance;
- else if (diffDistance < -deltaDistance)
- this._distance -= deltaDistance;
- else
- this._distance = this._targetDistance;
-
- if(this._phi == this._targetPhi)
- if(this._theta == this._targetTheta)
- if(this._distance == this._targetDistance)
- this._isAnimating = false;
-
- this._computeMatrix();
- return true;
- },
-
- get action() { return this._action; },
-
- set action(a) { if(this._action != a) this._new_action = true; this._action = a; },
-
- get matrix() { return this._matrix; },
-
- get distance() { return this._distance; },
-
- reset : function () {
- this._matrix = SglMat4.identity();
- this._action = SGL_TRACKBALL_NO_ACTION
-
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._distance = this._startDistance;
-
- this._isAnimating = false;
- },
-
- track : function(m, x, y, z) {
- if(this._new_action) {
- this._start[0] = x;
- this._start[1] = y;
- this._new_action = false;
- }
-
- var dx = this._start[0] - x;
- var dy = this._start[1] - y;
- this._start[0] = x;
- this._start[1] = y;
-
- switch (this._action) {
- case SGL_TRACKBALL_ROTATE:
- this._isAnimating = false; //stopping animation
- this.rotate(m, dx, dy);
- break;
-
- case SGL_TRACKBALL_PAN:
- break;
-
- case SGL_TRACKBALL_SCALE:
- this._isAnimating = false; //stopping animation
- this.scale(m, z);
- break;
-
- default:
- break;
- }
- return this._computeMatrix();
- },
-
- rotate: function(m, dx, dy) {
- this._phi += dx;
- if(this._limitPhi)
- this._phi = this.clamp(this._phi, this._minMaxPhi[0], this._minMaxPhi[1]);
-
- // avoid eternal accumulation of rotation, just for the sake of cleanliness
- if (this._phi > 10.0) this._phi = this._phi - 10.0;
- if (this._phi < -10.0) this._phi = this._phi + 10.0;
-
- this._theta += dy;
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- },
-
- scale : function(m, s) {
- this._distance *= s;
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- }
-};
-/***********************************************************************/
diff --git a/all_tools/js/trackball_turntable_pan.js b/all_tools/js/trackball_turntable_pan.js
deleted file mode 100644
index e5916ad..0000000
--- a/all_tools/js/trackball_turntable_pan.js
+++ /dev/null
@@ -1,408 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/**
- * Constructs a TurntableCylTrackball object.
- * @class Interactor which implements a Turntable controller + cylindrical pan with bounds.
- */
-function TurntablePanTrackball() {
-}
-
-TurntablePanTrackball.prototype = {
-
- setup : function (options) {
- options = options || {};
- var opt = sglGetDefaultObject({
- startCenter : [ 0.0, 0.0, 0.0 ],
- startPhi : 0.0,
- startTheta : 0.0,
- startDistance : 2.0,
- startPanX : 0.0,
- startPanY : 0.0,
- startPanZ : 0.0,
- minMaxDist : [0.2, 4.0],
- minMaxPhi : [-180, 180],
- minMaxTheta : [-80.0, 80.0],
- minMaxPanX : [-1.0, 1.0],
- minMaxPanY : [-1.0, 1.0],
- minMaxPanZ : [-1.0, 1.0],
- }, options);
-
-
- this._action = SGL_TRACKBALL_NO_ACTION;
- this._new_action = true;
-
- this._matrix = SglMat4.identity();
-
- // trackball center
- this._center = opt.startCenter;
-
- // starting/default parameters
- this._startPhi = sglDegToRad(opt.startPhi); //phi (horizontal rotation)
- this._startTheta = sglDegToRad(opt.startTheta); //theta (vertical rotation)
- this._startPanX = opt.startPanX; //panX
- this._startPanY = opt.startPanY; //panY
- this._startPanZ = opt.startPanZ; //panZ
- this._startDistance = opt.startDistance; //distance
-
- // current parameters
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._panX = this._startPanX;
- this._panY = this._startPanY;
- this._panZ = this._startPanZ;
- this._distance = this._startDistance;
-
- //animation data
- this._isAnimating = false;
-
- // limits
- if((opt.minMaxPhi[0] == -180)&&(opt.minMaxPhi[1] == 180))
- this._limitPhi = false;
- else
- this._limitPhi = true;
- this._minMaxPhi = opt.minMaxPhi;
- this._minMaxPhi[0] = sglDegToRad(this._minMaxPhi[0]);
- this._minMaxPhi[1] = sglDegToRad(this._minMaxPhi[1]);
- this._minMaxTheta = opt.minMaxTheta;
- this._minMaxTheta[0] = sglDegToRad(this._minMaxTheta[0]);
- this._minMaxTheta[1] = sglDegToRad(this._minMaxTheta[1]);
- this._minMaxPanX = opt.minMaxPanX;
- this._minMaxPanY = opt.minMaxPanY;
- this._minMaxPanZ = opt.minMaxPanZ;
- this._minMaxDist = opt.minMaxDist;
-
- this._start = [0.0, 0.0];
- this.reset();
- },
-
- clamp: function(value, low, high) {
- if(value < low) return low;
- if(value > high) return high;
- return value;
- },
-
- _computeMatrix: function() {
- var m = SglMat4.identity();
-
- // centering
- m = SglMat4.mul(m, SglMat4.translation([-this._center[0], -this._center[1], -this._center[2]]));
- // zoom
- m = SglMat4.mul(m, SglMat4.translation([0.0, 0.0, -this._distance]));
- // rotation
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]));
- // tilt
- m = SglMat4.mul(m, SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]));
- // panning
- m = SglMat4.mul(m, SglMat4.translation([-this._panX, -this._panY, -this._panZ]));
-
- this._matrix = m;
-
- if(typeof onTrackballUpdate != "undefined")
- onTrackballUpdate(this.getState());
- },
-
- getState : function () {
- return [sglRadToDeg(this._phi), sglRadToDeg(this._theta), this._panX, this._panY, this._panZ, this._distance];
- },
-
- setState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._phi = sglDegToRad(newstate[0]);
- this._theta = sglDegToRad(newstate[1]);
- this._panX = newstate[2];
- this._panY = newstate[3];
- this._panZ = newstate[4];
- this._distance = newstate[5];
-
- //check limits
- if(this._limitPhi)
- this._phi = this.clamp(this._phi, this._minMaxPhi[0], this._minMaxPhi[1]);
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._panY = this.clamp(this._panY, this._minMaxPanY[0], this._minMaxPanY[1]);
- this._panZ = this.clamp(this._panZ, this._minMaxPanZ[0], this._minMaxPanZ[1]);
-
- this._computeMatrix();
- },
-
- animateToState : function (newstate) {
- // stop animation
- this._isAnimating = false;
-
- this._targetPhi = sglDegToRad(newstate[0]);
- this._targetTheta = sglDegToRad(newstate[1]);
- this._targetPanX = newstate[2];
- this._targetPanY = newstate[3];
- this._targetPanZ = newstate[4];
- this._targetDistance = newstate[5];
-
- //check limits
- if(this._limitPhi)
- this._targetPhi = this.clamp(this._targetPhi, this._minMaxPhi[0], this._minMaxPhi[1]);
- this._targetPhi = this._targetPhi % (2*Math.PI);
- this._targetTheta = this.clamp(this._targetTheta, this._minMaxTheta[0], this._minMaxTheta[1]);
- this._targetPanX = this.clamp(this._targetPanX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._targetPanY = this.clamp(this._targetPanY, this._minMaxPanY[0], this._minMaxPanY[1]);
- this._targetPanZ = this.clamp(this._targetPanZ, this._minMaxPanZ[0], this._minMaxPanZ[1]);
- this._targetDistance = this.clamp(this._targetDistance, this._minMaxDist[0], this._minMaxDist[1]);
-
- // setting base velocities
- this._speedPhi = Math.PI;
- this._speedTheta = Math.PI;
- this._speedPanX = 1.0;
- this._speedPanY = 1.0;
- this._speedPanZ = 1.0;
- this._speedDistance = 2.0;
-
- //if phi unconstrained rotation, it is necessary to find a good rotation direction
- if(!this._limitPhi){
- // normalize (-2pi 2pi) current phi angle, to prevent endless unwinding
- this._phi = this._phi % (2*Math.PI);
-
- // determine minimal, normalized target phi angle, to prevent endless unwinding
- var clampedangle = this._targetPhi;
- clampedangle = clampedangle % (2*Math.PI);
-
- if(Math.abs(clampedangle - this._phi) < Math.PI) { // standard rotation
- if(clampedangle > this._phi){
- this.speedphi = Math.PI;
- }
- else{
- this.speedphi = -Math.PI;
- }
- }
- else{
- if(clampedangle > this._phi){
- clampedangle = (clampedangle - 2*Math.PI)
- this.speedphi = -Math.PI;
- }
- else{
- clampedangle = (clampedangle + 2*Math.PI)
- this.speedphi = Math.PI;
- }
- }
-
- this._targetPhi = clampedangle;
- }
-
- // find max animation time to set a time limit and then synchronize all movements
- var timePhi = Math.abs((this._targetPhi - this._phi) / this._speedPhi);
- var timeTheta = Math.abs((this._targetTheta - this._theta) / this._speedTheta);
- var timeDistance = Math.abs((this._targetDistance - this._distance) / this._speedDistance);
- var timePanX = Math.abs((this._targetPanX - this._panX) / this._speedPanX);
- var timePanY = Math.abs((this._targetPanY - this._panY) / this._speedPanY);
- var timePanZ = Math.abs((this._targetPanZ - this._panZ) / this._speedPanZ);
-
- var maxtime = Math.max( timePhi, Math.max( timeTheta, Math.max( timeDistance, Math.max( timePanX, Math.max( timePanY, timePanZ )))));
- maxtime = this.clamp(maxtime, 0.5, 2.0);
-
- this._speedPhi *= timePhi / maxtime;
- this._speedTheta *= timeTheta / maxtime;
- this._speedDistance *= timeDistance / maxtime;
- this._speedPanX *= timePanX / maxtime;
- this._speedPanY *= timePanY / maxtime;
- this._speedPanZ *= timePanZ / maxtime;
-
- // start animation
- this._isAnimating = true;
- },
-
- recenter : function (newpoint) {
- // stop animation
- this._isAnimating = false;
-
- var newpanX = (newpoint[0]-presenter.sceneCenter[0]) * presenter.sceneRadiusInv;
- var newpanY = (newpoint[1]-presenter.sceneCenter[1]) * presenter.sceneRadiusInv;
- var newpanZ = (newpoint[2]-presenter.sceneCenter[2]) * presenter.sceneRadiusInv;
-
- this.animateToState([sglRadToDeg(this._phi), sglRadToDeg(this._theta), newpanX, newpanY, newpanZ, (this._distance * 0.8)]);
- },
-
- tick : function (dt) {
- if(!this._isAnimating) return false;
-
- var deltaPhi = this._speedPhi * dt;
- var deltaTheta = this._speedTheta * dt;
- var deltaDistance = this._speedDistance * dt;
- var deltaPanX = this._speedPanX * dt;
- var deltaPanY = this._speedPanY * dt;
- var deltaPanZ = this._speedPanZ * dt;
-
- var diffPhi = this._targetPhi - this._phi;
- var diffTheta = this._targetTheta - this._theta;
- var diffDistance = this._targetDistance - this._distance;
- var diffPanX = this._targetPanX - this._panX;
- var diffPanY = this._targetPanY - this._panY;
- var diffPanZ = this._targetPanZ - this._panZ;
-
- if (diffPhi > deltaPhi)
- this._phi += deltaPhi;
- else if (diffPhi < -deltaPhi)
- this._phi -= deltaPhi;
- else
- this._phi = this._targetPhi;
-
- if (diffTheta > deltaTheta)
- this._theta += deltaTheta;
- else if (diffTheta < -deltaTheta)
- this._theta -= deltaTheta;
- else
- this._theta = this._targetTheta;
-
- if (diffDistance > deltaDistance)
- this._distance += deltaDistance;
- else if (diffDistance < -deltaDistance)
- this._distance -= deltaDistance;
- else
- this._distance = this._targetDistance;
-
- if (diffPanX > deltaPanX)
- this._panX += deltaPanX;
- else if (diffPanX < -deltaPanX)
- this._panX -= deltaPanX;
- else
- this._panX = this._targetPanX;
-
- if (diffPanY > deltaPanY)
- this._panY += deltaPanY;
- else if (diffPanY < -deltaPanY)
- this._panY -= deltaPanY;
- else
- this._panY = this._targetPanY;
-
- if (diffPanZ > deltaPanZ)
- this._panZ += deltaPanZ;
- else if (diffPanZ < -deltaPanZ)
- this._panZ -= deltaPanZ;
- else
- this._panZ = this._targetPanZ;
-
- if(this._phi == this._targetPhi)
- if(this._theta == this._targetTheta)
- if(this._distance == this._targetDistance)
- if(this._panX == this._targetPanX)
- if(this._panY == this._targetPanY)
- if(this._panZ == this._targetPanZ)
- this._isAnimating = false;
-
- this._computeMatrix();
- return true;
- },
-
- get action() { return this._action; },
-
- set action(a) { if(this._action != a) this._new_action = true; this._action = a; },
-
- get matrix() { return this._matrix; },
-
- get distance() { return this._distance; },
-
- reset : function () {
- this._matrix = SglMat4.identity();
- this._action = SGL_TRACKBALL_NO_ACTION
-
- this._phi = this._startPhi;
- this._theta = this._startTheta;
- this._distance = this._startDistance;
- this._panX = this._startPanX;
- this._panY = this._startPanY;
- this._panZ = this._startPanZ;
-
- this._isAnimating = false;
- },
-
- track : function(m, x, y, z) {
- if(this._new_action) {
- this._start[0] = x;
- this._start[1] = y;
- this._new_action = false;
- }
-
- var dx = this._start[0] - x;
- var dy = this._start[1] - y;
- this._start[0] = x;
- this._start[1] = y;
-
- switch (this._action) {
- case SGL_TRACKBALL_ROTATE:
- this._isAnimating = false; //stopping animation
- this.rotate(m, dx, dy);
- break;
-
- case SGL_TRACKBALL_PAN:
- this._isAnimating = false; //stopping animation
- this.pan(m, dx, dy);
- break;
-
- case SGL_TRACKBALL_SCALE:
- this._isAnimating = false; //stopping animation
- this.scale(m, z);
- break;
-
- default:
- break;
- }
- return this._computeMatrix();
- },
-
- pan: function(m, dx, dy) {
- //determining current X, Y and Z axis
- var Xvec = [1.0, 0.0, 0.0, 1.0];
- var Yvec = [0.0, 1.0, 0.0, 1.0];
- var Zvec = [0.0, 0.0, 1.0, 1.0];
- Xvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]), Xvec);
- Yvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]), Yvec);
- Zvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._phi, [0.0, -1.0, 0.0]), Zvec);
- Xvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]), Xvec);
- Yvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]), Yvec);
- Zvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]), Zvec);
-
- this._panX += (dx * Xvec[0]) + (dy * Xvec[1]);
- this._panY += (dx * Yvec[0]) + (dy * Yvec[1]);
- this._panZ += (dx * Zvec[0]) + (dy * Zvec[1]);
-
- //clamping
- this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);
- this._panY = this.clamp(this._panY, this._minMaxPanY[0], this._minMaxPanY[1]);
- this._panZ = this.clamp(this._panZ, this._minMaxPanZ[0], this._minMaxPanZ[1]);
- },
-
- rotate: function(m, dx, dy) {
- this._phi += dx;
- if(this._limitPhi)
- this._phi = this.clamp(this._phi, this._minMaxPhi[0], this._minMaxPhi[1]);
-
- // avoid eternal accumulation of rotation, just for the sake of cleanliness
- if (this._phi > 10.0) this._phi = this._phi - 10.0;
- if (this._phi < -10.0) this._phi = this._phi + 10.0;
-
- this._theta += dy;
- this._theta = this.clamp(this._theta, this._minMaxTheta[0], this._minMaxTheta[1]);
- },
-
- scale : function(m, s) {
- this._distance *= s;
- this._distance = this.clamp(this._distance, this._minMaxDist[0], this._minMaxDist[1]);
- }
-};
-/***********************************************************************/
diff --git a/all_tools/models/gargo.nxs b/all_tools/models/gargo.nxs
deleted file mode 100644
index 7e8b952..0000000
Binary files a/all_tools/models/gargo.nxs and /dev/null differ
diff --git a/all_tools/skins/backgrounds/dark.jpg b/all_tools/skins/backgrounds/dark.jpg
deleted file mode 100644
index 47e816f..0000000
Binary files a/all_tools/skins/backgrounds/dark.jpg and /dev/null differ
diff --git a/all_tools/skins/backgrounds/light.jpg b/all_tools/skins/backgrounds/light.jpg
deleted file mode 100644
index ab43209..0000000
Binary files a/all_tools/skins/backgrounds/light.jpg and /dev/null differ
diff --git a/all_tools/skins/dark/back.png b/all_tools/skins/dark/back.png
deleted file mode 100644
index 4163da5..0000000
Binary files a/all_tools/skins/dark/back.png and /dev/null differ
diff --git a/all_tools/skins/dark/close.png b/all_tools/skins/dark/close.png
deleted file mode 100644
index 305c362..0000000
Binary files a/all_tools/skins/dark/close.png and /dev/null differ
diff --git a/all_tools/skins/dark/close_on.png b/all_tools/skins/dark/close_on.png
deleted file mode 100644
index 659f30a..0000000
Binary files a/all_tools/skins/dark/close_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/color.png b/all_tools/skins/dark/color.png
deleted file mode 100644
index d3c6fd6..0000000
Binary files a/all_tools/skins/dark/color.png and /dev/null differ
diff --git a/all_tools/skins/dark/color_on.png b/all_tools/skins/dark/color_on.png
deleted file mode 100644
index bc3d3d9..0000000
Binary files a/all_tools/skins/dark/color_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/exit.png b/all_tools/skins/dark/exit.png
deleted file mode 100644
index 1f77277..0000000
Binary files a/all_tools/skins/dark/exit.png and /dev/null differ
diff --git a/all_tools/skins/dark/full.png b/all_tools/skins/dark/full.png
deleted file mode 100644
index 4240f04..0000000
Binary files a/all_tools/skins/dark/full.png and /dev/null differ
diff --git a/all_tools/skins/dark/full_on.png b/all_tools/skins/dark/full_on.png
deleted file mode 100644
index 28729ba..0000000
Binary files a/all_tools/skins/dark/full_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/help.png b/all_tools/skins/dark/help.png
deleted file mode 100644
index 180ed38..0000000
Binary files a/all_tools/skins/dark/help.png and /dev/null differ
diff --git a/all_tools/skins/dark/help_on.png b/all_tools/skins/dark/help_on.png
deleted file mode 100644
index c2c3ebc..0000000
Binary files a/all_tools/skins/dark/help_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/home.png b/all_tools/skins/dark/home.png
deleted file mode 100644
index b576061..0000000
Binary files a/all_tools/skins/dark/home.png and /dev/null differ
diff --git a/all_tools/skins/dark/light.png b/all_tools/skins/dark/light.png
deleted file mode 100644
index 25417be..0000000
Binary files a/all_tools/skins/dark/light.png and /dev/null differ
diff --git a/all_tools/skins/dark/light_on.png b/all_tools/skins/dark/light_on.png
deleted file mode 100644
index 532a4d2..0000000
Binary files a/all_tools/skins/dark/light_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/measure.png b/all_tools/skins/dark/measure.png
deleted file mode 100644
index 0b91007..0000000
Binary files a/all_tools/skins/dark/measure.png and /dev/null differ
diff --git a/all_tools/skins/dark/measure_on.png b/all_tools/skins/dark/measure_on.png
deleted file mode 100644
index d437d7a..0000000
Binary files a/all_tools/skins/dark/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/menu.png b/all_tools/skins/dark/menu.png
deleted file mode 100644
index e162b51..0000000
Binary files a/all_tools/skins/dark/menu.png and /dev/null differ
diff --git a/all_tools/skins/dark/next.png b/all_tools/skins/dark/next.png
deleted file mode 100644
index 226993c..0000000
Binary files a/all_tools/skins/dark/next.png and /dev/null differ
diff --git a/all_tools/skins/dark/pick.png b/all_tools/skins/dark/pick.png
deleted file mode 100644
index faff7f0..0000000
Binary files a/all_tools/skins/dark/pick.png and /dev/null differ
diff --git a/all_tools/skins/dark/pick_on.png b/all_tools/skins/dark/pick_on.png
deleted file mode 100644
index 398fcee..0000000
Binary files a/all_tools/skins/dark/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/pin.png b/all_tools/skins/dark/pin.png
deleted file mode 100644
index eddd0af..0000000
Binary files a/all_tools/skins/dark/pin.png and /dev/null differ
diff --git a/all_tools/skins/dark/pin_on.png b/all_tools/skins/dark/pin_on.png
deleted file mode 100644
index 0ca7ed1..0000000
Binary files a/all_tools/skins/dark/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/play.png b/all_tools/skins/dark/play.png
deleted file mode 100644
index 5e0145c..0000000
Binary files a/all_tools/skins/dark/play.png and /dev/null differ
diff --git a/all_tools/skins/dark/sectionX.png b/all_tools/skins/dark/sectionX.png
deleted file mode 100644
index c7fa058..0000000
Binary files a/all_tools/skins/dark/sectionX.png and /dev/null differ
diff --git a/all_tools/skins/dark/sections.png b/all_tools/skins/dark/sections.png
deleted file mode 100644
index 268f080..0000000
Binary files a/all_tools/skins/dark/sections.png and /dev/null differ
diff --git a/all_tools/skins/dark/sections_on.png b/all_tools/skins/dark/sections_on.png
deleted file mode 100644
index d8502e7..0000000
Binary files a/all_tools/skins/dark/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/dark/zoomin.png b/all_tools/skins/dark/zoomin.png
deleted file mode 100644
index 1162e55..0000000
Binary files a/all_tools/skins/dark/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/dark/zoomout.png b/all_tools/skins/dark/zoomout.png
deleted file mode 100644
index d5db698..0000000
Binary files a/all_tools/skins/dark/zoomout.png and /dev/null differ
diff --git a/all_tools/skins/icons/cursor_light.png b/all_tools/skins/icons/cursor_light.png
deleted file mode 100644
index d289369..0000000
Binary files a/all_tools/skins/icons/cursor_light.png and /dev/null differ
diff --git a/all_tools/skins/icons/cursor_light_on.png b/all_tools/skins/icons/cursor_light_on.png
deleted file mode 100644
index eb917dc..0000000
Binary files a/all_tools/skins/icons/cursor_light_on.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionX.png b/all_tools/skins/icons/sectionX.png
deleted file mode 100644
index b36900b..0000000
Binary files a/all_tools/skins/icons/sectionX.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionX_on.png b/all_tools/skins/icons/sectionX_on.png
deleted file mode 100644
index 6b6f2ab..0000000
Binary files a/all_tools/skins/icons/sectionX_on.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionY.png b/all_tools/skins/icons/sectionY.png
deleted file mode 100644
index abaffd4..0000000
Binary files a/all_tools/skins/icons/sectionY.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionY_on.png b/all_tools/skins/icons/sectionY_on.png
deleted file mode 100644
index 69cfc1a..0000000
Binary files a/all_tools/skins/icons/sectionY_on.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionZ.png b/all_tools/skins/icons/sectionZ.png
deleted file mode 100644
index f0e1043..0000000
Binary files a/all_tools/skins/icons/sectionZ.png and /dev/null differ
diff --git a/all_tools/skins/icons/sectionZ_on.png b/all_tools/skins/icons/sectionZ_on.png
deleted file mode 100644
index 00b35d3..0000000
Binary files a/all_tools/skins/icons/sectionZ_on.png and /dev/null differ
diff --git a/all_tools/skins/light/back.png b/all_tools/skins/light/back.png
deleted file mode 100644
index db0685d..0000000
Binary files a/all_tools/skins/light/back.png and /dev/null differ
diff --git a/all_tools/skins/light/close.png b/all_tools/skins/light/close.png
deleted file mode 100644
index a76eafe..0000000
Binary files a/all_tools/skins/light/close.png and /dev/null differ
diff --git a/all_tools/skins/light/close_on.png b/all_tools/skins/light/close_on.png
deleted file mode 100644
index feacb09..0000000
Binary files a/all_tools/skins/light/close_on.png and /dev/null differ
diff --git a/all_tools/skins/light/color.png b/all_tools/skins/light/color.png
deleted file mode 100644
index e2f6665..0000000
Binary files a/all_tools/skins/light/color.png and /dev/null differ
diff --git a/all_tools/skins/light/color_on.png b/all_tools/skins/light/color_on.png
deleted file mode 100644
index 886ed80..0000000
Binary files a/all_tools/skins/light/color_on.png and /dev/null differ
diff --git a/all_tools/skins/light/exit.png b/all_tools/skins/light/exit.png
deleted file mode 100644
index d84fe81..0000000
Binary files a/all_tools/skins/light/exit.png and /dev/null differ
diff --git a/all_tools/skins/light/full.png b/all_tools/skins/light/full.png
deleted file mode 100644
index b9f7d05..0000000
Binary files a/all_tools/skins/light/full.png and /dev/null differ
diff --git a/all_tools/skins/light/full_on.png b/all_tools/skins/light/full_on.png
deleted file mode 100644
index f513d74..0000000
Binary files a/all_tools/skins/light/full_on.png and /dev/null differ
diff --git a/all_tools/skins/light/help.png b/all_tools/skins/light/help.png
deleted file mode 100644
index 70ef4d3..0000000
Binary files a/all_tools/skins/light/help.png and /dev/null differ
diff --git a/all_tools/skins/light/help_on.png b/all_tools/skins/light/help_on.png
deleted file mode 100644
index acd7352..0000000
Binary files a/all_tools/skins/light/help_on.png and /dev/null differ
diff --git a/all_tools/skins/light/home.png b/all_tools/skins/light/home.png
deleted file mode 100644
index 85a5fa6..0000000
Binary files a/all_tools/skins/light/home.png and /dev/null differ
diff --git a/all_tools/skins/light/light.png b/all_tools/skins/light/light.png
deleted file mode 100644
index fb54071..0000000
Binary files a/all_tools/skins/light/light.png and /dev/null differ
diff --git a/all_tools/skins/light/light_on.png b/all_tools/skins/light/light_on.png
deleted file mode 100644
index f617580..0000000
Binary files a/all_tools/skins/light/light_on.png and /dev/null differ
diff --git a/all_tools/skins/light/measure.png b/all_tools/skins/light/measure.png
deleted file mode 100644
index 7784d60..0000000
Binary files a/all_tools/skins/light/measure.png and /dev/null differ
diff --git a/all_tools/skins/light/measure_on.png b/all_tools/skins/light/measure_on.png
deleted file mode 100644
index fbf50b7..0000000
Binary files a/all_tools/skins/light/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/light/menu.png b/all_tools/skins/light/menu.png
deleted file mode 100644
index 4ba3b98..0000000
Binary files a/all_tools/skins/light/menu.png and /dev/null differ
diff --git a/all_tools/skins/light/next.png b/all_tools/skins/light/next.png
deleted file mode 100644
index 07f32e7..0000000
Binary files a/all_tools/skins/light/next.png and /dev/null differ
diff --git a/all_tools/skins/light/pick.png b/all_tools/skins/light/pick.png
deleted file mode 100644
index 32d3f56..0000000
Binary files a/all_tools/skins/light/pick.png and /dev/null differ
diff --git a/all_tools/skins/light/pick_on.png b/all_tools/skins/light/pick_on.png
deleted file mode 100644
index bb054b7..0000000
Binary files a/all_tools/skins/light/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/light/pin.png b/all_tools/skins/light/pin.png
deleted file mode 100644
index 32463d5..0000000
Binary files a/all_tools/skins/light/pin.png and /dev/null differ
diff --git a/all_tools/skins/light/pin_on.png b/all_tools/skins/light/pin_on.png
deleted file mode 100644
index 441b2a5..0000000
Binary files a/all_tools/skins/light/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/light/play.png b/all_tools/skins/light/play.png
deleted file mode 100644
index 13450bd..0000000
Binary files a/all_tools/skins/light/play.png and /dev/null differ
diff --git a/all_tools/skins/light/sectionX.png b/all_tools/skins/light/sectionX.png
deleted file mode 100644
index 3a22fe2..0000000
Binary files a/all_tools/skins/light/sectionX.png and /dev/null differ
diff --git a/all_tools/skins/light/sections.png b/all_tools/skins/light/sections.png
deleted file mode 100644
index a160265..0000000
Binary files a/all_tools/skins/light/sections.png and /dev/null differ
diff --git a/all_tools/skins/light/sections_on.png b/all_tools/skins/light/sections_on.png
deleted file mode 100644
index 32a0b22..0000000
Binary files a/all_tools/skins/light/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/light/zoomin.png b/all_tools/skins/light/zoomin.png
deleted file mode 100644
index 711c8e8..0000000
Binary files a/all_tools/skins/light/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/light/zoomout.png b/all_tools/skins/light/zoomout.png
deleted file mode 100644
index 9833330..0000000
Binary files a/all_tools/skins/light/zoomout.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/back.png b/all_tools/skins/minimal_dark/back.png
deleted file mode 100644
index d3aa419..0000000
Binary files a/all_tools/skins/minimal_dark/back.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/close.png b/all_tools/skins/minimal_dark/close.png
deleted file mode 100644
index 8a0cac6..0000000
Binary files a/all_tools/skins/minimal_dark/close.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/close_on.png b/all_tools/skins/minimal_dark/close_on.png
deleted file mode 100644
index ace95cb..0000000
Binary files a/all_tools/skins/minimal_dark/close_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/color.png b/all_tools/skins/minimal_dark/color.png
deleted file mode 100644
index 1806063..0000000
Binary files a/all_tools/skins/minimal_dark/color.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/color_on.png b/all_tools/skins/minimal_dark/color_on.png
deleted file mode 100644
index 068d2a7..0000000
Binary files a/all_tools/skins/minimal_dark/color_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/exit.png b/all_tools/skins/minimal_dark/exit.png
deleted file mode 100644
index 7604077..0000000
Binary files a/all_tools/skins/minimal_dark/exit.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/full.png b/all_tools/skins/minimal_dark/full.png
deleted file mode 100644
index 226bede..0000000
Binary files a/all_tools/skins/minimal_dark/full.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/full_on.png b/all_tools/skins/minimal_dark/full_on.png
deleted file mode 100644
index 71d7786..0000000
Binary files a/all_tools/skins/minimal_dark/full_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/help.png b/all_tools/skins/minimal_dark/help.png
deleted file mode 100644
index 6cb918d..0000000
Binary files a/all_tools/skins/minimal_dark/help.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/help_on.png b/all_tools/skins/minimal_dark/help_on.png
deleted file mode 100644
index 3ec1989..0000000
Binary files a/all_tools/skins/minimal_dark/help_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/home.png b/all_tools/skins/minimal_dark/home.png
deleted file mode 100644
index 600da24..0000000
Binary files a/all_tools/skins/minimal_dark/home.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/light.png b/all_tools/skins/minimal_dark/light.png
deleted file mode 100644
index 8df0d7d..0000000
Binary files a/all_tools/skins/minimal_dark/light.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/light_on.png b/all_tools/skins/minimal_dark/light_on.png
deleted file mode 100644
index 95febe2..0000000
Binary files a/all_tools/skins/minimal_dark/light_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/measure.png b/all_tools/skins/minimal_dark/measure.png
deleted file mode 100644
index 55ec934..0000000
Binary files a/all_tools/skins/minimal_dark/measure.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/measure_on.png b/all_tools/skins/minimal_dark/measure_on.png
deleted file mode 100644
index 48d9c80..0000000
Binary files a/all_tools/skins/minimal_dark/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/menu.png b/all_tools/skins/minimal_dark/menu.png
deleted file mode 100644
index e50a394..0000000
Binary files a/all_tools/skins/minimal_dark/menu.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/next.png b/all_tools/skins/minimal_dark/next.png
deleted file mode 100644
index d4f9449..0000000
Binary files a/all_tools/skins/minimal_dark/next.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/pick.png b/all_tools/skins/minimal_dark/pick.png
deleted file mode 100644
index 38bff25..0000000
Binary files a/all_tools/skins/minimal_dark/pick.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/pick_on.png b/all_tools/skins/minimal_dark/pick_on.png
deleted file mode 100644
index 019c7e8..0000000
Binary files a/all_tools/skins/minimal_dark/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/pin.png b/all_tools/skins/minimal_dark/pin.png
deleted file mode 100644
index 9d830f1..0000000
Binary files a/all_tools/skins/minimal_dark/pin.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/pin_on.png b/all_tools/skins/minimal_dark/pin_on.png
deleted file mode 100644
index f7cdffe..0000000
Binary files a/all_tools/skins/minimal_dark/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/play.png b/all_tools/skins/minimal_dark/play.png
deleted file mode 100644
index 3fbed4a..0000000
Binary files a/all_tools/skins/minimal_dark/play.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/sections.png b/all_tools/skins/minimal_dark/sections.png
deleted file mode 100644
index 4eac6db..0000000
Binary files a/all_tools/skins/minimal_dark/sections.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/sections_on.png b/all_tools/skins/minimal_dark/sections_on.png
deleted file mode 100644
index ffe6bd5..0000000
Binary files a/all_tools/skins/minimal_dark/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/zoomin.png b/all_tools/skins/minimal_dark/zoomin.png
deleted file mode 100644
index ecec536..0000000
Binary files a/all_tools/skins/minimal_dark/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/minimal_dark/zoomout.png b/all_tools/skins/minimal_dark/zoomout.png
deleted file mode 100644
index 3f618a6..0000000
Binary files a/all_tools/skins/minimal_dark/zoomout.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/back.png b/all_tools/skins/minimal_light/back.png
deleted file mode 100644
index fb9ad0a..0000000
Binary files a/all_tools/skins/minimal_light/back.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/close.png b/all_tools/skins/minimal_light/close.png
deleted file mode 100644
index b6f8a7a..0000000
Binary files a/all_tools/skins/minimal_light/close.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/close_on.png b/all_tools/skins/minimal_light/close_on.png
deleted file mode 100644
index ace95cb..0000000
Binary files a/all_tools/skins/minimal_light/close_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/color.png b/all_tools/skins/minimal_light/color.png
deleted file mode 100644
index a8f8b82..0000000
Binary files a/all_tools/skins/minimal_light/color.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/color_on.png b/all_tools/skins/minimal_light/color_on.png
deleted file mode 100644
index 78a37fb..0000000
Binary files a/all_tools/skins/minimal_light/color_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/exit.png b/all_tools/skins/minimal_light/exit.png
deleted file mode 100644
index 6d553bf..0000000
Binary files a/all_tools/skins/minimal_light/exit.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/full.png b/all_tools/skins/minimal_light/full.png
deleted file mode 100644
index 0d2563b..0000000
Binary files a/all_tools/skins/minimal_light/full.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/full_on.png b/all_tools/skins/minimal_light/full_on.png
deleted file mode 100644
index 9099018..0000000
Binary files a/all_tools/skins/minimal_light/full_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/help.png b/all_tools/skins/minimal_light/help.png
deleted file mode 100644
index 91b43e1..0000000
Binary files a/all_tools/skins/minimal_light/help.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/help_on.png b/all_tools/skins/minimal_light/help_on.png
deleted file mode 100644
index 3ec1989..0000000
Binary files a/all_tools/skins/minimal_light/help_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/home.png b/all_tools/skins/minimal_light/home.png
deleted file mode 100644
index 73af9db..0000000
Binary files a/all_tools/skins/minimal_light/home.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/light.png b/all_tools/skins/minimal_light/light.png
deleted file mode 100644
index 00e5e15..0000000
Binary files a/all_tools/skins/minimal_light/light.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/light_on.png b/all_tools/skins/minimal_light/light_on.png
deleted file mode 100644
index 95febe2..0000000
Binary files a/all_tools/skins/minimal_light/light_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/measure.png b/all_tools/skins/minimal_light/measure.png
deleted file mode 100644
index b063fc5..0000000
Binary files a/all_tools/skins/minimal_light/measure.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/measure_on.png b/all_tools/skins/minimal_light/measure_on.png
deleted file mode 100644
index 6353577..0000000
Binary files a/all_tools/skins/minimal_light/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/menu.png b/all_tools/skins/minimal_light/menu.png
deleted file mode 100644
index 0c0058a..0000000
Binary files a/all_tools/skins/minimal_light/menu.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/next.png b/all_tools/skins/minimal_light/next.png
deleted file mode 100644
index d67e325..0000000
Binary files a/all_tools/skins/minimal_light/next.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/pick.png b/all_tools/skins/minimal_light/pick.png
deleted file mode 100644
index 83a693b..0000000
Binary files a/all_tools/skins/minimal_light/pick.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/pick_on.png b/all_tools/skins/minimal_light/pick_on.png
deleted file mode 100644
index 91d4b63..0000000
Binary files a/all_tools/skins/minimal_light/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/pin.png b/all_tools/skins/minimal_light/pin.png
deleted file mode 100644
index 5125e8b..0000000
Binary files a/all_tools/skins/minimal_light/pin.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/pin_on.png b/all_tools/skins/minimal_light/pin_on.png
deleted file mode 100644
index f7cdffe..0000000
Binary files a/all_tools/skins/minimal_light/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/play.png b/all_tools/skins/minimal_light/play.png
deleted file mode 100644
index 3e4c488..0000000
Binary files a/all_tools/skins/minimal_light/play.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/sections.png b/all_tools/skins/minimal_light/sections.png
deleted file mode 100644
index 20559ad..0000000
Binary files a/all_tools/skins/minimal_light/sections.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/sections_on.png b/all_tools/skins/minimal_light/sections_on.png
deleted file mode 100644
index ffe6bd5..0000000
Binary files a/all_tools/skins/minimal_light/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/zoomin.png b/all_tools/skins/minimal_light/zoomin.png
deleted file mode 100644
index 9c1c328..0000000
Binary files a/all_tools/skins/minimal_light/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/minimal_light/zoomout.png b/all_tools/skins/minimal_light/zoomout.png
deleted file mode 100644
index 22b32f9..0000000
Binary files a/all_tools/skins/minimal_light/zoomout.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/back.png b/all_tools/skins/transparent_dark/back.png
deleted file mode 100644
index 61e73ba..0000000
Binary files a/all_tools/skins/transparent_dark/back.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/close.png b/all_tools/skins/transparent_dark/close.png
deleted file mode 100644
index 4f7bb52..0000000
Binary files a/all_tools/skins/transparent_dark/close.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/close_on.png b/all_tools/skins/transparent_dark/close_on.png
deleted file mode 100644
index 30f4518..0000000
Binary files a/all_tools/skins/transparent_dark/close_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/color.png b/all_tools/skins/transparent_dark/color.png
deleted file mode 100644
index 3a7743e..0000000
Binary files a/all_tools/skins/transparent_dark/color.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/color_on.png b/all_tools/skins/transparent_dark/color_on.png
deleted file mode 100644
index f96d023..0000000
Binary files a/all_tools/skins/transparent_dark/color_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/exit.png b/all_tools/skins/transparent_dark/exit.png
deleted file mode 100644
index 1ce7ef4..0000000
Binary files a/all_tools/skins/transparent_dark/exit.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/full.png b/all_tools/skins/transparent_dark/full.png
deleted file mode 100644
index 6637f8b..0000000
Binary files a/all_tools/skins/transparent_dark/full.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/full_on.png b/all_tools/skins/transparent_dark/full_on.png
deleted file mode 100644
index 0e64024..0000000
Binary files a/all_tools/skins/transparent_dark/full_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/help.png b/all_tools/skins/transparent_dark/help.png
deleted file mode 100644
index e01668d..0000000
Binary files a/all_tools/skins/transparent_dark/help.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/help_on.png b/all_tools/skins/transparent_dark/help_on.png
deleted file mode 100644
index 68119d6..0000000
Binary files a/all_tools/skins/transparent_dark/help_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/home.png b/all_tools/skins/transparent_dark/home.png
deleted file mode 100644
index 2035e07..0000000
Binary files a/all_tools/skins/transparent_dark/home.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/light.png b/all_tools/skins/transparent_dark/light.png
deleted file mode 100644
index fa62449..0000000
Binary files a/all_tools/skins/transparent_dark/light.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/light_on.png b/all_tools/skins/transparent_dark/light_on.png
deleted file mode 100644
index 5b606c8..0000000
Binary files a/all_tools/skins/transparent_dark/light_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/measure.png b/all_tools/skins/transparent_dark/measure.png
deleted file mode 100644
index de0e49e..0000000
Binary files a/all_tools/skins/transparent_dark/measure.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/measure_on.png b/all_tools/skins/transparent_dark/measure_on.png
deleted file mode 100644
index fbb3fbd..0000000
Binary files a/all_tools/skins/transparent_dark/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/menu.png b/all_tools/skins/transparent_dark/menu.png
deleted file mode 100644
index d0dcd1f..0000000
Binary files a/all_tools/skins/transparent_dark/menu.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/next.png b/all_tools/skins/transparent_dark/next.png
deleted file mode 100644
index de9018b..0000000
Binary files a/all_tools/skins/transparent_dark/next.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/pick.png b/all_tools/skins/transparent_dark/pick.png
deleted file mode 100644
index 8df40ed..0000000
Binary files a/all_tools/skins/transparent_dark/pick.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/pick_on.png b/all_tools/skins/transparent_dark/pick_on.png
deleted file mode 100644
index 655606a..0000000
Binary files a/all_tools/skins/transparent_dark/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/pin.png b/all_tools/skins/transparent_dark/pin.png
deleted file mode 100644
index 1efc727..0000000
Binary files a/all_tools/skins/transparent_dark/pin.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/pin_on.png b/all_tools/skins/transparent_dark/pin_on.png
deleted file mode 100644
index bea47d9..0000000
Binary files a/all_tools/skins/transparent_dark/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/play.png b/all_tools/skins/transparent_dark/play.png
deleted file mode 100644
index b5e0763..0000000
Binary files a/all_tools/skins/transparent_dark/play.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/sections.png b/all_tools/skins/transparent_dark/sections.png
deleted file mode 100644
index b94d61d..0000000
Binary files a/all_tools/skins/transparent_dark/sections.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/sections_on.png b/all_tools/skins/transparent_dark/sections_on.png
deleted file mode 100644
index 5488e7a..0000000
Binary files a/all_tools/skins/transparent_dark/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/zoomin.png b/all_tools/skins/transparent_dark/zoomin.png
deleted file mode 100644
index b9bfcfa..0000000
Binary files a/all_tools/skins/transparent_dark/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/transparent_dark/zoomout.png b/all_tools/skins/transparent_dark/zoomout.png
deleted file mode 100644
index 8c2fb05..0000000
Binary files a/all_tools/skins/transparent_dark/zoomout.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/back.png b/all_tools/skins/transparent_light/back.png
deleted file mode 100644
index 50a314a..0000000
Binary files a/all_tools/skins/transparent_light/back.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/close.png b/all_tools/skins/transparent_light/close.png
deleted file mode 100644
index 9b2d48d..0000000
Binary files a/all_tools/skins/transparent_light/close.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/close_on.png b/all_tools/skins/transparent_light/close_on.png
deleted file mode 100644
index e77636d..0000000
Binary files a/all_tools/skins/transparent_light/close_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/color.png b/all_tools/skins/transparent_light/color.png
deleted file mode 100644
index ca2c5a7..0000000
Binary files a/all_tools/skins/transparent_light/color.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/color_on.png b/all_tools/skins/transparent_light/color_on.png
deleted file mode 100644
index 50bd0d2..0000000
Binary files a/all_tools/skins/transparent_light/color_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/exit.png b/all_tools/skins/transparent_light/exit.png
deleted file mode 100644
index 81a1a0d..0000000
Binary files a/all_tools/skins/transparent_light/exit.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/full.png b/all_tools/skins/transparent_light/full.png
deleted file mode 100644
index 89ad9f9..0000000
Binary files a/all_tools/skins/transparent_light/full.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/full_on.png b/all_tools/skins/transparent_light/full_on.png
deleted file mode 100644
index 1a8f55d..0000000
Binary files a/all_tools/skins/transparent_light/full_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/help.png b/all_tools/skins/transparent_light/help.png
deleted file mode 100644
index faead33..0000000
Binary files a/all_tools/skins/transparent_light/help.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/help_on.png b/all_tools/skins/transparent_light/help_on.png
deleted file mode 100644
index fc373d6..0000000
Binary files a/all_tools/skins/transparent_light/help_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/home.png b/all_tools/skins/transparent_light/home.png
deleted file mode 100644
index 7a593b4..0000000
Binary files a/all_tools/skins/transparent_light/home.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/light.png b/all_tools/skins/transparent_light/light.png
deleted file mode 100644
index dbf44dc..0000000
Binary files a/all_tools/skins/transparent_light/light.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/light_on.png b/all_tools/skins/transparent_light/light_on.png
deleted file mode 100644
index 5b606c8..0000000
Binary files a/all_tools/skins/transparent_light/light_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/measure.png b/all_tools/skins/transparent_light/measure.png
deleted file mode 100644
index 67adc3b..0000000
Binary files a/all_tools/skins/transparent_light/measure.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/measure_on.png b/all_tools/skins/transparent_light/measure_on.png
deleted file mode 100644
index 376b639..0000000
Binary files a/all_tools/skins/transparent_light/measure_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/menu.png b/all_tools/skins/transparent_light/menu.png
deleted file mode 100644
index 3964fb3..0000000
Binary files a/all_tools/skins/transparent_light/menu.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/next.png b/all_tools/skins/transparent_light/next.png
deleted file mode 100644
index 6bbd18d..0000000
Binary files a/all_tools/skins/transparent_light/next.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/pick.png b/all_tools/skins/transparent_light/pick.png
deleted file mode 100644
index cccefa0..0000000
Binary files a/all_tools/skins/transparent_light/pick.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/pick_on.png b/all_tools/skins/transparent_light/pick_on.png
deleted file mode 100644
index 655606a..0000000
Binary files a/all_tools/skins/transparent_light/pick_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/pin.png b/all_tools/skins/transparent_light/pin.png
deleted file mode 100644
index bc40551..0000000
Binary files a/all_tools/skins/transparent_light/pin.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/pin_on.png b/all_tools/skins/transparent_light/pin_on.png
deleted file mode 100644
index d7a0903..0000000
Binary files a/all_tools/skins/transparent_light/pin_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/play.png b/all_tools/skins/transparent_light/play.png
deleted file mode 100644
index 3392036..0000000
Binary files a/all_tools/skins/transparent_light/play.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/sections.png b/all_tools/skins/transparent_light/sections.png
deleted file mode 100644
index 75d9de8..0000000
Binary files a/all_tools/skins/transparent_light/sections.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/sections_on.png b/all_tools/skins/transparent_light/sections_on.png
deleted file mode 100644
index 5488e7a..0000000
Binary files a/all_tools/skins/transparent_light/sections_on.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/zoomin.png b/all_tools/skins/transparent_light/zoomin.png
deleted file mode 100644
index a78f9a1..0000000
Binary files a/all_tools/skins/transparent_light/zoomin.png and /dev/null differ
diff --git a/all_tools/skins/transparent_light/zoomout.png b/all_tools/skins/transparent_light/zoomout.png
deleted file mode 100644
index 545e7e7..0000000
Binary files a/all_tools/skins/transparent_light/zoomout.png and /dev/null differ
diff --git a/all_tools/stylesheet/3dhop.css b/all_tools/stylesheet/3dhop.css
deleted file mode 100644
index 803eea1..0000000
--- a/all_tools/stylesheet/3dhop.css
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-body { width:100%; height:100%; margin:0px; }
-
-.tdhop { position:relative; width:100%; height:100%; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-#tdhlg { position:absolute; right:2; bottom:2; width:105px; height:13px; overflow:hidden; cursor:pointer; color:#909090; text-decoration:none; font-family:verdana; font-style:italic; font-size:10px; line-height:13px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-#toolbar { position:absolute; left:10px; top:10px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-#toolbar img { margin-bottom:8px; width:50px; height:50px; opacity:0.5; cursor:pointer; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-.output-box { position:absolute; display:none; border-radius:5px; margin:0; height:48px; padding:0px 5px 2px 5px; cursor:default; background-color:rgba(125,125,125,0.5); color:#f8f8f8; text-decoration:none; text-align:center; font-family:verdana; font-style:italic; font-size:12px; line-height:20px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-.output-text { padding:0px 5px 0px 5px; cursor:text; -webkit-user-select:text; -webkit-touch-callout:text; -khtml-user-select:text; -moz-user-select:text; -ms-user-select:text; user-select:text; }
-
-.output-input { vertical-align:middle; cursor:pointer; height:16px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-.output-table { margin:0; width:100%; color:#f8f8f8; text-align:center; font-style:italic; font-size:12px; line-height:15px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-.output-table img { height:25px; cursor:pointer; background-color:rgba(125,125,125,0.25); border:1px outset; border-radius:5px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; user-drag: none; -webkit-user-drag: none; }
-
-.output-table img:hover { background-color:rgba(125,125,125,0.8); }
-
-.output-box hr { margin:0 0 3px 0; border:0; height:1px; background-image:linear-gradient(to right, rgba(0, 0, 0, 0), rgba(225, 225, 225, 0.75), rgba(0, 0, 0, 0)); }
-
-#draw-canvas { background-repeat:no-repeat; background-position:center top; -webkit-background-size:cover; -moz-background-size:cover; -o-background-size:cover; background-size:cover; outline:none; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-
-
-/*DEPRECATED*/
-#measurebox { position:absolute; visibility:hidden; overflow:hidden; border-radius:5px; right:10; top:10; margin:0; width:105px; height:26px; cursor:default; color:#909090; text-decoration:none; text-align:center; font-family:verdana; font-style:italic; font-size:10px; line-height:13px; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; -webkit-tap-highlight-color: rgba(0,0,0,0); -webkit-tap-highlight-color: transparent; }
-#measure-output { cursor:text; -webkit-user-select:text; -webkit-touch-callout:text; -khtml-user-select:text; -moz-user-select:text; -ms-user-select:text; user-select:text; }
diff --git a/all_tools/stylesheet/help_spots.css b/all_tools/stylesheet/help_spots.css
deleted file mode 100644
index b00af2b..0000000
--- a/all_tools/stylesheet/help_spots.css
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
-3DHOP - 3D Heritage Online Presenter
-Copyright (c) 2014-2016, Marco Callieri - Visual Computing Lab, ISTI - CNR
-All rights reserved.
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-
-/*HELP PANEL*/
-#cover{ display:none; position:fixed; z-index:20; width:100%; height:100%; top:0; left:0; padding-bottom:20px; background-color:rgba(50, 50, 50, 0.5); }
-
-.panel { display:none; width:550px; font-size:80%; font-family:verdana; font-style:italic; color:#f8f8f8; text-align:center; background-color:rgba(50, 50, 50, 0.97); border:2px solid #f8f8f8; border-radius:10px;box-shadow:1px 1px 10px #f8f8f8;-webkit-box-shadow:1px 1px 10px #f8f8f8;-moz-box-shadow:1px 1px 10px #f8f8f8;cursor:default; text-decoration:none; -webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; }
-
-.close { position:relative; margin-left:99%; margin-top:-25px;width:25px; height:25px;background-color:#f8f8f8; border:2px solid #f8f8f8; border-radius:50%; box-shadow:1px -1px 10px #f8f8f8;-webkit-box-shadow:1px -1px 10px #f8f8f8;-moz-box-shadow:1px -1px 10px #f8f8f8;-webkit-user-select:none; -webkit-touch-callout:none; -khtml-user-select:none; -moz-user-select:none; -ms-user-select:none; user-select:none; touch-action:none; -ms-touch-action:none; }
-
-.close:hover { background-color:rgba(255, 0, 110, 1.0); cursor:pointer; }
\ No newline at end of file
diff --git a/all_tools/index.html b/minimal/index_all_tools.html
similarity index 100%
rename from all_tools/index.html
rename to minimal/index_all_tools.html
diff --git a/minimal/index.html b/minimal/index_no_tools.html
similarity index 100%
rename from minimal/index.html
rename to minimal/index_no_tools.html
diff --git a/minimal/js/trackball_pantilt.js b/minimal/js/trackball_pantilt.js
index b0bd74d..a9e111f 100644
--- a/minimal/js/trackball_pantilt.js
+++ b/minimal/js/trackball_pantilt.js
@@ -318,8 +318,9 @@ PanTiltTrackball.prototype = {
},
pan: function(m, dx, dy) {
- this._panX -= dx/2.0;
- this._panY -= dy/2.0;
+ var panSpeed = Math.max(Math.min(1.5, this._distance),0.05);
+ this._panX -= dx/2.0 * panSpeed;
+ this._panY -= dy/2.0 * panSpeed;
this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);
this._panY = this.clamp(this._panY, this._minMaxPanY[0], this._minMaxPanY[1]);
},
diff --git a/minimal/js/trackball_turntable_pan.js b/minimal/js/trackball_turntable_pan.js
index e5916ad..86a1e65 100644
--- a/minimal/js/trackball_turntable_pan.js
+++ b/minimal/js/trackball_turntable_pan.js
@@ -377,9 +377,10 @@ TurntablePanTrackball.prototype = {
Yvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]), Yvec);
Zvec = SglMat4.mul4(SglMat4.rotationAngleAxis(this._theta, [1.0, 0.0, 0.0]), Zvec);
- this._panX += (dx * Xvec[0]) + (dy * Xvec[1]);
- this._panY += (dx * Yvec[0]) + (dy * Yvec[1]);
- this._panZ += (dx * Zvec[0]) + (dy * Zvec[1]);
+ var panSpeed = Math.max(Math.min(1.5, this._distance),0.05);
+ this._panX += ((dx * Xvec[0]) + (dy * Xvec[1])) * panSpeed;
+ this._panY += ((dx * Yvec[0]) + (dy * Yvec[1])) * panSpeed;
+ this._panZ += ((dx * Zvec[0]) + (dy * Zvec[1])) * panSpeed;
//clamping
this._panX = this.clamp(this._panX, this._minMaxPanX[0], this._minMaxPanX[1]);