>1)-1,e=(2|o&1)<=i||e>=this._dictionarySizeCheck)return!1;this._outWindow.copyBlock(e,m),i+=m,j=this._outWindow.getByte(0)}}this._outWindow.flush(),this._outWindow.releaseStream(),this._rangeDecoder.releaseStream();return!0},LZMA.Decoder.prototype.setDecoderProperties=function(a){var b,c,d,e,f;if(a.size<5)return!1;b=a.readByte(),c=b%9,b=~~(b/9),d=b%5,e=~~(b/5);if(!this.setLcLpPb(c,d,e))return!1;f=a.readByte(),f|=a.readByte()<<8,f|=a.readByte()<<16,f+=a.readByte()*16777216;return this.setDictionarySize(f)},LZMA.decompress=function(a,b,c,d){var e=new LZMA.Decoder;if(!e.setDecoderProperties(a))throw"Incorrect stream properties";if(!e.decode(b,c,d))throw"Error in data stream";return!0},LZMA.decompressFile=function(a,b){var c=new LZMA.Decoder,d;if(!c.setDecoderProperties(a))throw"Incorrect stream properties";d=a.readByte(),d|=a.readByte()<<8,d|=a.readByte()<<16,d+=a.readByte()*16777216,a.readByte(),a.readByte(),a.readByte(),a.readByte();if(!c.decode(a,b,d))throw"Error in data stream";return!0};var CTM=CTM||{};CTM.CompressionMethod={RAW:5718354,MG1:3229517,MG2:3295053},CTM.Flags={NORMALS:1},CTM.File=function(a){this.load(a)},CTM.File.prototype.load=function(a){this.header=new CTM.FileHeader(a),this.body=new CTM.FileBody(this.header),this.getReader().read(a,this.body)},CTM.File.prototype.getReader=function(){var a;switch(this.header.compressionMethod){case CTM.CompressionMethod.RAW:a=new CTM.ReaderRAW;break;case CTM.CompressionMethod.MG1:a=new CTM.ReaderMG1;break;case CTM.CompressionMethod.MG2:a=new CTM.ReaderMG2}return a},CTM.FileHeader=function(a){a.readInt32(),this.fileFormat=a.readInt32(),this.compressionMethod=a.readInt32(),this.vertexCount=a.readInt32(),this.triangleCount=a.readInt32(),this.uvMapCount=a.readInt32(),this.attrMapCount=a.readInt32(),this.flags=a.readInt32(),this.comment=a.readString()},CTM.FileHeader.prototype.hasNormals=function(){return this.flags&CTM.Flags.NORMALS},CTM.FileBody=function(a){var b=a.triangleCount*3,c=a.vertexCount*3,d=a.hasNormals()?a.vertexCount*3:0,e=a.vertexCount*2,f=a.vertexCount*4,g=0,h=new ArrayBuffer((b+c+d+e*a.uvMapCount+f*a.attrMapCount)*4);this.indices=new Uint32Array(h,0,b),this.vertices=new Float32Array(h,b*4,c),a.hasNormals()&&(this.normals=new Float32Array(h,(b+c)*4,d));if(a.uvMapCount){this.uvMaps=[];for(g=0;g0&&(a[2]+=a[0]);for(;c4?f=(n[o+2]*4/e-2)*q:f=(n[o+2]-2)*q,e*=c*q,g=d*Math.sin(e),h=g*Math.cos(f),i=g*Math.sin(f),j=d*Math.cos(e),l=b[o+1],k=b[o]-b[o+2],m=Math.sqrt(2*l*l+k*k),m>1e-20&&(k/=m,l/=m),a[o]=b[o]*j+(b[o+1]*l-b[o+2]*k)*i-l*h,a[o+1]=b[o+1]*j-(b[o+2]+b[o])*l*i+k*h,a[o+2]=b[o+2]*j+(b[o]*k+b[o+1]*l)*i+l*h)},CTM.restoreMap=function(a,b,c){var d,e,f=new Uint32Array(a.buffer,a.byteOffset,a.length),g=0,h,i=a.length;for(;g>1):e>>1,a[h]=d*c}},CTM.calcSmoothNormals=function(a,b){var c=new Float32Array(b.length),d,e,f,g,h,i,j,k,l,m,n,o,p,q,r;for(q=0,r=a.length;q1e-10&&(g/=p,h/=p,i/=p),c[d]+=g,c[d+1]+=h,c[d+2]+=i,c[e]+=g,c[e+1]+=h,c[e+2]+=i,c[f]+=g,c[f+1]+=h,c[f+2]+=i;for(q=0,r=c.length;q1e-10&&(c[q]/=p,c[q+1]/=p,c[q+2]/=p);return c},CTM.isLittleEndian=function(){var a=new ArrayBuffer(2),b=new Uint8Array(a),c=new Uint16Array(a);b[0]=1;return c[0]===1}(),CTM.InterleavedStream=function(a,b){this.data=new Uint8Array(a.buffer,a.byteOffset,a.byteLength),this.offset=CTM.isLittleEndian?3:0,this.count=b*4,this.len=this.data.length},CTM.InterleavedStream.prototype.writeByte=function(a){this.data[this.offset]=a,this.offset+=this.count,this.offset>=this.len&&(this.offset-=this.len-4,this.offset>=this.count&&(this.offset-=this.count+(CTM.isLittleEndian?1:-1)))},CTM.Stream=function(a){this.data=a,this.offset=0},CTM.Stream.prototype.TWO_POW_MINUS23=Math.pow(2,-23),CTM.Stream.prototype.TWO_POW_MINUS126=Math.pow(2,-126),CTM.Stream.prototype.readByte=function(){return this.data.charCodeAt(this.offset++)&255},CTM.Stream.prototype.readInt32=function(){var a=this.readByte();a|=this.readByte()<<8,a|=this.readByte()<<16;return a|this.readByte()<<24},CTM.Stream.prototype.readFloat32=function(){var a=this.readByte();a+=this.readByte()<<8;var b=this.readByte(),c=this.readByte();a+=(b&127)<<16;var d=(c&127)<<1|(b&128)>>>7,e=c&128?-1:1;if(d===255)return a!==0?NaN:e*Infinity;if(d>0)return e*(1+a*this.TWO_POW_MINUS23)*Math.pow(2,d-127);if(a!==0)return e*a*this.TWO_POW_MINUS126;return e*0},CTM.Stream.prototype.readString=function(){var a=this.readInt32();this.offset+=a;return this.data.substr(this.offset-a,a)},CTM.Stream.prototype.readArrayInt32=function(a){var b=0,c=a.length;while(b0&&(b=b.substr(0,b.indexOf("?")));var c=b.split("/"),d=c[2],e=c[0],f=[];for(var g=3;g65024){var g=[],h=[],i=[];for(var j=0;j0&&h.push(d[f[j]*3],d[f[j]*3+1],d[f[j]*3+2]),e.length>0&&i.push(e[f[j]*2],e[f[j]*2+1]);c=g,d=h,e=i,f=[]}var k=new a.Mesh;k.setPositions(c),d.length>0&&k.setNormals(d),e.length>0&&k.setUV(e),f.length>0&&k.setFaces(f),this.setMesh(k)},a.Document.prototype.getOpenCTM=function(b){if(!b.object){var c=this.getAbsolutePath(this.rootURL,null);b.object=new(a[this.classString(b.tagName)]),b.object.setSrc(b.getAttribute("src"),c),b.removeAttribute("src"),this.setProperties(b)}return b.object},a.Scene.prototype.addOpenCTM=a.Scene.prototype.addObject}(GLGE),function(a){a.Scene.prototype.physicsGravity=[0,0,-9.8,0],a.Scene.prototype.getPhysicsNodes=function(b){b||(b=[]),this.jigLibObj&&b.push(this);if(this.children)for(var c=0;c-1&&(this.constraints.push(a),this.physicsSystem&&this.physicsSystem.removeConstraint(a.constraint));return this}}(GLGE),function(a){a.PhysicsCar=function(b){a.PhysicsBox.call(this,b),this.wheels=[],this.setRotationalVelocityDamping([.1,.6,.1]),this.setLinearVelocityDamping([.996,.92,.996]);return this},a.augment(a.PhysicsBox,a.PhysicsCar),a.PhysicsCar.prototype.className="PhysicsCar",a.Group.prototype.addPhysicsCar=a.Group.prototype.addChild,a.Scene.prototype.addPhysicsCar=a.Group.prototype.addChild,a.PhysicsCar.prototype.drive=function(a){for(var b=0;b-1&&this.wheels.splice(c,1);return a.PhsyicsBox.prototype.addChild.call(this,b)},a.PhysicsCar.prototype.getScene=function(){var a=this;while(a.parent)a=a.parent;return a},a.PhysicsCar.prototype.preProcess=function(b){var c=this.getScene(),d=this.getVelocity(),e=this.getMass(),f=this.wheels;for(var g=0;gy&&(z=y)}if(h.driveForce){var B=h.driveForce*(1-h.braking);B<-x&&(B=x),B>x&&(B=x),this.addWorldForce(a.scaleVec3(l,B),m),z+=h.driveForce/e*b/n}if(h.braking){var C=a.dotVec3(d,l),D=-h.braking*C/b;D<-x&&(D=-x),D>x&&(D=x),this.addWorldForce(a.scaleVec3(l,D),m)}h.angVel+=z,h.brake&&(h.angVel*=1-h.braking),h.innerGroup.setRotZ(h.innerGroup.getRotZ()-h.angVel*b),h.angVel*=.995,h.oldPos=m}a.PhysicsBox.prototype.preProcess.call(this,b)},a.PhysicsWheel=function(b){a.Group.call(this,b),this.innerGroup=new a.Group,a.Group.prototype.addChild.call(this,this.innerGroup);return this},a.augment(a.Group,a.PhysicsWheel),a.PhysicsWheel.prototype.radius=1,a.PhysicsWheel.prototype.travel=.75,a.PhysicsWheel.prototype.angVel=0,a.PhysicsWheel.prototype.spring=90,a.PhysicsWheel.prototype.braking=0,a.PhysicsWheel.prototype.driveForce=0,a.PhysicsWheel.prototype.powered=!1,a.PhysicsWheel.prototype.sideFriction=3,a.PhysicsWheel.prototype.frontFriction=3,a.PhysicsWheel.prototype.className="PhysicsWheel",a.PhysicsWheel.prototype.addChild=function(a){return this.innerGroup.addChild(a)},a.PhysicsWheel.prototype.removeChild=function(a){return this.innerGroup.removeChild(a)},a.PhysicsWheel.prototype.addGroup=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.addCollada=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.addObject=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.addMD2=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.addMD3=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.addWavefront=a.PhysicsWheel.prototype.addChild,a.PhysicsWheel.prototype.setPowered=function(a){this.powered=a;return this},a.PhysicsWheel.prototype.setRadius=function(a){this.radius=a;return this},a.PhysicsWheel.prototype.setSpring=function(a){this.spring=a;return this},a.PhysicsWheel.prototype.setTravel=function(a){this.travel=a;return this},a.PhysicsWheel.prototype.setFrontFriction=function(a){this.frontFriction=a;return this},a.PhysicsWheel.prototype.setSideFriction=function(a){this.sideFriction=a;return this},a.PhysicsWheel.prototype.setWheelRotation=function(a){this.setRotY(a);return this},a.PhysicsWheel.prototype.getWheelRotation=function(a){return this.getRotY()},a.PhysicsWheel.prototype.getRadius=function(){return this.radius},a.PhysicsWheel.prototype.getSpring=function(){return this.spring},a.PhysicsWheel.prototype.getTravel=function(){return this.travel},a.PhysicsWheel.prototype.getFrontFriction=function(){return this.frontFriction},a.PhysicsWheel.prototype.getSideFriction=function(){return this.sideFriction},a.PhysicsWheel.prototype.drive=function(a){this.driveForce=a;return this},a.PhysicsWheel.prototype.brake=function(a){this.braking=a;return this}}(GLGE),function(a){a.FilePreloader=function(){this.files=[]},a.augment(a.Events,a.FilePreloader),a.FilePreloader.prototype.loadedBytes=0,a.FilePreloader.prototype.totalBytes=0,a.FilePreloader.prototype.numLoadedFiles=0,a.FilePreloader.prototype.numTotalFiles=0,a.FilePreloader.prototype.sizesCount=0,a.FilePreloader.prototype.progress=0,a.FilePreloader.prototype.files=null,a.FilePreloader.prototype.addFile=function(a,b,c){this.files.push({url:a,loaded:!1,size:-1,bytesLoaded:0,type:b,callback:c,content:null,preloader:this}),this.numTotalFiles++},a.FilePreloader.prototype.addFileRef=function(a){this.files.push(a),this.numTotalFiles++},a.FilePreloader.prototype.accumulateFileSize=function(a){var b=new XMLHttpRequest;b.preloader=this,b.active=!0,b.file=a,b.overrideMimeType("text/xml"),b.onreadystatechange=function(){this.readyState>1&&b.active&&(this.active=!1,this.file.size=parseFloat(this.getResponseHeader("Content-length")),this.preloader.totalBytes+=this.file.size,++this.preloader.sizesCount>=this.preloader.files.length&&this.preloader.loadFiles(),this.abort(),this.onreadystatechange=null)},b.open("GET",a.url,!0),b.send("")},a.FilePreloader.prototype.start=function(){for(i in this.files)this.accumulateFileSize(this.files[i])},a.FilePreloader.prototype.loadFiles=function(){for(i in this.files){var a=this.files[i];if(a.type=="image"){var b=new Image;a.content=b;var c=this;b.file=a,b.onload=function(){c.fileLoaded(this.file,this.file.size)},b.src=a.url}else{var d=new XMLHttpRequest;d.overrideMimeType("text/xml"),d.preloader=this,d.file=a;var e=setInterval(function(){if(d.readyState==3){var b=d.responseText.length-a.bytesLoaded;a.bytesLoaded=d.responseText.length,d.preloader.update(b)}},100);d.onreadystatechange=function(){if(this.readyState>=4){clearInterval(e),this.file.content=this.responseXML;var a=this.responseText.length-this.file.bytesLoaded;this.preloader.update(a),this.preloader.fileLoaded(this.file,a)}},d.open("GET",a.url,!0),d.send()}}},a.FilePreloader.prototype.update=function(a){this.loadedBytes+=a,this.progress=100*this.loadedBytes/this.totalBytes,this.fireEvent("progress",{progress:this.progress,stepBytes:a,loadedBytes:this.loadedBytes,totalBytes:this.totalBytes,loadedFiles:this.numLoadedFiles,totalFiles:this.numTotalFiles})},a.FilePreloader.prototype.fileLoaded=function(a,b){this.numLoadedFiles++,a.loaded=!0,a.bytesLoaded=a.size,this.numLoadedFiles0?(this.loadedBytes+=a.stepBytes,this.progress=this.XMLQuota*100*this.loadedBytes/this.XMLBytes):(this.progress+=this.XMLQuota*100/this.numXMLFiles,this.progress>this.XMLQuota*100&&(this.progress=this.XMLQuota*100)):this.progress=this.XMLQuota*100+this.imageQuota*this.imagePreloader.progress,this.fireEvent("progress",{progress:this.progress,stepBytes:a.stepBytes,loadedBytes:a.loadedBytes,totalBytes:a.totalBytes,loadedFiles:a.loadedFiles,totalFiles:a.totalFiles})},a.DocumentPreloader.prototype.loadXMLFile=function(b){this.changeState(1);var c=new a.FilePreloader;c.addFile(b,"xml");var d=this;this.XMLBytes>0?c.addEventListener("progress",function(a){d.updateProgress.call(d,a)}):c.addEventListener("downloadComplete",function(a){d.updateProgress.call(d,a)});var e=this.document;c.addEventListener("fileLoaded",function(a){a.file.content.getElementById=e.getElementById,e.loaded(a.file.url,a.file.content),d.fireEvent("fileLoaded",a.file)}),c.start()},a.DocumentPreloader.prototype.changeState=function(a){this.state=a,this.fireEvent("stateChange",a)},a.DocumentPreloader.prototype.finish=function(a){this.changeState(3),this.progress=100,this.fireEvent("downloadComplete")}}(GLGE),function(a){typeof a.GUI=="undefined"&&(a.GUI={}),function(b){b.useLibrary=function(a){a=="jQuery"&&jQuery&&(b.Progressbar.prototype.setValue=function(a){$(this.domRoot).progressbar({value:a})},b.Progressbar.prototype.init=function(){$(this.domRoot).progressbar({value:0})})},b.Widget=function(){this.domRoot=document.createElement("div"),this.domRoot.setAttribute("class","glge-gui-widget-root"),this.init()},b.Widget.prototype.domRoot=null,b.Widget.prototype.init=function(){},b.Progressbar=function(){this.baseclass.call(this),this.domRoot.className+=" glge-gui-progressbar"},b.Progressbar.prototype.value=0,b.Progressbar.prototype.setValue=function(a){this.value=a},a.augment(b.Widget,b.Progressbar)}(a.GUI)}(GLGE),function(a){typeof a.GUI=="undefined"&&(a.GUI={}),function(a){a.Gadget=function(){this.domGadgetRoot=document.createElement("div"),this.domGadgetRoot.setAttribute("class","glge-gui-gadget-root"),this.domGadgetRoot.style.position="absolute",this.domGadgetRoot.style.top="0px",this.domGadgetOuterWrapper=document.createElement("div"),this.domGadgetOuterWrapper.setAttribute("class","glge-gui-gadget-OuterWrapper"),this.domGadgetOuterWrapper.style.position="relative",this.domGadgetRoot.appendChild(this.domGadgetOuterWrapper),this.domGadgetInnerWrapper=document.createElement("div"),this.domGadgetInnerWrapper.setAttribute("class","glge-gui-gadget-InnerWrapper"),this.domGadgetInnerWrapper.style.position="relative",this.domGadgetOuterWrapper.appendChild(this.domGadgetInnerWrapper),this.domGadgetObject=document.createElement("div"),this.domGadgetObject.setAttribute("class","glge-gui-gadget"),this.domGadgetObject.style.position="relative",this.domGadgetInnerWrapper.appendChild(this.domGadgetObject),this.domGadgetFooter=document.createElement("div"),this.domGadgetFooter.setAttribute("class","glge-gui-gadget-footer"),this.domGadgetFooter.style.clear="both",this.domGadgetRoot.appendChild(this.domGadgetFooter),this.position={},this.position.x="middle",this.position.y="middle",this.updatePosition()},a.Gadget.prototype.domGadgetRoot=null,a.Gadget.prototype.domGadgetOuterWrapper=null,a.Gadget.prototype.domGadgetInnerWrapper=null,a.Gadget.prototype.domGadgetObject=null,a.Gadget.prototype.domGadgetFooter=null,a.Gadget.prototype.domGadgetParent=null,a.Gadget.prototype.position=null,a.Gadget.prototype.setPosition=function(a){a&&(a.x&&(this.position.x=a.x),a.y&&(this.position.y=a.y)),this.updatePosition()},a.Gadget.prototype.updatePosition=function(){if(this.domGadgetParent){var a="";document.defaultView&&document.defaultView.getComputedStyle?a=document.defaultView.getComputedStyle(this.domGadgetParent,null).getPropertyValue("position"):this.domGadgetParent.currentStyle&&(a=this.domGadgetParent.currentStyle.position),a=="absolute"?(this.domGadgetRoot.style.width="100%",this.domGadgetRoot.style.height="100%",this.domGadgetRoot.style.display="table",this.domGadgetOuterWrapper.style.display="table-cell",this.position.y=="top"?this.domGadgetOuterWrapper.style.verticalAlign="top":this.position.y=="middle"?this.domGadgetOuterWrapper.style.verticalAlign="middle":this.position.y=="bottom"&&(this.domGadgetOuterWrapper.style.verticalAlign="bottom"),this.position.x=="left"?(this.domGadgetInnerWrapper.style.cssFloat="left",this.domGadgetInnerWrapper.style.left="0px",this.domGadgetObject.style.cssFloat="left",this.domGadgetObject.style.left="0px"):this.position.x=="middle"?(this.domGadgetInnerWrapper.style.cssFloat="right",this.domGadgetInnerWrapper.style.right="50%",this.domGadgetObject.style.cssFloat="left",this.domGadgetObject.style.right="-50%"):this.position.x=="right"&&(this.domGadgetInnerWrapper.style.cssFloat="right",this.domGadgetInnerWrapper.style.right="0px",this.domGadgetObject.style.cssFloat="right",this.domGadgetObject.style.right="0px")):(this.position.y=="top"?this.domGadgetRoot.style.top=this.domGadgetParent.offsetTop:this.position.y=="middle"?this.domGadgetRoot.style.top=this.domGadgetParent.offsetTop+this.domGadgetParent.offsetHeight/2-this.domGadgetRoot.offsetHeight/2:this.position.y=="bottom"&&(this.domGadgetRoot.style.top=this.domGadgetParent.offsetTop+this.domGadgetParent.offsetHeight-this.domGadgetRoot.offsetHeight),this.position.x=="left"?this.domGadgetRoot.style.left=this.domGadgetParent.offsetLeft:this.position.x=="middle"?this.domGadgetRoot.style.left=this.domGadgetParent.offsetLeft+this.domGadgetParent.offsetWidth/2-this.domGadgetRoot.offsetWidth/2:this.position.x=="right"&&(this.domGadgetRoot.style.left=this.domGadgetParent.offsetLeft+this.domGadgetParent.offsetWidth-this.domGadgetRoot.offsetWidth))}},a.Gadget.prototype.addToDOM=function(a,b){this.domGadgetParent=a,this.domGadgetParent.appendChild(this.domGadgetRoot),this.setPosition(b)}}(a.GUI)}(GLGE),function(a){(function(b){b.Preloader=function(){this.baseclass.call(this),this.domGadgetObject.innerHTML="Loading
",this.domGadgetObject.className+=" glge-gui-gadget-preloader",this.progressBar=new b.Progressbar,this.domGadgetObject.appendChild(this.progressBar.domRoot),this.domPercentageLabel=document.createElement("div"),this.domPercentageLabel.setAttribute("class","glge-gui-gadget-preloader-percentage"),this.domPercentageLabel.innerHTML="0%
100%
",this.domGadgetObject.appendChild(this.domPercentageLabel),this.domInfoBox=document.createElement("div"),this.domInfoBox.setAttribute("class","glge-gui-gadget-preloader-info"),this.domInfoBox.setAttribute("style","clear:both;"),this.domGadgetObject.appendChild(this.domInfoBox),this.domStateLabel=document.createElement("div"),this.domInfoBox.appendChild(this.domStateLabel),this.domBytesLabel=document.createElement("div"),this.domInfoBox.appendChild(this.domBytesLabel),this.domFilesLabel=document.createElement("div"),this.domInfoBox.appendChild(this.domFilesLabel),this.domLastFileLabel=document.createElement("div"),this.domInfoBox.appendChild(this.domLastFileLabel)},b.Preloader.prototype.progressBar=null,b.Preloader.prototype.documentLoader=null,b.Preloader.prototype.domInfoBox=null,b.Preloader.prototype.domStateLabel=null,b.Preloader.prototype.domBytesLabel=null,b.Preloader.prototype.domFilesLabel=null,b.Preloader.prototype.domLastFileLabel=null,b.Preloader.prototype.domPercentageLabel=null,b.Preloader.prototype.setDocumentLoader=function(a){this.documentLoader=a;var b=this;this.documentLoader.addEventListener("downloadComplete",function(a){b.complete(a)}),this.documentLoader.addEventListener("progress",function(a){b.progress(a)}),this.documentLoader.addEventListener("stateChange",function(a){b.stateChange(a)}),this.documentLoader.addEventListener("fileLoaded",function(a){b.fileLoaded(a)})},b.Preloader.prototype.addToDOM=function(a,b){this.stateChange(this.documentLoader.state),this.progress({progress:0,loadedBytes:0,loadedFiles:0,totalFiles:0,totalBytes:0}),this.fileLoaded({}),this.baseclass.addToDOM.call(this,a,b)},b.Preloader.prototype.progress=function(a){this.progressBar.setValue(a.progress),this.domBytesLabel.innerHTML=a.loadedBytes+" of "+a.totalBytes+" Bytes loaded",this.domFilesLabel.innerHTML=a.loadedFiles+" of "+a.totalFiles+" Files loaded"},b.Preloader.prototype.complete=function(a){this.progressBar.setValue(100);var b=this;setTimeout(function(){b.domGadgetRoot.parentNode.removeChild(b.domGadgetRoot)},300)},b.Preloader.prototype.stateChange=function(a){switch(a){case 0:case 1:this.domStateLabel.innerHTML="Step 1 of 2: Loading XML";break;case 2:case 3:this.domStateLabel.innerHTML="Step 2 of 2: Loading Textures"}},b.Preloader.prototype.fileLoaded=function(a){if(a.url){var b=a.url;b.length>40&&(b=b.slice(-37),b="..."+b),this.domLastFileLabel.innerHTML='Last file loaded: "'+b+'"'}else this.domLastFileLabel.innerHTML==""&&(this.domLastFileLabel.innerHTML="Last file loaded: none")},a.augment(b.Gadget,b.Preloader)})(a.GUI)}(GLGE)
================================================
FILE: RecordRTC/WebGL-Recording/vendor/glge-compiled.js
================================================
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name GLGE_math.js
*/
if(typeof(GLGE) == "undefined"){
/**
* @namespace Holds the functionality of the library
*/
GLGE = {};
}
(function(GLGE){
var matrixCache=[];
//matrix reuse prevent so much GC
GLGE.reuseMatrix4=function(mat4){
//if(mat4 && mat4.length==16 && matrixCache<10000) matrixCache.push(mat4);
}
GLGE.matrix4=function(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16){
if(matrixCache.length==0){
var mat=[a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16];
}else{
var mat=matrixCache.shift();
mat[0]=a1;
mat[1]=a2;
mat[2]=a3;
mat[3]=a4;
mat[4]=a5;
mat[5]=a6;
mat[6]=a7;
mat[7]=a8;
mat[8]=a9;
mat[9]=a10;
mat[10]=a11;
mat[11]=a12;
mat[12]=a13;
mat[13]=a14;
mat[14]=a15;
mat[15]=a16;
}
return mat;
}
GLGE.Vec=function(array) {
return array.slice(0);
}
/**
* The Vec3 Class creates a vector
* @param {Array} array An array of 3 floats
*/
GLGE.Vec3=function(x,y,z){
return [x,y,z];
}
/**
* The Vec4 Class creates a vector
* @param {Array} array An array of 4 floats
*/
GLGE.Vec4=function(x,y,z,w){
return [x,y,z,w];
}
/**
* Gets the nth element (1 indexed) from the array
* @param {Array} v A vector with 4 elements
* @param {number} i The index from one
*/
GLGE.get1basedVec4=function(v,i){
return v[i-1];
};
/**
* Gets the nth element (1 indexed) from the array
* @param {Array} v A vector with 3 elements
* @param {number} i The index from one
*/
GLGE.get1basedVec3=function(v,i){
return v[i-1];
};
/**
* Gets the nth element (1 indexed) from the array
* @param {Array} v A vector with 4 elements
* @param {number} i The index from one
*/
GLGE.getVec4=function(v,i){
return v[i];
};
/**
* Gets the nth element (1 indexed) from the array
* @param {Array} v A vector with 3 elements
* @param {number} i The index from one
*/
GLGE.getVec3=function(v,i){
return v[i];
};
/**
* Adds a GLGE.Vec4 to this Vec4
* @param {Array} a The first value to add
* * @param {Array} b The second value to add
*/
GLGE.addVec4=function(a,b) {
return [a[0]+b[0],a[1]+b[1],a[2]+b[2],a[3]+b[3]];
}
/**
* Adds a GLGE.Vec3 to this GLGE.Vec3
* @param {Array} a The first value to add
* @param {Array} b The second value to add
*/
GLGE.addVec3=function(a,b) {
return [a[0]+b[0],a[1]+b[1],a[2]+b[2]];
}
/**
* Adds a GLGE.Vec4 to this Vec4
* @param {Array} a The first value
* * @param {Array} b The second value to subtract from the first
*/
GLGE.subVec4=function(a,b) {
return [a[0]-b[0],a[1]-b[1],a[2]-b[2],a[3]-b[3]];
}
/**
* Adds a GLGE.Vec3 to this GLGE.Vec3
* @param {Array} a The first value
* @param {Array} b The second value to subtract from the first
*/
GLGE.subVec3=function(a,b) {
return [a[0]-b[0],a[1]-b[1],a[2]-b[2]];
}
/**
* Negates a GLGE.Vec4
*/
GLGE.negVec4=function(a) {
return [-a[0], -a[1], -a[2], -a[3]];
}
GLGE.negVec3=function(a) {
return [-a[0], -a[1], -a[2]];
}
/**
* Gets the dot product between this and the input vector
* @param {Array} a the first value to dot
* @param {Array} b the second value to dot
*/
GLGE.dotVec3=function(a,b) {
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2];
}
/**
* Gets the dot product between this and the input vector
* @param {Array} a the first value to dot
* @param {Array} b the second value to dot
*/
GLGE.dotVec4=function(a,b) {
return a[0]*b[0]+a[1]*b[1]+a[2]*b[2]+a[3]*b[3];
}
/**
* Gets the dot product between this and the input vector
* @param {Array} a the vector to scale
* @param {Number} b the scalar
*/
GLGE.scaleVec4=function(a,b) {
return [a[0]*b,a[1]*b,a[2]*b,a[3]*b];
}
/**
* Gets the dot product between this and the input vector
* @param {Array} a the vector to scale
* @param {Number} b the scalar
*/
GLGE.scaleVec3=function(a,b) {
return [a[0]*b,a[1]*b,a[2]*b];
}
/**
* Gets the cross product between this and the input vector
* @param {Array} a the first value to dot
* @param {Array} b the second value to dot
*/
GLGE.crossVec3=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]];
}
/**
* Returns a unitized version of the input vector3
* @param {Array} a the vector3 to be unitized
*/
GLGE.toUnitVec3=function(a) {
var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2];
var f=1.0;
if (sq>0) {
f=Math.pow(sq,0.5);
}
return [a[0]/f,a[1]/f,a[2]/f];
};
/**
* Returns a unitized version of the input vector4
* @param {Array} a the vector4 to be unitized
*/
GLGE.toUnitVec4=function(a) {
var sq=a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3];
var f=1.0;
if (sq>0) {
f=Math.pow(sq,0.5);
}
return [a[0]/f,a[1]/f,a[2]/f,a[3]/f];
};
/**
* Returns the length of a vector3
* @param {Array} a the vector to be measured
*/
GLGE.lengthVec3=function(a) {
return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2],0.5);
};
/**
* Returns the distance between 2 vector3s
* @param {Array} a the first vector
* @param {Array} b the second vector
*/
GLGE.distanceVec3=function(a,b){
return GLGE.lengthVec3(GLGE.subVec3(a,b));
};
/**
* Returns the length of a vector3
* @param {Array} a the vector to be measured
*/
GLGE.lengthVec4=function(a,b) {
return Math.pow(a[0]*a[0]+a[1]*a[1]+a[2]*a[2]+a[3]*a[3],0.5);
};
/**
* Returns the distance between 2 vector4s
* @param {Array} a the first vector
* @param {Array} b the second vector
*/
GLGE.distanceVec4=function(a,b){
return GLGE.lengthVec4(GLGE.subVec4(a,b));
};
/**
* Returns the angle between 2 vector3s in radians
* @param {Array} a the first vector
* @param {Array} b the second vector
*/
GLGE.angleVec3=function(a,b){
a=GLGE.toUnitVec3(a);
b=GLGE.toUnitVec3(b);
d=GLGE.dotVec3(a,b);
if (d<-1)
d=-1;
if (d>1)
d=1;
return Math.acos(d);
};
/**
* Returns the angle between 2 vector4s in radians
* @param {Array} a the first vector
* @param {Array} b the second vector
*/
GLGE.angleVec4=function(a,b){
a=GLGE.toUnitVec4(a);
b=GLGE.toUnitVec4(b);
d=GLGE.dotVec4(a,b);
if (d<-1)
d=-1;
if (d>1)
d=1;
return Math.acos(d);
};
GLGE_math_use_webgl_float=false;
/**
* The Mat class creates a matrix from an array
* @param {Array} array An array of 9 or 16 floats
*/
GLGE.Mat3=GLGE_math_use_webgl_float?function(array) {
if (array.length==9) {
return new Float32Array(array);
}else if (array.length==16) {
return new Float32Array([array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]]);
}else {
throw "invalid matrix length";
}
}:function(array) {
var retval;
if (array.length==9) {
retval=array.slice(0);
}else if (array.length==16) {
retval=[array[0],array[1],array[2],array[4],array[5],array[6],array[8],array[9],array[10]];
}else {
throw "invalid matrix length";
}
retval.get=function(i){return this[i];};
return retval;
};
GLGE.Mat=GLGE_math_use_webgl_float?function(array) {
return new Float32Array(array);
}:function(array){
var retval=array.slice(0);
retval.get=function(i){return this[i];};
return retval;
};
GLGE.Mat4=function(array) {
var retval;
if (array.length==9) {
retval=[array[0],array[1],array[2],0,array[3],array[4],array[5],0,array[6],array[7],array[8],0,0,0,0,1];
}else if (array.length==16) {
if(array.slice) retval=array.slice(0);
else retval=array.subarray(0);
}else {
throw "invalid matrix length";
}
retval.get=function(i){return this[i];};
return retval;
};
/**
* Finds the determinate of the matrix
* @returns {number} the determinate
*/
GLGE.determinantMat4=function(m) {
return m[12] * m[9] * m[6] * m[3] - m[8] * m[13] * m[6] * m[3] - m[12] * m[5] * m[10] * m[3] + m[4] * m[13] * m[10] * m[3] + m[8] * m[5] * m[14] * m[3] - m[4] * m[9] * m[14] * m[3] - m[12] * m[9] * m[2] * m[7] + m[8] * m[13] * m[2] * m[7] + m[12] * m[1] * m[10] * m[7] - m[0] * m[13] * m[10] * m[7] - m[8] * m[1] * m[14] * m[7] + m[0] * m[9] * m[14] * m[7] + m[12] * m[5] * m[2] * m[11] - m[4] * m[13] * m[2] * m[11] - m[12] * m[1] * m[6] * m[11] + m[0] * m[13] * m[6] * m[11] + m[4] * m[1] * m[14] * m[11] - m[0] * m[5] * m[14] * m[11] - m[8] * m[5] * m[2] * m[15] + m[4] * m[9] * m[2] * m[15] + m[8] * m[1] * m[6] * m[15] - m[0] * m[9] * m[6] * m[15] - m[4] * m[1] * m[10] * m[15] + m[0] * m[5] * m[10] * m[15];
};
/**
* Finds the inverse of the matrix
* @returns {GLGE.Mat} the inverse
*/
GLGE.inverseMat4=function(mat){
// Cache the matrix values (makes for huge speed increases!)
var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
var d = a30*a21*a12*a03 - a20*a31*a12*a03 - a30*a11*a22*a03 + a10*a31*a22*a03 +
a20*a11*a32*a03 - a10*a21*a32*a03 - a30*a21*a02*a13 + a20*a31*a02*a13 +
a30*a01*a22*a13 - a00*a31*a22*a13 - a20*a01*a32*a13 + a00*a21*a32*a13 +
a30*a11*a02*a23 - a10*a31*a02*a23 - a30*a01*a12*a23 + a00*a31*a12*a23 +
a10*a01*a32*a23 - a00*a11*a32*a23 - a20*a11*a02*a33 + a10*a21*a02*a33 +
a20*a01*a12*a33 - a00*a21*a12*a33 - a10*a01*a22*a33 + a00*a11*a22*a33;
return GLGE.matrix4((a21*a32*a13 - a31*a22*a13 + a31*a12*a23 - a11*a32*a23 - a21*a12*a33 + a11*a22*a33)/d,
(a31*a22*a03 - a21*a32*a03 - a31*a02*a23 + a01*a32*a23 + a21*a02*a33 - a01*a22*a33)/d,
(a11*a32*a03 - a31*a12*a03 + a31*a02*a13 - a01*a32*a13 - a11*a02*a33 + a01*a12*a33)/d,
(a21*a12*a03 - a11*a22*a03 - a21*a02*a13 + a01*a22*a13 + a11*a02*a23 - a01*a12*a23)/d,
(a30*a22*a13 - a20*a32*a13 - a30*a12*a23 + a10*a32*a23 + a20*a12*a33 - a10*a22*a33)/d,
(a20*a32*a03 - a30*a22*a03 + a30*a02*a23 - a00*a32*a23 - a20*a02*a33 + a00*a22*a33)/d,
(a30*a12*a03 - a10*a32*a03 - a30*a02*a13 + a00*a32*a13 + a10*a02*a33 - a00*a12*a33)/d,
(a10*a22*a03 - a20*a12*a03 + a20*a02*a13 - a00*a22*a13 - a10*a02*a23 + a00*a12*a23)/d,
(a20*a31*a13 - a30*a21*a13 + a30*a11*a23 - a10*a31*a23 - a20*a11*a33 + a10*a21*a33)/d,
(a30*a21*a03 - a20*a31*a03 - a30*a01*a23 + a00*a31*a23 + a20*a01*a33 - a00*a21*a33)/d,
(a10*a31*a03 - a30*a11*a03 + a30*a01*a13 - a00*a31*a13 - a10*a01*a33 + a00*a11*a33)/d,
(a20*a11*a03 - a10*a21*a03 - a20*a01*a13 + a00*a21*a13 + a10*a01*a23 - a00*a11*a23)/d,
(a30*a21*a12 - a20*a31*a12 - a30*a11*a22 + a10*a31*a22 + a20*a11*a32 - a10*a21*a32)/d,
(a20*a31*a02 - a30*a21*a02 + a30*a01*a22 - a00*a31*a22 - a20*a01*a32 + a00*a21*a32)/d,
(a30*a11*a02 - a10*a31*a02 - a30*a01*a12 + a00*a31*a12 + a10*a01*a32 - a00*a11*a32)/d,
(a10*a21*a02 - a20*a11*a02 + a20*a01*a12 - a00*a21*a12 - a10*a01*a22 + a00*a11*a22)/d)
};
/**
* multiplies two mat4's
* @returns {GLGE.Mat} the matrix multiplication of the matrices
*/
GLGE.mulMat4Vec3=function(mat1,vec2){
return GLGE.Vec3(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3],
mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7],
mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]);
};
/**
* multiplies two mat4's
* @returns {GLGE.Mat} the matrix multiplication of the matrices
*/
GLGE.mulMat4Vec4=function(mat1,vec2){
return GLGE.Vec4(mat1[0]*vec2[0]+mat1[1]*vec2[1]+mat1[2]*vec2[2]+mat1[3]*vec2[3],
mat1[4]*vec2[0]+mat1[5]*vec2[1]+mat1[6]*vec2[2]+mat1[7]*vec2[3],
mat1[8]*vec2[0]+mat1[9]*vec2[1]+mat1[10]*vec2[2]+mat1[11]*vec2[3],
mat1[12]*vec2[0]+mat1[13]*vec2[1]+mat1[14]*vec2[2]+mat1[15]*vec2[3]);
};
/**
* multiplies a Mat4 by a scalar value
* @returns {GLGE.Mat} the matrix multiplication of the matrices
*/
GLGE.scaleMat4=function(m,value) {
return GLGE.matrix4([m[0]*value,m[1]*value,m[2]*value,m[3]*value,
m[4]*value,m[5]*value,m[6]*value,m[7]*value,
m[8]*value,m[9]*value,m[10]*value,m[11]*value,
m[12]*value,m[13]*value,m[14]*value,m[15]*value]);
};
/**
* multiplies a Mat4 by a scalar value in place without allocation
* @returns {GLGE.Mat} the input matrix, modified
*/
GLGE.scaleInPlaceMat4=function(m,value) {
m.set(0,m[0]*value);
m.set(1,m[1]*value);
m.set(2,m[2]*value);
m.set(3,m[3]*value);
m.set(4,m[4]*value);
m.set(5,m[5]*value);
m.set(6,m[6]*value);
m.set(7,m[7]*value);
m.set(8,m[8]*value);
m.set(9,m[9]*value);
m.set(10,m[10]*value);
m.set(11,m[11]*value);
m.set(12,m[12]*value);
m.set(13,m[13]*value);
m.set(14,m[14]*value);
m.set(15,m[15]*value);
return m;
};
/**
* adds a Mat4 to another Mat4 in place without allocation
* @returns {GLGE.Mat} the first input matrix, modified to be added
*/
GLGE.addInPlaceMat4=function(m,value) {
m.set(0,m[0]+value[0]);
m.set(1,m[1]+value[1]);
m.set(2,m[2]+value[2]);
m.set(3,m[3]+value[3]);
m.set(4,m[4]+value[4]);
m.set(5,m[5]+value[5]);
m.set(6,m[6]+value[6]);
m.set(7,m[7]+value[7]);
m.set(8,m[8]+value[8]);
m.set(9,m[9]+value[9]);
m.set(10,m[10]+value[10]);
m.set(11,m[11]+value[11]);
m.set(12,m[12]+value[12]);
m.set(13,m[13]+value[13]);
m.set(14,m[14]+value[14]);
m.set(15,m[15]+value[15]);
return m;
};
/**
* adds two Mat4 together
* @returns {GLGE.Mat} a new, added Mat4
*/
GLGE.addMat4=function(m,value) {
return GLGE.Mat([m[0]+value[0],
m[1]+value[1],
m[2]+value[2],
m[3]+value[3],
m[4]+value[4],
m[5]+value[5],
m[6]+value[6],
m[7]+value[7],
m[8]+value[8],
m[9]+value[9],
m[10]+value[10],
m[11]+value[11],
m[12]+value[12],
m[13]+value[13],
m[14]+value[14],
m[15]+value[15]]);
return m;
};
/**
* subs a Mat4 from another Mat4 in place without allocation
* @returns {GLGE.Mat} the first input matrix, modified to have the second subtacted
*/
GLGE.subInPlaceMat4=function(m,value) {
m.set(0,m[0]-value[0]);
m.set(1,m[1]-value[1]);
m.set(2,m[2]-value[2]);
m.set(3,m[3]-value[3]);
m.set(4,m[4]-value[4]);
m.set(5,m[5]-value[5]);
m.set(6,m[6]-value[6]);
m.set(7,m[7]-value[7]);
m.set(8,m[8]-value[8]);
m.set(9,m[9]-value[9]);
m.set(10,m[10]-value[10]);
m.set(11,m[11]-value[11]);
m.set(12,m[12]-value[12]);
m.set(13,m[13]-value[13]);
m.set(14,m[14]-value[14]);
m.set(15,m[15]-value[15]);
return m;
};
/**
* subtracts the second matrix from the first
* @returns {GLGE.Mat} a new, subed Mat4
*/
GLGE.subMat4=function(m,value) {
return GLGE.Mat([m[0]-value[0],
m[1]-value[1],
m[2]-value[2],
m[3]-value[3],
m[4]-value[4],
m[5]-value[5],
m[6]-value[6],
m[7]-value[7],
m[8]-value[8],
m[9]-value[9],
m[10]-value[10],
m[11]-value[11],
m[12]-value[12],
m[13]-value[13],
m[14]-value[14],
m[15]-value[15]]);
return m;
};
/**
* Finds the matrix multiplication with another GLGE.Mat or GLGE.vec or an Array of length 3-4
* @param {object} value An GLGE.Mat, GLGE.vec or Array
* @returns {GLGE.Mat|GLGE.Vec}
*/
GLGE.mulMat4=function(mat2,mat1){
var a00 = mat1[0], a01 = mat1[1], a02 = mat1[2], a03 = mat1[3];
var a10 = mat1[4], a11 = mat1[5], a12 = mat1[6], a13 = mat1[7];
var a20 = mat1[8], a21 = mat1[9], a22 = mat1[10], a23 = mat1[11];
var a30 = mat1[12], a31 = mat1[13], a32 = mat1[14], a33 = mat1[15];
var b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], b03 = mat2[3];
var b10 = mat2[4], b11 = mat2[5], b12 = mat2[6], b13 = mat2[7];
var b20 = mat2[8], b21 = mat2[9], b22 = mat2[10], b23 = mat2[11];
var b30 = mat2[12], b31 = mat2[13], b32 = mat2[14], b33 = mat2[15];
return GLGE.matrix4(b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30,
b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31,
b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32,
b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33,
b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30,
b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31,
b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32,
b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33,
b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30,
b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31,
b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32,
b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33,
b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30,
b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31,
b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32,
b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33);
};
GLGE.transposeInPlaceMat4=function(m) {
var v=m[1];
m.set(1,m[4]);
m.set(4,v);
v=m[8];
m.set(8,m[2]);
m.set(2,v);
v=m[3];
m.set(3,m[12]);
m.set(12,v);
v=m[9];
m.set(9,m[6]);
m.set(6,v);
v=m[13];
m.set(13,m[7]);
m.set(7,v);
v=m[14];
m.set(14,m[11]);
m.set(11,v);
};
/**
* Builds the transpose of the matrix
* @returns {GLGE.Mat} the transposed matrix
*/
GLGE.transposeMat4=function(m) {
return GLGE.matrix4(m[0],m[4],m[8],m[12],
m[1],m[5],m[9],m[13],
m[2],m[6],m[10],m[14],
m[3],m[7],m[11],m[15]);
};
/**
* copys a js array into a webglarray
* @param {array} mat the source array
* @param {webglarray} glarray the destination array
*/
GLGE.mat4gl=function(mat,glarray){
glarray[0]=mat[0];
glarray[1]=mat[1];
glarray[2]=mat[2];
glarray[3]=mat[3];
glarray[4]=mat[4];
glarray[5]=mat[5];
glarray[6]=mat[6];
glarray[7]=mat[7];
glarray[8]=mat[8];
glarray[9]=mat[9];
glarray[10]=mat[10];
glarray[11]=mat[11];
glarray[12]=mat[12];
glarray[13]=mat[13];
glarray[14]=mat[14];
glarray[15]=mat[15];
};
/**
* Sets the value at the specified index
* @param {number} i the first index 1 offset
* @param {number} j the second index 1 offset
* @param {number} value the value to set
*/
GLGE.set1basedMat4=function(m,i,j,value){
m[(i-1)*4+(j-1)]=value;
if(m.glData!==undefined){
delete m.glData;
}
};
/**
* Sets the value at the specified index
* @param {number} i the first index from zero
* @param {number} j the second index from zero
* @param {number} value the value to set
*/
GLGE.setMat4=function(m,i,j,value){
m[i*4+j]=value;
if(m.glData!==undefined){
delete m.glData;
}
};
/**
* Gets the value at the specified index
* @param {number} i the first index from one
* @param {number} j the second index from one
* @returns {number} the value at the given index
*/
GLGE.get1basedMat4=function(m,i,j){
return m.get((i-1)*4+(j-1));
};
/**
* Gets the value at the specified index
* @param {number} i the first index from zero
* @param {number} j the second index from zero
* @returns {number} the value at the given index
*/
GLGE.getMat4=function(m,i,j){
return m[i*4+j];
};
/**
* gets the a webgl float array for this Matrix, once generated it will cache it so it doesn't need to recreate everytime
* @returns {Float32Array} the webgl array for this Matrix
* @private
*/
GLGE.glDataMat4=function(m) {
m.glArray=new Float32Array(m);
return m.glArray;
};
/**
* Creates an identity matrix
* @returns {GLGE.Mat} the identity matrix
*/
GLGE.identMatrix=function(){
return GLGE.matrix4(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1);
};
/**
* Creates a translation matrix
* @returns {Array} value an array GLGE.Vec or 3 paramters
* @returns {GLGE.Mat} the translation matrix
*/
GLGE.translateMatrix=function(value){
var x;
var y;
var z;
if(arguments.length==3){
x=arguments[0];
y=arguments[1];
z=arguments[2];
}
else if(value.data){
x=value.data[0];
y=value.data[1];
z=value.data[2];
}
else if(value instanceof Array){
x=value[0];
y=value[1];
z=value[2];
}
return GLGE.matrix4(
1,0,0,x,
0,1,0,y,
0,0,1,z,
0,0,0,1
);
};
/**
* Creates a scale matrix
* @returns {Array} value an array GLGE.Vec or 3 paramters
* @returns {GLGE.Mat} the scale matrix
*/
GLGE.scaleMatrix=function(value){
var x;
var y;
var z;
if(arguments.length==3){
x=arguments[0];
y=arguments[1];
z=arguments[2];
}
else if(value.data){
x=value.data[0];
y=value.data[1];
z=value.data[2];
}
else if(value instanceof Array){
x=value[0];
y=value[1];
z=value[2];
}
return GLGE.matrix4(
x,0,0,0,
0,y,0,0,
0,0,z,0,
0,0,0,1
);
}
/**
* @constant
* @description Enum for XYZ rotation order
*/
GLGE.ROT_XYZ=1;
/**
* @constant
* @description Enum for XZY rotation order
*/
GLGE.ROT_XZY=2;
/**
* @constant
* @description Enum for YXZ rotation order
*/
GLGE.ROT_YXZ=3;
/**
* @constant
* @description Enum for YZX rotation order
*/
GLGE.ROT_YZX=4;
/**
* @constant
* @description Enum for ZXY rotation order
*/
GLGE.ROT_ZXY=5;
/**
* @constant
* @description Enum for ZYX rotation order
*/
GLGE.ROT_ZYX=6;
/**
* Creates a rotation matrix
* @returns {Array} value an array GLGE.Vec or 3 paramters
* @returns {GLGE.Mat} the rotation matrix
*/
GLGE.rotateMatrix=function(value,type) {
var x;
var y;
var z;
if(arguments.length>2){
x=arguments[0];
y=arguments[1];
z=arguments[2];
type=arguments[3];
}
else if(value.data){
x=value.data[0];
y=value.data[1];
z=value.data[2];
}
else if(value instanceof Array){
x=value[0];
y=value[1];
z=value[2];
}
if(!type) type=GLGE.ROT_XYZ;
var cosx=Math.cos(x);
var sinx=Math.sin(x);
var cosy=Math.cos(y);
var siny=Math.sin(y);
var cosz=Math.cos(z);
var sinz=Math.sin(z);
var rotx=GLGE.matrix4(1,0,0,0,0,cosx,-sinx,0,0,sinx,cosx,0,0,0,0,1);
var roty=GLGE.matrix4(cosy,0,siny,0,0,1,0,0,-siny,0,cosy,0,0,0,0,1);
var rotz=GLGE.matrix4(cosz,-sinz,0,0,sinz,cosz,0,0,0,0,1,0,0,0,0,1);
switch(type){
case GLGE.ROT_XYZ:
return GLGE.mulMat4(rotx,GLGE.mulMat4(roty,rotz));
break;
case GLGE.ROT_XZY:
return GLGE.mulMat4(rotx,GLGE.mulMat4(rotz,roty));
break;
case GLGE.ROT_YXZ:
return GLGE.mulMat4(roty,GLGE.mulMat4(rotx,rotz));
break;
case GLGE.ROT_YZX:
return GLGE.mulMat4(roty,GLGE.mulMat4(rotz,rotx));
break;
case GLGE.ROT_ZXY:
return GLGE.mulMat4(rotz,GLGE.mulMat4(rotx,roty));
break;
case GLGE.ROT_ZYX:
return GLGE.mulMat4(rotz,GLGE.mulMat4(roty,rotx));
break;
}
}
GLGE.angleAxis=function(angle, axis) {
var xmx,ymy,zmz,xmy,ymz,zmx,xms,yms,zms;
axis=[axis[0],axis[1],axis[2],0];
var x = axis[0];
var y = axis[1];
var z = axis[2];
var cos = Math.cos(angle);
var cosi = 1.0 - cos;
var sin = Math.sin(angle);
xms = x * sin;yms = y * sin;zms = z * sin;
xmx = x * x;ymy = y * y;zmz = z * z;
xmy = x * y;ymz = y * z;zmx = z * x;
var matrix = GLGE.matrix4((cosi * xmx) + cos,(cosi * xmy) - zms,(cosi * zmx) + yms,0,
(cosi * xmy) + zms,(cosi * ymy) + cos,(cosi * ymz) - xms,0,
(cosi * zmx) - yms,(cosi * ymz) + xms,(cosi * zmz) + cos,0,
0,0,0,1);
return GLGE.Mat(matrix);
};
// JHD
GLGE.quatFromAxisAngle = function(axis, angle) {
var quaternion = [];
var halfAngle = angle * 0.5;
var sinus = Math.sin(halfAngle);
var cosinus = Math.cos(halfAngle);
quaternion[0] = axis[0] * sinus;
quaternion[1] = axis[1] * sinus;
quaternion[2] = axis[2] * sinus;
quaternion[3] = cosinus;
return quaternion;
};
GLGE.mulQuat = function(quaternion1, quaternion2) {
var quaternion = [];
var x = quaternion1[0];
var y = quaternion1[1];
var z = quaternion1[2];
var w = quaternion1[3];
var x2 = quaternion2[0];
var y2 = quaternion2[1];
var z2 = quaternion2[2];
var w2 = quaternion2[3];
var a = (y * z2) - (z * y2);
var b = (z * x2) - (x * z2);
var c = (x * y2) - (y * x2);
var d = ((x * x2) + (y * y2)) + (z * z2);
quaternion[0] = ((x * w2) + (x2 * w)) + a;
quaternion[1] = ((y * w2) + (y2 * w)) + b;
quaternion[2] = ((z * w2) + (z2 * w)) + c;
quaternion[3] = (w * w2) - d;
return quaternion;
};
GLGE.mat4FromQuat = function(quaternion) {
// TODO: Optimize with storing the array-wise indexed values
// in direct acessible variables?
var x2 = quaternion[0] * quaternion[0];
var y2 = quaternion[1] * quaternion[1];
var z2 = quaternion[2] * quaternion[2];
var xy = quaternion[0] * quaternion[1];
var zw = quaternion[2] * quaternion[3];
var zx = quaternion[2] * quaternion[0];
var yw = quaternion[1] * quaternion[3];
var yz = quaternion[1] * quaternion[2];
var xw = quaternion[0] * quaternion[3];
var result = [];
result[0] = 1 - (2 * (y2 + z2));
result[1] = 2 * (xy + zw);
result[2] = 2 * (zx - yw);
result[3] = 0;
result[4] = 2 * (xy - zw);
result[5] = 1 - (2 * (z2 + x2));
result[6] = 2 * (yz + xw);
result[7] = 0;
result[8] = 2 * (zx + yw);
result[9] = 2 * (yz - xw);
result[10] = 1 - (2 * (y2 + x2));
result[11] = 0;
result[12] = 0;
result[13] = 0;
result[14] = 0;
result[15] = 1;
return result;
};
// JHD - end
GLGE.quatRotation=function(qx,qy,qz,qw){
return GLGE.matrix4(
1 - 2*qy*qy - 2*qz*qz,2*qx*qy - 2*qz*qw,2*qx*qz + 2*qy*qw,0,
2*qx*qy + 2*qz*qw,1 - 2*qx*qx - 2*qz*qz,2*qy*qz - 2*qx*qw,0,
2*qx*qz - 2*qy*qw,2*qy*qz + 2*qx*qw,1 - 2*qx*qx - 2*qy*qy,0,
0,0,0,1
);
};
GLGE.makeOrtho=function(left,right,bottom,top,near,far){
var x = -(right+left)/(right-left);
var y = -(top+bottom)/(top-bottom);
var z = -(far+near)/(far-near);
return GLGE.matrix4(2/(right-left), 0, 0, x,
0, 2/(top-bottom), 0, y,
0, 0, -2/(far-near), z,
0, 0, 0, 1);
};
GLGE.makeFrustum=function(left,right,bottom,top,near,far){
var x = 2*near/(right-left);
var y = 2*near/(top-bottom);
var a = (right+left)/(right-left);
var b = (top+bottom)/(top-bottom);
var c = -(far+near)/(far-near);
var d = -2*far*near/(far-near);
return GLGE.matrix4(x, 0, a, 0,
0, y, b, 0,
0, 0, c, d,
0, 0, -1, 0);
};
GLGE.makePerspective=function(fovy, aspect, near, far){
var ymax = near * Math.tan(fovy * 0.00872664625972);
var ymin = -ymax;
var xmin = ymin * aspect;
var xmax = ymax * aspect;
return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
};
GLGE.makePerspectiveX=function(fovx, aspect, near, far){
var xmax = near * Math.tan(fovx * 0.00872664625972);
var xmin = -xmax;
var ymin = xmin / aspect;
var ymax = xmax / aspect;
return GLGE.makeFrustum(xmin, xmax, ymin, ymax, near, far);
};
GLGE.matrix2Scale=function(m){
var m1=m[0];
var m2=m[1];
var m3=m[2];
var m4=m[4];
var m5=m[5];
var m6=m[6];
var m7=m[8];
var m8=m[9];
var m9=m[10];
var scaleX=Math.sqrt(m1*m1+m2*m2+m3*m3);
var scaleY=Math.sqrt(m4*m4+m5*m5+m6*m6);
var scaleZ=Math.sqrt(m7*m7+m8*m8+m9*m9);
return [scaleX,scaleY,scaleZ]
}
GLGE.rotationMatrix2Quat=function(m){
var tr = m[0] + m[5] + m[10]+1.0;
var S,x,y,z,w;
if (tr > 0) {
S = 0.5/Math.sqrt(tr);
w = 0.25 / S;
x = (m[9] - m[6]) * S;
y = (m[2] - m[8]) * S;
z = (m[4] - m[1]) * S;
} else if ((m[0] > m[5])&&(m[0] > m[10])) {
S = Math.sqrt(1.0 + m[0] - m[5] - m[10]) * 2;
w = (m[9] - m[6]) / S;
x = 0.25 / S;
y = (m[1] + m[4]) / S;
z = (m[2] + m[8]) / S;
} else if (m[5] > m[10]) {
S = Math.sqrt(1.0 + m[5] - m[0] - m[10]) * 2;
w = (m[2] - m[8]) / S;
x = (m[1] + m[4]) / S;
y = 0.25 / S;
z = (m[6] + m[9]) / S;
} else {
S = Math.sqrt(1.0 + m[10] - m[0] - m[5]) * 2;
w = (m[4] - m[1]) / S;
x = (m[2] + m[8]) / S;
y = (m[6] + m[9]) / S;
z = 0.25 / S;
}
var N=Math.sqrt(x*x+y*y+z*z+w*w)
return [x/N,y/N,z/N,w/N];
}
//returns plane as array [X,Y,Z,D]
GLGE.rayToPlane=function(origin,dir){
var dirnorm=GLGE.toUnitVec3(dir);
return [dirnorm[0],dirnorm[1],dirnorm[2],GLGE.dotVec3(origin,dirnorm)];
}
GLGE.rayIntersectPlane=function(origin,dir,plane){
var planeN=[plane[0],plane[1],plane[2]];
var planeD=plane[3];
var vdir=GLGE.dotVec3(planeN,dir);
if(vdir<=0){
//ray in wrong direction
return false;
}
var vo=-(GLGE.dotVec3(planeN,origin)+planeD);
var t=vo/vdir;
if(t<=0){
return false;
}
return GLGE.addVec3(origin,GLGE.scaleVec3(dir,t));
}
//assumes perspective projection
GLGE.screenToDirection=function(x,y,width,height,proj){
xcoord = -( ( ( 2 * x ) / width ) - 1 ) / proj[0];
ycoord =( ( ( 2 * y ) / height ) - 1 ) / proj[5];
zcoord = 1;
return GLGE.toUnitVec3([xcoord,ycoord,zcoord]);
}
GLGE.BoundingVolume=function(minX,maxX,minY,maxY,minZ,maxZ){
this.limits=[minX,maxX,minY,maxY,minZ,maxZ];
this.calcProps();
}
GLGE.BoundingVolume.prototype.getCornerPoints=function(){
return this.points;
}
//returns the radius of a bounding sphere
GLGE.BoundingVolume.prototype.getSphereRadius=function(){
return this.radius;
}
//returns the center of a bounding volume
GLGE.BoundingVolume.prototype.getCenter=function(){
return this.center;
}
GLGE.BoundingVolume.prototype.isNull=function(){
return this.limits[0]==0&&this.limits[1]==0&&this.limits[2]==0&&this.limits[3]==0&&this.limits[4]==0&&this.limits[5]==0;
}
//adds an additional bounding volume to resize the current and returns the result
GLGE.BoundingVolume.prototype.addBoundingVolume=function(vol){
if (this.isNull()) {
this.limits[0]=vol.limits[0];
this.limits[1]=vol.limits[1];
this.limits[2]=vol.limits[2];
this.limits[3]=vol.limits[3];
this.limits[4]=vol.limits[4];
this.limits[5]=vol.limits[5];
}
else if (!vol.isNull()) {
this.limits[0]=Math.min(vol.limits[0],this.limits[0]);
this.limits[2]=Math.min(vol.limits[2],this.limits[2]);
this.limits[4]=Math.min(vol.limits[4],this.limits[4]);
this.limits[1]=Math.max(vol.limits[1],this.limits[1]);
this.limits[3]=Math.max(vol.limits[3],this.limits[3]);
this.limits[5]=Math.max(vol.limits[5],this.limits[5]);
}
this.calcProps();
}
//scales a volume based on a transform matrix
GLGE.BoundingVolume.prototype.applyMatrix=function(matrix){
var coord0=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[2],this.limits[4],1]);
var coord1=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[2],this.limits[4],1]);
var coord2=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[3],this.limits[4],1]);
var coord3=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[3],this.limits[4],1]);
var coord4=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[2],this.limits[5],1]);
var coord5=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[2],this.limits[5],1]);
var coord6=GLGE.mulMat4Vec4(matrix,[this.limits[0],this.limits[3],this.limits[5],1]);
var coord7=GLGE.mulMat4Vec4(matrix,[this.limits[1],this.limits[3],this.limits[5],1]);
this.limits[0]=Math.min(coord0[0],coord1[0],coord2[0],coord3[0],coord4[0],coord5[0],coord6[0],coord7[0]);
this.limits[1]=Math.max(coord0[0],coord1[0],coord2[0],coord3[0],coord4[0],coord5[0],coord6[0],coord7[0]);
this.limits[2]=Math.min(coord0[1],coord1[1],coord2[1],coord3[1],coord4[1],coord5[1],coord6[1],coord7[1]);
this.limits[3]=Math.max(coord0[1],coord1[1],coord2[1],coord3[1],coord4[1],coord5[1],coord6[1],coord7[1]);
this.limits[4]=Math.min(coord0[2],coord1[2],coord2[2],coord3[2],coord4[2],coord5[2],coord6[2],coord7[2]);
this.limits[5]=Math.max(coord0[2],coord1[2],coord2[2],coord3[2],coord4[2],coord5[2],coord6[2],coord7[2]);
this.calcProps();
}
GLGE.BoundingVolume.prototype.calcProps=function(){
var minX=this.limits[0];
var maxX=this.limits[1];
var minY=this.limits[2];
var maxY=this.limits[3];
var minZ=this.limits[4];
var maxZ=this.limits[5];
this.points=[
[minX,minY,minZ],
[maxX,minY,minZ],
[minX,maxY,minZ],
[maxX,maxY,minZ],
[minX,minY,maxZ],
[maxX,minY,maxZ],
[minX,maxY,maxZ],
[maxX,maxY,maxZ]
];
this.center=[(this.limits[1]-this.limits[0])/2+this.limits[0],(this.limits[3]-this.limits[2])/2+this.limits[2],(this.limits[5]-this.limits[4])/2+this.limits[4]];
var dx=this.limits[0]-this.center[0];
var dy=this.limits[2]-this.center[1];
var dz=this.limits[4]-this.center[2];
this.radius=Math.sqrt(dx*dx+dy*dy+dz*dz);
}
GLGE.BoundingVolume.prototype.clone=function(){
return new GLGE.BoundingVolume(this.limits[0],this.limits[1],this.limits[2],this.limits[3],this.limits[4],this.limits[5]);
}
GLGE.BoundingVolume.prototype.toString=function(){
return this.limits.toString();
}
//creates the bounding planes for the cameraViewProjectionMatrix
GLGE.cameraViewProjectionToPlanes=function(cvp){
var cvpinv=GLGE.inverseMat4(cvp);
var mulMat4Vec4=GLGE.mulMat4Vec4;
var subVec3=GLGE.subVec3;
var crossVec3=GLGE.crossVec3;
var toUnitVec3=GLGE.toUnitVec3;
var dotVec3=GLGE.dotVec3
var nbl=mulMat4Vec4(cvpinv,[-1,-1,-1,1]);
var nbr=mulMat4Vec4(cvpinv,[1,-1,-1,1]);
var fbl=mulMat4Vec4(cvpinv,[-1,-1,1,1]);
var ntr=mulMat4Vec4(cvpinv,[1,1,-1,1]);
var ftr=mulMat4Vec4(cvpinv,[1,1,1,1]);
var ftl=mulMat4Vec4(cvpinv,[-1,1,1,1]);
nbl=[nbl[0]/nbl[3],nbl[1]/nbl[3],nbl[2]/nbl[3]];
nbr=[nbr[0]/nbr[3],nbr[1]/nbr[3],nbr[2]/nbr[3]];
fbl=[fbl[0]/fbl[3],fbl[1]/fbl[3],fbl[2]/fbl[3]];
ntr=[ntr[0]/ntr[3],ntr[1]/ntr[3],ntr[2]/ntr[3]];
ftr=[ftr[0]/ftr[3],ftr[1]/ftr[3],ftr[2]/ftr[3]];
ftl=[ftl[0]/ftl[3],ftl[1]/ftl[3],ftl[2]/ftl[3]];
var nearnorm=toUnitVec3(crossVec3(subVec3(ntr,nbr),subVec3(nbl,nbr)));
var farnorm=toUnitVec3(crossVec3(subVec3(ftl,fbl),subVec3(ftr,fbl)));
var leftnorm=toUnitVec3(crossVec3(subVec3(nbl,fbl),subVec3(ftl,fbl)));
var rightnorm=toUnitVec3(crossVec3(subVec3(ftr,ntr),subVec3(ntr,nbr)));
var topnorm=toUnitVec3(crossVec3(subVec3(ftl,ntr),subVec3(ntr,ftr)));
var bottomnorm=toUnitVec3(crossVec3(subVec3(nbl,nbr),subVec3(fbl,nbl)));
nearnorm.push(dotVec3(nearnorm,nbl));
farnorm.push(dotVec3(farnorm,fbl));
leftnorm.push(dotVec3(leftnorm,nbl));
rightnorm.push(dotVec3(rightnorm,nbr));
topnorm.push(dotVec3(topnorm,ftr));
bottomnorm.push(dotVec3(bottomnorm,nbl));
//might be worth calulating the frustum sphere for optimization at this point!
return [nearnorm,farnorm,leftnorm,rightnorm,topnorm,bottomnorm];
}
//Checks if sphere is within frustum planes
//sphere passed as [center.x,center.y,center.z,radius]
GLGE.sphereInFrustumPlanes=function(sphere,planes){
var sphere0=sphere[0];var sphere1=sphere[1];
var sphere2=sphere[2];var sphere3=sphere[3];
var plane0=planes[0];var plane1=planes[1];
var plane2=planes[2];var plane3=planes[3];
var plane4=planes[4];var plane5=planes[5];
if(sphere0*plane0[0] + sphere1*plane0[1] + sphere2*plane0[2] - plane0[3] - sphere3 > 0
|| sphere0*plane1[0] + sphere1*plane1[1] + sphere2*plane1[2] - plane1[3] - sphere3 > 0
|| sphere0*plane2[0] + sphere1*plane2[1] + sphere2*plane2[2] - plane2[3] - sphere3 > 0
|| sphere0*plane3[0] + sphere1*plane3[1] + sphere2*plane3[2] - plane3[3] - sphere3 > 0
|| sphere0*plane4[0] + sphere1*plane4[1] + sphere2*plane4[2] - plane4[3] - sphere3 > 0
|| sphere0*plane5[0] + sphere1*plane5[1] + sphere2*plane5[2] - plane5[3] - sphere3 > 0){
return false;
}else{
return true;
}
}
//checks if cube points are within the frustum planes
GLGE.pointsInFrustumPlanes=function(points,planes){
var plane0=planes[0];var plane1=planes[1];
var plane2=planes[2];var plane3=planes[3];
var plane4=planes[4];var plane5=planes[5];
var x, y, z;
for(var i=0; i 0
&& x*plane1[0] + y*plane1[1] + z*plane1[2] - plane1[3] > 0
&& x*plane2[0] + y*plane2[1] + z*plane2[2] - plane3[3] > 0
&& x*plane3[0] + y*plane3[1] + z*plane3[2] - plane4[3] > 0
&& x*plane4[0] + y*plane4[1] + z*plane4[2] - plane4[3] > 0
&& x*plane5[0] + y*plane5[1] + z*plane5[2] - plane5[3] > 0){
return false;
}
}
return true;
}
//get projection matrix for a directional light
GLGE.getDirLightProjection=function(cvp,light,projectedDistance,distance){
var pointTransform=GLGE.mulMat4(light,GLGE.inverseMat4(cvp));
var min=[0,0,0];
var max=[0,0,0];
for(var x=0;x<2;x++){
for(var y=0;y<2;y++){
for(var z=0;z<2;z++){
//var vec=GLGE.mulMat4Vec4(pointTransform,[x*2-1,y*2-1,z*projectedDistance,1]);
var vec=GLGE.mulMat4Vec4(pointTransform,[x*2-1,y*2-1,(z*2-1),1]);
//console.log(vec[0]/vec[3],vec[1]/vec[3],vec[2]/vec[3],vec[3]/vec[3]);
vec[0]=vec[0]/vec[3];vec[1]=vec[1]/vec[3];vec[2]=vec[2]/vec[3];
min[0]=min[0] > vec[0] ? vec[0] : min[0];
min[1]=min[1] > vec[1] ? vec[1] : min[1];
max[0]=max[0] < vec[0] ? vec[0] : max[0];
max[1]=max[1] < vec[1] ? vec[1] : max[1];
max[2]=max[2] < vec[2] ? vec[2] : max[2];
}
}
}
var mat=GLGE.makeOrtho(min[0],max[0],min[1],max[1],0.01,+distance);
//mat[0]*=8;
//mat[5]*=8;
//var mat=GLGE.makeFrustum(min[0],max[0],min[1],max[1],500,0.01);
//var mat=GLGE.makeOrtho(-30,30,-30,30,0.01,500);
//alert(mat);
return mat
};
function GLGE_mathUnitTest() {
var a=GLGE.Vec([1,2,3,4]);
var b=GLGE.Vec4(GLGE.getVec4(a,3),
GLGE.get1basedVec4(a,3),
GLGE.getVec4(a,1),
GLGE.getVec4(a,0));
var c=GLGE.identMatrix();
var d=GLGE.mulMat4Vec4(c,b);
if (GLGE.getVec4(d,0)!=4||
GLGE.getVec4(d,1)!=3||
GLGE.getVec4(d,2)!=2||
GLGE.getVec4(d,3)!=1) {
throw "Unit Test 1 failed MatVecMul "+d;
}
var m=GLGE.Mat4([3,4,5,0,.5,.75,0,0,.75,.5,0,0,.25,.25,1,1]);
var m1=GLGE.Mat4([2,1,8,2,1,4,3,2,1,.5,6.5,2,8,3,1,.25]);
var mm1=GLGE.mulMat4(m,m1);
var am1=GLGE.Mat4([15,21.5,68.5,24,
1.75,3.5,6.25,2.5,
2,2.75,7.5,2.5,
9.75,4.75,10.25,3.25]);
for (var i=0;i<4;++i) {
for (var j=0;j<4;++j) {
var diff=GLGE.getMat4(mm1,i,j)-GLGE.getMat4(am1,i,j);
if (diff<.000001&&diff>-.000001) {
}else {
throw "Unit Test 1 failed Multiplication "+GLGE.getMat4(mm1,i,j)+" != "+GLGE.getMat4(am1,i,j);
}
}
}
var inv = GLGE.inverseMat4(m);
var k = GLGE.mulMat4(m,inv);
var l = GLGE.mulMat4(inv,m);
for (var i=0;i<4;++i) {
for (var j=0;j<4;++j) {
var diff=GLGE.getMat4(k,i,j)-GLGE.getMat4(c,i,j);
if (diff<.0001&&diff>-.0001) {
}else {
throw "Unit Test 1 failed Inverse "+GLGE.getMat4(k,i,j)+" != "+GLGE.getMat4(c,i,j);
}
}
}
}
GLGE_mathUnitTest() ;
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge.js
* @author me@paulbrunt.co.uk
*/
if(typeof(GLGE) == "undefined"){
/**
* @namespace Holds the functionality of the library
*/
GLGE = {};
}
(function(GLGE){
//speed ups parsing a float that is already a float is expensive!
var parseFloat2=function(val){
if(typeof val!="number") return parseFloat(val);
else return val;
}
/**
* Function to augment one object with another
* @param {object} obj1 Source Object
* @param {object} obj2 Destination Object
*/
GLGE.augment=function(obj1,obj2){
obj2.prototype.baseclass = obj1;
for(var proto in obj1.prototype){
if(!obj2.prototype[proto]) // do not overwrite functions of the derived objects
obj2.prototype[proto]=obj1.prototype[proto];
else // Attach those to the baseclass instead. Use 'call(this)' to call baseclass methods
obj2.prototype.baseclass[proto]=obj1.prototype[proto];
}
}
/**
* Moves all GLGE function to global
**/
GLGE.makeGlobal=function(){
for(var key in GLGE){
window[key]=GLGE[key];
}
}
GLGE.New=function(createclass){
if(GLGE[createclass].prototype.className!=""){
return new GLGE[createclass]();
}else{
return false;
}
}
/**
* @constant
* @description Enumeration for TRUE
*/
GLGE.TRUE=1;
/**
* @constant
* @description Enumeration for FALSE
*/
GLGE.FALSE=0;
/**
* @constant
* @description Enumeration for global refrance frame
*/
GLGE.GLOBAL=0;
/**
* @constant
* @description Enumeration for local refrance frame
*/
GLGE.LOCAL=1;
/**
* @constant
* @description Enumeration for tri rendering
*/
GLGE.DRAW_TRIS=1;
/**
* @constant
* @description Enumeration for line rendering
*/
GLGE.DRAW_LINES=2;
/**
* @constant
* @description Enumeration for line loop rendering
*/
GLGE.DRAW_LINELOOPS=3;
/**
* @constant
* @description Enumeration for line loop rendering
*/
GLGE.DRAW_LINESTRIPS=4;
/**
* @constant
* @description Enumeration for point rendering
*/
GLGE.DRAW_POINTS=5;
/**
* @constant
* @description Enumeration for point rendering
*/
GLGE.DRAW_TRIANGLESTRIP=6;
/**
* @constant
* @description Enumeration for rendering using default shader
*/
GLGE.RENDER_DEFAULT=0;
/**
* @constant
* @description Enumeration for rendering using shadow shader
*/
GLGE.RENDER_SHADOW=1;
/**
* @constant
* @description Enumeration for rendering using pick shader
*/
GLGE.RENDER_PICK=2;
/**
* @constant
* @description Enumeration for rendering using normal shader
*/
GLGE.RENDER_NORMAL=3;
/**
* @constant
* @description Enumeration for emit rendering
*/
GLGE.RENDER_EMIT=4;
/**
* @constant
* @description Enumeration for depth rendering
*/
GLGE.RENDER_DEPTH=5;
/**
* @constant
* @description Enumeration for no rendering
*/
GLGE.RENDER_NULL=6;
/**
* @constant
* @description Enumeration for box bound text picking
*/
GLGE.TEXT_BOXPICK=1;
/**
* @constant
* @description Enumeration for text bound text picking
*/
GLGE.TEXT_TEXTPICK=2;
/**
* @constant
* @description Enumeration for euler rotaions mode
*/
GLGE.P_EULER=1;
/**
* @constant
* @description Enumeration for quaternions mode
*/
GLGE.P_QUAT=2;
/**
* @constant
* @description Enumeration for matrix rotation mode
*/
GLGE.P_MATRIX=3;
/**
* @constant
* @description Enumeration for no value
*/
GLGE.NONE=0;
/**
* @constant
* @description Enumeration for X-Axis
*/
GLGE.XAXIS=1;
/**
* @constant
* @description Enumeration for Y-Axis
*/
GLGE.YAXIS=2;
/**
* @constant
* @description Enumeration for Z-Axis
*/
GLGE.ZAXIS=3;
/**
* @constant
* @description Enumeration for +X-Axis
*/
GLGE.POS_XAXIS=1;
/**
* @constant
* @description Enumeration for -X-Axis
*/
GLGE.NEG_XAXIS=2;
/**
* @constant
* @description Enumeration for +Y-Axis
*/
GLGE.POS_YAXIS=3;
/**
* @constant
* @description Enumeration for -Y-Axis
*/
GLGE.NEG_YAXIS=4;
/**
* @constant
* @description Enumeration for +Z-Axis
*/
GLGE.POS_ZAXIS=5;
/**
* @constant
* @description Enumeration for -Z-Axis
*/
GLGE.NEG_ZAXIS=6;
GLGE.ZERO="ZERO";
GLGE.ONE="ONE";
GLGE.SRC_COLOR="SRC_COLOR";
GLGE.ONE_MINUS_SRC_COLOR="ONE_MINUS_SRC_COLOR";
GLGE.SRC_ALPHA="SRC_ALPHA";
GLGE.ONE_MINUS_SRC_ALPHA="ONE_MINUS_SRC_ALPHA";
GLGE.DST_ALPHA="DST_ALPHA";
GLGE.ONE_MINUS_DST_ALPHA="ONE_MINUS_DST_ALPHA";
/**
* @constant
* @description Linear blending function
*/
GLGE.LINEAR_BLEND=function(value){
return value;
}
/**
* @constant
* @description Quadratic blending function
*/
GLGE.QUAD_BLEND=function(value){
return value*value;
}
/**
* @constant
* @description Special blending function
*/
GLGE.SPECIAL_BLEND=function(value){
value=value*(2-value);
return value*value;
}
GLGE.error=function(error){
if (console&&console.log)
console.log("GLGE error: "+error);
//do not use a modal dialog to indicate this users can override GLGE.error if they desire
};
GLGE.warning=function(warning){
if (console&&console.log)
console.log("GLGE warning: "+warning);
//do not use a modal dialog to indicate this users can override GLGE.warning if they desire
};
/**
* @namespace Holds the global asset store
*/
GLGE.Assets={};
GLGE.Assets.assets={};
//don't need to register assets unless we are using network or webworkers
GLGE.REGISTER_ASSETS=false;
GLGE.Assets.createUUID=function(){
var data=["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"];
var data2=["8","9","A","B"];
uuid="";
for(var i=0;i<38;i++){
switch(i){
case 8:uuid=uuid+"-";break;
case 13:uuid=uuid+"-";break;
case 18:uuid=uuid+"-";break;
case 14:uuid=uuid+"4";break;
case 19:uuid=uuid+data2[Math.round(Math.random()*3)];break;
default:uuid=uuid+data[Math.round(Math.random()*15)];break;
}
}
return uuid;
}
/**
* @function registers a new asset
*/
GLGE.Assets.registerAsset=function(obj,uid){
if(typeof uid=="object"){
if(obj._) obj._(uid);
uid=uid.uid;
}
if(!uid){
uid=GLGE.Assets.createUUID();
};
obj.uid=uid;
if(GLGE.REGISTER_ASSETS){
GLGE.Assets.assets[uid]=obj;
}
}
/**
* @function removes an asset
*/
GLGE.Assets.unregisterAsset=function(uid){
delete GLGE.Assets.assets[uid];
}
/**
* @function finds an asset by uid
*/
GLGE.Assets.get=function(uid){
var value=GLGE.Assets.assets[uid];
if(value){
return value;
}else{
return false;
}
}
/**
* @function hashing function
* @private
*/
GLGE.DJBHash=function(str){
var hash = 5381;
for(var i = 0; i < str.length; i++){
hash = ((hash << 5) + hash) + str.charCodeAt(i);
}
return hash;
}
/**
* @function check if shader is already created if not then create it
* @private
*/
GLGE.getGLShader=function(gl,type,str){
var hash=GLGE.DJBHash(str);
if(!gl.shaderCache) gl.shaderCache={};
if(!gl.shaderCache[hash]){
var shader=gl.createShader(type);
gl.shaderSource(shader, str);
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
try {
GLGE.error(gl.getShaderInfoLog(shader));
return;
} catch (e) {
/* Firefox hack: Assume no error if there was no shader log. */
}
}
gl.shaderCache[hash]=shader;
}
return gl.shaderCache[hash];
}
var progIdx=0;
/**
* @function tries to re use programs
* @private
*/
GLGE.getGLProgram=function(gl,vShader,fShader){
if(!gl.programCache) gl.programCache=[];
var programCache=gl.programCache;
for(var i=0; i1){
if(this.loop){
frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)%(this.animFrames-1)+1+this.startFrame;
}else{
frame=((parseFloat(now)-parseFloat(this.animationStart))/1000*this.frameRate)+1+this.startFrame;
if(frame>=(this.animFrames+this.startFrame)){
frame=this.animFrames;
}
}
}else{
frame=1;
}
return Math.round(frame);
}
/**
* Sets the start frame for the animation overriding the animation default
* @param {number} startFrame the start frame
*/
GLGE.Animatable.prototype.setStartFrame=function(startFrame,blendTime,loop){
this.loop=loop;
var starttime=parseInt(new Date().getTime());
if(!blendTime) blendTime=0;
if(blendTime>0){
if(this.animation){
this.blendInitValues=this.getInitialValues(this.animation,starttime);
this.blendTime=blendTime;
}
}
this.animationStart=starttime;
this.lastFrame=null;
this.animFinished=false;
this.startFrame=startFrame;
if(this.children){
for(var i=0;i0){
this.blendInitValues=this.getInitialValues(animationVector,starttime);
this.blendTime=blendDuration;
}
this.animFrames=null;
this.startFrame=null;
this.animationStart=starttime;
this.lastFrame=null;
this.animation=animationVector;
this.animFinished=false;
return this;
}
/**
* Gets the animation vector of this object
* @returns {AnimationVector}
*/
GLGE.Animatable.prototype.getAnimation=function(){
return this.animation;
}
/**
* Sets the frame rate of the animation
* @param {number} value the frame rate to set
*/
GLGE.Animatable.prototype.setFrameRate=function(value){
this.frameRate=value;
if (this.children) {
for (var i = 0; i < this.children.length; i++) {
if (this.children[i].setFrameRate) {
this.children[i].setFrameRate(value);
}
}
}
return this;
}
/**
* Gets the frame rate of the animation
* @return {number} the current frame rate
*/
GLGE.Animatable.prototype.getFrameRate=function(){
return this.frameRate;
}
/**
* Sets the loop flag to GLGE.TRUE or GLGE.FALSE
* @param {boolean} value
*/
GLGE.Animatable.prototype.setLoop=function(value){
this.loop=value;
return this;
}
/**
* Gets the loop flag
* @return {boolean}
*/
GLGE.Animatable.prototype.getLoop=function(){
return this.loop;
}
/**
* @function is looping? @see GLGE.Animatable#getLoop
*/
GLGE.Animatable.prototype.isLooping=GLGE.Animatable.prototype.getLoop;
/**
* Sets the paused flag to GLGE.TRUE or GLGE.FALSE
* @param {boolean} value
*/
GLGE.Animatable.prototype.setPaused=function(value){
if(value) this.pauseTime=parseInt(new Date().getTime());
else this.animationStart=this.animationStart+(parseInt(new Date().getTime())-this.pauseTime);
this.paused=value;
return this;
}
/**
* Gets the paused flag
* @return {boolean}
*/
GLGE.Animatable.prototype.getPaused=function(){
return this.paused;
}
/**
* Toggles the paused flag
* @return {boolean} returns the resulting flag state
*/
GLGE.Animatable.prototype.togglePaused=function(){
this.setPaused(!this.getPaused());
return this.paused;
}
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_document.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Document class to load scene, object, mesh etc from an external XML file
* @param {string} url URL of the resource to load
*/
GLGE.Document=function(){
this.listeners=[];
this.documents=[];
}
GLGE.Document.prototype.listeners=null;
GLGE.Document.prototype.documents=null;
GLGE.Document.prototype.rootURL=null;
GLGE.Document.prototype.loadCount=0;
GLGE.Document.prototype.version=0;
GLGE.Document.prototype.preloader=null;
/**
* This is just a fix for a bug in webkit
* @param {string} id the id name to get
* @returns {object} node with teh specified id
* @private
*/
GLGE.Document.prototype.getElementById=function(id){
var tags=this.getElementsByTagName("*");
for(var i=0; i0) return this.getDefault(ele); //as of GLGE XML 1.0 the mesh is nothing special!
if(!ele.object){
ele.object=new GLGE.Mesh();
this.setProperties(ele);
var child=ele.firstChild;
while(child){
switch(child.tagName){
case "positions":
ele.object.setPositions(this.parseArray(child));
break;
case "normals":
ele.object.setNormals(this.parseArray(child));
break;
case "uv1":
ele.object.setUV(this.parseArray(child));
break;
case "uv2":
ele.object.setUV2(this.parseArray(child));
break;
case "faces":
ele.object.setFaces(this.parseArray(child));
break;
case "color":
ele.object.setVertexColors(this.parseArray(child));
break;
case "joint_names":
var names=this.parseArray(child);
var jointObjects=[];
for(var i=0;i0) || object.className=="Light"){
var root=object;
while(root.parent) root=root.parent;
root.updateAllPrograms();
}
if(object.addEventListener){
object.addEventListener("shaderupdate",function(){
var root=this;
while(root.parent) root=root.parent;
root.updateAllPrograms();
});
object.addEventListener("downloadComplete",this.downloadComplete);
}
this.fireEvent("childAdded",{obj:object});
if(object.fireEvent) object.fireEvent("appened",{obj:this});
this.fireEvent("childAdded",{obj:object});
//fire child added event for all parents as well
var o=this;
while(o=o.parent) o.fireEvent("childAdded",{obj:object,target:this});
return this;
}
GLGE.Group.prototype.addObject=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addObjectInstance=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addGroup=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addLight=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addText=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addSkeleton=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addCamera=GLGE.Group.prototype.addChild;
GLGE.Group.prototype.addWavefront=GLGE.Group.prototype.addChild;
/**
* Removes an object or sub group from this group
* @param {child} object or index the item to remove
*/
GLGE.Group.prototype.removeChild=function(child){
var object;
if (typeof child == 'object') {
for(var i=0;i0) GLGE.Message.loadMessages();
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_action.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Class to describe and action on a skeleton
* @param {string} uid a unique reference string for this object
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.Action=function(uid){
this.channels=[];
GLGE.Assets.registerAsset(this,uid);
};
GLGE.augment(GLGE.QuickNotation,GLGE.Action);
GLGE.augment(GLGE.JSONLoader,GLGE.Action);
/**
* @name Action#animFinished
* @event
* @param {object} data
*/
GLGE.augment(GLGE.Events,GLGE.Action);
/**
* Starts playing the action
*/
GLGE.Action.prototype.start=function(blendTime,loop,names){
if(!loop) loop=false;
if(!blendTime) blendTime=0;
var channels=this.channels;
var start=(new Date()).getTime();
this.animFinished=false;
for(var i=0;ithis.keyFrames[startKey].x)){
preStartKey=startKey;
startKey=i;
}else if(this.keyFrames[i].x<=frame && (preStartKey==undefined || this.keyFrames[i].x>this.keyFrames[preStartKey].x)){
preStartKey=i;
}
if(this.keyFrames[i].x>frame && (endKey==undefined || this.keyFrames[i].x<=this.keyFrames[endKey].x)){
preEndKey=endKey;
endKey=i;
}else if(this.keyFrames[i].x>frame && (preEndKey==undefined || this.keyFrames[i].x<=this.keyFrames[preEndKey].x)){
preEndKey=i;
}
}
if(startKey==undefined){
startKey=endKey;
endKey=preEndKey;
}
if(endKey==undefined){
endKey=startKey;
startKey=preStartKey;
}
if(this.keyFrames[startKey] instanceof GLGE.BezTriple && this.keyFrames[endKey] instanceof GLGE.BezTriple){
var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
var C2=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
var C3=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
return this.atX(frame,C1,C2,C3,C4).y;
}
if(this.keyFrames[startKey] instanceof GLGE.LinearPoint && this.keyFrames[endKey] instanceof GLGE.BezTriple){
var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
var C2=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
var C3=this.coord(this.keyFrames[endKey].x1,this.keyFrames[endKey].y1);
var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
return this.atX(frame,C1,C2,C3,C4).y;
}
if(this.keyFrames[startKey] instanceof GLGE.BezTriple && this.keyFrames[endKey] instanceof GLGE.LinearPoint){
var C1=this.coord(this.keyFrames[startKey].x,this.keyFrames[startKey].y);
var C2=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
var C3=this.coord(this.keyFrames[startKey].x3,this.keyFrames[startKey].y3);
var C4=this.coord(this.keyFrames[endKey].x,this.keyFrames[endKey].y);
return this.atX(frame,C1,C2,C3,C4).y;
}
if(this.keyFrames[startKey] instanceof GLGE.LinearPoint && this.keyFrames[endKey] instanceof GLGE.LinearPoint){
var value=(frame-this.keyFrames[startKey].x)*(this.keyFrames[endKey].y-this.keyFrames[startKey].y)/(this.keyFrames[endKey].x-this.keyFrames[startKey].x)+this.keyFrames[startKey].y;
return value;
}
if(this.keyFrames[startKey] instanceof GLGE.StepPoint){
return this.keyFrames[startKey].y
}
if(!this.keyFrames.preStartKey) this.keyFrames.preStartKey=this.keyFrames[0].y;
this.caches[frame]=this.keyFrames.preStartKey;
return this.caches[frame];
};
/**
* Function used to calculate bezier curve
* @private
*/
GLGE.AnimationCurve.prototype.B1=function(t) { return t*t*t };
/**
* Function used to calculate bezier curve
* @private
*/
GLGE.AnimationCurve.prototype.B2=function(t) { return 3*t*t*(1-t) };
/**
* Function used to calculate bezier curve
* @private
*/
GLGE.AnimationCurve.prototype.B3=function(t) { return 3*t*(1-t)*(1-t) };
/**
* Function used to calculate bezier curve
* @private
*/
GLGE.AnimationCurve.prototype.B4=function(t) { return (1-t)*(1-t)*(1-t) };
/**
* Gets the value of a bezier curve at a given point
* @private
*/
GLGE.AnimationCurve.prototype.getBezier=function(t,C1,C2,C3,C4) {
var pos = {};
pos.x = C1.x*this.B1(t) + C2.x*this.B2(t) + C3.x*this.B3(t) + C4.x*this.B4(t);
pos.y = C1.y*this.B1(t) + C2.y*this.B2(t) + C3.y*this.B3(t) + C4.y*this.B4(t);
return pos;
};
/**
* Solves cubic equation to get the parametic value of the curve at a specified point
* @private
*/
GLGE.AnimationCurve.prototype.Quad3Solve=function(a,b,c,d){
ref=a+"-"+b+"-"+"-"+c+"-"+d;
if(this.solutions[ref]){
return this.solutions[ref];
}
else
{
b /= a;c /= a;d /= a;
var q, r, d1, s, t, t1, r13;
q = (3.0*c - (b*b))/9.0;
r = -(27.0*d) + b*(9.0*c - 2.0*(b*b));
r /= 54.0;
t1 = (b/3.0);
discrim = q*q*q + r*r;
result=[];
if (discrim > 0) {
// one real, two complex
s = r + Math.sqrt(discrim);
s = ((s < 0) ? -Math.pow(-s, (1.0/3.0)) : Math.pow(s, (1.0/3.0)));
t = r - Math.sqrt(discrim);
t = ((t < 0) ? -Math.pow(-t, (1.0/3.0)) : Math.pow(t, (1.0/3.0)));
result[0] = -t1 + s + t;
t1 = t1 + (s + t)/2.0;
result[1] = result[2] = -t1;
t1 = Math.sqrt(3.0)*(-t + s)/2;
}
else if (discrim == 0){
// All roots real
r13 = ((r < 0) ? -Math.pow(-r,(1.0/3.0)) : Math.pow(r,(1.0/3.0)));
result[1] = -t1 + 2.0*r13;
result[1] = result[2] = -(r13 + t1);
}
else
{
q = -q;
d1 = q*q*q;
d1 = Math.acos(r/Math.sqrt(1));
r13 = 2.0*Math.sqrt(q);
result[0] = -t1 + r13*Math.cos(d1/3.0);
result[1] = -t1 + r13*Math.cos((d1 + 2.0*Math.PI)/3.0);
result[2] = -t1 + r13*Math.cos((d1 + 4.0*Math.PI)/3.0);
}
var toreturn=false;
//determine which is the correct result
if(result[0]>=0 && result[0]<=1) toreturn=result[0];
if(!toreturn && result[1]>=0 && result[1]<=1) toreturn=result[1];
if(!toreturn && result[2]>=0 && result[2]<=1) toreturn=result[2];
//cache result for next time
this.solutions[ref]=toreturn;
return toreturn;
}
};
/**
* Get the value of the a single bezier curve
* @param {Number} x xcoord of point to get
* @param {Number} C1 First bezier control point
* @param {Number} C2 Second bezier control point
* @param {Number} C3 Third bezier control point
* @param {Number} C4 Forth bezier control point
* @returns {Number} The value of the curve at the given x
*/
GLGE.AnimationCurve.prototype.atX=function(x,C1,C2,C3,C4){
a=C1.x-C2.x*3+C3.x*3-C4.x;
b=C2.x*3-C3.x*6+C4.x*3;
c=C3.x*3-C4.x*3;
d=C4.x-x;
return this.getBezier(this.Quad3Solve(a,b,c,d),C1,C2,C3,C4);
};
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_animationvector.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class The AnimationVectors class allows you to specify the 2D Animation curves that define specific channels of animation within the engine.
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.AnimationVector=function(uid){
this.curves={};
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.AnimationVector);
GLGE.augment(GLGE.JSONLoader,GLGE.AnimationVector);
GLGE.AnimationVector.prototype.curves={};
GLGE.AnimationVector.prototype.frames=250;
GLGE.AnimationVector.prototype.startFrame=0;
/**
* Adds an Animation Curve to a channel
* @param {String} channel The name of the curve to be added
* @param {GLGE.AnimationCurve} curve The animation curve to add
*/
GLGE.AnimationVector.prototype.addAnimationCurve=function(curve){
this.curves[curve.channel]=curve;
return this;
}
/**
* Removes an Animation Curve form a channel
* @param {String} channel The name of the curve to be removed
*/
GLGE.AnimationVector.prototype.removeAnimationCurve=function(name){
delete(this.curves[name]);
}
/**
* Sets the number of frames in the animation
* @param {number} value The number of frames in the animation
*/
GLGE.AnimationVector.prototype.setFrames=function(value){
this.frames=value;
return this;
}
/**
* Sets the number of frames in the animation
* @returns {number} The number of frames in the animation
*/
GLGE.AnimationVector.prototype.getFrames=function(){
return this.frames;
}
/**
* Sets the start frame
* @param {number} value The starting frame for the animation
*/
GLGE.AnimationVector.prototype.setStartFrame=function(value){
this.startFrame=value;
return this;
}
/**
* Gets the start fames
* @returns {number} The starting frame for the animation
*/
GLGE.AnimationVector.prototype.getStartFrame=function(){
return this.startFrame;
}
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_animationpoints.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A bezier class to add points to the Animation Curve
* @param {string} uid a unique string to identify this object
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.BezTriple=function(uid){
GLGE.Assets.registerAsset(this,uid);
};
GLGE.augment(GLGE.QuickNotation,GLGE.BezTriple);
GLGE.augment(GLGE.JSONLoader,GLGE.BezTriple);
GLGE.BezTriple.prototype.className="BezTriple";
/**
* set the x1-coord
* @param {number} x x1-coord control point
*/
GLGE.BezTriple.prototype.setX1=function(x){
this.x1=parseFloat(x);
return this;
};
/**
* set the y1-coord
* @param {number} y y1-coord control point
*/
GLGE.BezTriple.prototype.setY1=function(y){
this.y1=parseFloat(y);
return this;
};
/**
* set the x2-coord
* @param {number} x x2-coord control point
*/
GLGE.BezTriple.prototype.setX2=function(x){
this.x=parseFloat(x);
return this;
};
/**
* set the y2-coord
* @param {number} y y2-coord control point
*/
GLGE.BezTriple.prototype.setY2=function(y){
this.y=parseFloat(y);
return this;
};
/**
* set the x3-coord
* @param {number} x x3-coord control point
*/
GLGE.BezTriple.prototype.setX3=function(x){
this.x3=parseFloat(x);
return this;
};
/**
* set the y3-coord
* @param {number} y y3-coord control point
*/
GLGE.BezTriple.prototype.setY3=function(y){
this.y3=parseFloat(y);
return this;
};
/**
* @class A LinearPoint class to add points to the Animation Curve
* @param {string} uid unique string for this class
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.LinearPoint=function(uid){
//GLGE.Assets.registerAsset(this,uid);
};
GLGE.augment(GLGE.QuickNotation,GLGE.LinearPoint);
GLGE.augment(GLGE.JSONLoader,GLGE.LinearPoint);
GLGE.LinearPoint.prototype.className="LinearPoint";
GLGE.LinearPoint.prototype.x=0;
GLGE.LinearPoint.prototype.y=0;
/**
* set the x-coord
* @param {number} x x-coord control point
*/
GLGE.LinearPoint.prototype.setX=function(x){
this.x=parseFloat(x);
return this;
};
/**
* set the y-coord
* @param {number} y y-coord control point
*/
GLGE.LinearPoint.prototype.setY=function(y){
this.y=parseFloat(y);
return this;
};
/**
* @class A StepPoint class to add points to the Animation Curve
* @param {number} x x-coord control point
* @param {object} value value of control point
*/
GLGE.StepPoint=function(x,value){
this.x=parseFloat(x);
this.y=value;
};
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_mesh.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Creates a new mesh
* @see GLGE.Object
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
* @augments GLGE.Events
*/
GLGE.Mesh=function(uid,windingOrder){
this.GLbuffers=[];
this.buffers=[];
this.framePositions=[];
this.frameNormals=[];
this.frameTangents=[];
this.UV=[];
this.boneWeights=[];
this.setBuffers=[];
this.faces={};
if (windingOrder!==undefined)
this.windingOrder=windingOrder;
else
this.windingOrder=GLGE.Mesh.WINDING_ORDER_UNKNOWN;
GLGE.Assets.registerAsset(this,uid);
};
GLGE.Mesh.WINDING_ORDER_UNKNOWN=2;
GLGE.Mesh.WINDING_ORDER_CLOCKWISE=1;
GLGE.Mesh.WINDING_ORDER_COUNTER=0;
GLGE.augment(GLGE.QuickNotation,GLGE.Mesh);
GLGE.augment(GLGE.JSONLoader,GLGE.Mesh);
GLGE.augment(GLGE.Events,GLGE.Mesh);
GLGE.Mesh.prototype.gl=null;
GLGE.Mesh.prototype.className="Mesh";
GLGE.Mesh.prototype.GLbuffers=null;
GLGE.Mesh.prototype.buffers=null;
GLGE.Mesh.prototype.setBuffers=null;
GLGE.Mesh.prototype.GLfaces=null;
GLGE.Mesh.prototype.faces=null;
GLGE.Mesh.prototype.UV=null;
GLGE.Mesh.prototype.joints=null;
GLGE.Mesh.prototype.invBind=null;
GLGE.Mesh.prototype.loaded=false;
/**
* @name GLGE.Mesh#shaderupdate
* @event fired when the shader needs updating
* @param {object} data
*/
/**
* Gets the bounding volume for the mesh
* @returns {GLGE.BoundingVolume}
*/
GLGE.Mesh.prototype.getBoundingVolume=function(){
if(!this.positions) return new GLGE.BoundingVolume(0,0,0,0,0,0);
if(!this.boundingVolume){
var minX,maxX,minY,maxY,minZ,maxZ;
var positions=this.positions;
for(var i=0;i0){
t=scaleVec3(t,-1);
b=scaleVec3(b,-1);
}
return [t,b];
}
/**
* Sets the faces for this mesh
* @param {Number[]} jsArray The 1 dimentional array of normals
*/
GLGE.Mesh.prototype.setFaces=function(jsArray){
this.faces={data:jsArray,GL:false};
//if at this point calculate normals if we haven't got them yet
if(!this.normals) this.calcNormals();
if(!this.tangents && this.UV.length>0) this.calcTangents();
return this;
}
/**
* Calculates the tangents for this mesh - this is messy FIX ME!
* @private
*/
GLGE.Mesh.prototype.calcTangents=function(){
for(var j=0;j0){
tangentsTemp.push(tangents[faces[i]*3]);
tangentsTemp.push(tangents[faces[i]*3+1]);
tangentsTemp.push(tangents[faces[i]*3+2]);
}
if(uv1){
uv1Temp.push(uv1[faces[i]*2]);
uv1Temp.push(uv1[faces[i]*2+1]);
}
if(uv2){
uv2Temp.push(uv2[faces[i]*2]);
uv2Temp.push(uv2[faces[i]*2+1]);
}
}
}else{
vertsTemp=verts;
normalsTemp=normals;
tangentsTemp=tangents;
uv1Temp=uv1;
uv2Temp=uv2;
}
var newVerts=[];
var newNormals=[];
var newFaces=[];
var newUV1s=[];
var newUV2s=[];
var newTangents=[];
var stack=[];
for(var i=0;i0){
newTangents.push(tangentsTemp[i]);
newTangents.push(tangentsTemp[i+1]);
newTangents.push(tangentsTemp[i+2]);
}
if(uv1){
newUV1s.push(uv1Temp[i/3*2]);
newUV1s.push(uv1Temp[i/3*2+1]);
}
if(uv2){
newUV2s.push(uv2Temp[i/3*2]);
newUV2s.push(uv2Temp[i/3*2+1]);
}
}
newFaces.push(vertIdx);
}
this.setPositions(newVerts).setNormals(newNormals).setFaces(newFaces).setUV(newUV1s).setUV2(newUV2s).setTangents(newTangents);
}
/**
* Sets the Attributes for this mesh
* @param {WebGLContext} gl The context being drawn on
* @private
*/
GLGE.Mesh.prototype.GLAttributes=function(gl,shaderProgram,frame1, frame2){
this.gl=gl;
if(!frame1) frame1=0;
//if at this point we have no normals set then calculate them
if(!this.normals) this.calcNormals();
//disable all the attribute initially arrays - do I really need this?
for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
//check if the faces have been updated
if(!this.faces.GL && this.faces.data && this.faces.data.length>0){
this.GLSetFaceBuffer(gl);
this.faces.GL=true;
}
//loop though the buffers
for(i=0; i-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers[this.buffers[i].name]);
gl.enableVertexAttribArray(attribslot);
gl.vertexAttribPointer(attribslot, this.GLbuffers[this.buffers[i].name].itemSize, gl.FLOAT, false, 0, 0);
}
}
//do the position normal and if we have tangent then tangent
var positionSlot=GLGE.getAttribLocation(gl,shaderProgram, "position");
if(positionSlot>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["position"+frame1]);
gl.enableVertexAttribArray(positionSlot);
gl.vertexAttribPointer(positionSlot, this.GLbuffers["position"+frame1].itemSize, gl.FLOAT, false, 0, 0);
}
var normalSlot=GLGE.getAttribLocation(gl,shaderProgram, "normal");
if(normalSlot>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["normal"+frame1]);
gl.enableVertexAttribArray(normalSlot);
gl.vertexAttribPointer(normalSlot, this.GLbuffers["normal"+frame1].itemSize, gl.FLOAT, false, 0, 0);
}
var tangentSlot=GLGE.getAttribLocation(gl,shaderProgram, "tangent");
if(tangentSlot>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["tangent"+frame1]);
gl.enableVertexAttribArray(tangentSlot);
gl.vertexAttribPointer(tangentSlot, this.GLbuffers["tangent"+frame1].itemSize, gl.FLOAT, false, 0, 0);
}
if(frame2!=undefined){
var positionSlot2=GLGE.getAttribLocation(gl,shaderProgram, "position2");
if(positionSlot2>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["position"+frame2]);
gl.enableVertexAttribArray(positionSlot2);
gl.vertexAttribPointer(positionSlot2, this.GLbuffers["position"+frame2].itemSize, gl.FLOAT, false, 0, 0);
}
var normalSlot2=GLGE.getAttribLocation(gl,shaderProgram, "normal2");
if(normalSlot2>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["normal"+frame2]);
gl.enableVertexAttribArray(normalSlot2);
gl.vertexAttribPointer(normalSlot2, this.GLbuffers["normal"+frame2].itemSize, gl.FLOAT, false, 0, 0);
}
var tangentSlot2=GLGE.getAttribLocation(gl,shaderProgram, "tangent2");
if(tangentSlot2>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.GLbuffers["tangent"+frame2]);
gl.enableVertexAttribArray(tangentSlot2);
gl.vertexAttribPointer(tangentSlot2, this.GLbuffers["tangent"+frame2].itemSize, gl.FLOAT, false, 0, 0);
}
}
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2011, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_sphere.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Used to generate a basic sphere mesh
* @augments GLGE.Mesh
*/
GLGE.Sphere=function(uid){
this.vertical=10;
this.horizontal=10;
this.radius=1;
this.dirtySphere=false;
GLGE.Mesh.apply(this,arguments);
this.generateMeshData();
}
GLGE.augment(GLGE.Mesh,GLGE.Sphere);
/**
* @private
*/
GLGE.Sphere.prototype.generateMeshData=function(){
var vertical=this.vertical;
var horizontal=this.horizontal;
var radius=this.radius;
var t1,y,r1,i,j,x,y,t2;
var verts=[];
var normals=[];
var faces=[];
for(i=0;i<=vertical;i++){
t1=i/vertical*Math.PI;
y=Math.cos(t1)*radius;
r1=Math.sin(t1)*radius;
for(j=0;j0){
for(j=0;j0) color={r:color,g:color,b:color};
if(!color.r){
color=GLGE.colorParse(color);
}
this.emit={r:parseFloat(color.r),g:parseFloat(color.g),b:parseFloat(color.b)};
this.fireEvent("shaderupdate",{});
return this;
};
/**
* Sets how much the Red material should emit
* @param {Number} value what Red to emit
*/
GLGE.Material.prototype.setEmitR=function(value){
this.emit.r=parseFloat(value);
return this;
};
/**
* Sets how much the green material should emit
* @param {Number} value what green to emit
*/
GLGE.Material.prototype.setEmitG=function(value){
this.emit.g=parseFloat(value);
return this;
};
/**
* Sets how much the blue material should emit
* @param {Number} value what blue to emit
*/
GLGE.Material.prototype.setEmitB=function(value){
this.emit.b=parseFloat(value);
return this;
};
/**
* Sets how much the Red material should emit
* @returns Red to emit
*/
GLGE.Material.prototype.getEmitR=function(value){
return this.emit.r;
};
/**
* Sets how much the green material should emit
* @returns green to emit
*/
GLGE.Material.prototype.getEmitG=function(value){
return this.emit.g;
};
/**
* Sets how much the blue material should emit
* @returns blue to emit
*/
GLGE.Material.prototype.getEmitB=function(value){
return this.emit.b;
};
/**
* Gets the amount this material emits
* @return {Number} The emit value for the material
*/
GLGE.Material.prototype.getEmit=function(){
return this.emit;
};
/**
* Sets reflectivity of the material
* @param {Number} value how much to reflect (0-1)
*/
GLGE.Material.prototype.setReflectivity=function(value){
this.reflect=value;
this.fireEvent("shaderupdate",{});
return this;
};
/**
* Gets the materials reflectivity
* @return {Number} The reflectivity of the material
*/
GLGE.Material.prototype.getReflectivity=function(){
return this.reflect;
};
/**
* Sets the material to output with 0 alpha or 1 alpha
* @param {boolean} value binary alpha flag
*/
GLGE.Material.prototype.setBinaryAlpha=function(value){
this.binaryAlpha=value;
this.fireEvent("shaderupdate",{});
return this;
};
/**
* Gets the binary alpha flag
* @return {boolean} The binary alpha flag
*/
GLGE.Material.prototype.getBinaryAlpha=function(){
return this.binaryAlpha;
};
/**
* Add a new layer to the material
* @param {MaterialLayer} layer The material layer to add to the material
*/
GLGE.Material.prototype.addMaterialLayer=function(layer){
if(typeof layer=="string") layer=GLGE.Assets.get(layer);
this.layers.push(layer);
var material=this;
var listener=function(event){
material.fireEvent("shaderupdate",{});
};
this.layerlisteners.push(listener);
layer.addEventListener("shaderupdate",listener);
this.fireEvent("shaderupdate",{});
return this;
};
/**
* Removes a layer from the material
* @param {MaterialLayer} layer The material layer to remove
*/
GLGE.Material.prototype.removeMaterialLayer=function(layer){
var idx=this.layers.indexOf(layer);
if(idx>=0){
this.layers.splice(idx,1);
layer.removeEventListener("shaderupdate",this.layerlisteners[idx]);
this.layerlisteners.splice(idx,1);
this.fireEvent("shaderupdate",{});
}
return this;
};
/**
* Gets all the materials layers
* @returns {GLGE.MaterialLayer[]} all of the layers contained within this material
*/
GLGE.Material.prototype.getLayers=function(){
return this.layers;
};
/**
* Generate the code required to calculate the texture coords for each layer
* @private
*/
GLGE.Material.prototype.getLayerCoords=function(shaderInjection){
var shader=[];
shader.push("vec4 texturePos;\n");
for(var i=0; ineye.z*steepdisplace"+i+"){";
shader=shader+"textureHeight=vec3(vec2(neye.x,neye.y)*steepdisplace"+i+",0.0);";
shader=shader+"}else{";
shader=shader+"steepdisplace"+i+"-=steepstep"+i+";";
shader=shader+"steepstep"+i+"*=0.5;";
shader=shader+"}";
shader=shader+"steepdisplace"+i+"+=steepstep"+i+";";
shader=shader+"}";
}
if((this.layers[i].mapto & GLGE.M_SPECCOLOR) == GLGE.M_SPECCOLOR){
shader=shader+"specC = specC*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
}
if((this.layers[i].mapto & GLGE.M_MSKR) == GLGE.M_MSKR){
shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r;\n";
}
if((this.layers[i].mapto & GLGE.M_MSKG) == GLGE.M_MSKG){
shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g;\n";
}
if((this.layers[i].mapto & GLGE.M_MSKB) == GLGE.M_MSKB){
shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b;\n";
}
if((this.layers[i].mapto & GLGE.M_MSKA) == GLGE.M_MSKA){
shader=shader+"mask = texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a;\n";
}
if((this.layers[i].mapto & GLGE.M_SPECULAR) == GLGE.M_SPECULAR){
shader=shader+"spec = spec*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").r*mask;\n";
}
if((this.layers[i].mapto & GLGE.M_REFLECT) == GLGE.M_REFLECT){
shader=shader+"ref = ref*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").g*mask;\n";
}
if((this.layers[i].mapto & GLGE.M_SHINE) == GLGE.M_SHINE){
shader=shader+"sh = sh*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").b*mask*255.0;\n";
}
if((this.layers[i].mapto & GLGE.M_EMIT) == GLGE.M_EMIT){
shader=shader+"em = em*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
}
if((this.layers[i].mapto & GLGE.M_NOR) == GLGE.M_NOR){
shader=shader+"normalmap = normalmap*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+")*mask;\n";
shader=shader+"normal = normalmap.rgb;\n";
shader=shader+"normal = 2.0*(vec3(normal.r, -normal.g, normal.b) - vec3(0.5, -0.5, 0.5));";
shader=shader+"b=normalize(cross(t.xyz,n));\n";
shader=shader+"normal = normal.x*t + normal.y*b + normal.z*n;";
shader=shader+"normal = normalize(normal);";
}
if((this.layers[i].mapto & GLGE.M_ALPHA) == GLGE.M_ALPHA){
anyAlpha=true;
shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").a*mask;\n";
}
if((this.layers[i].mapto & GLGE.M_AMBIENT) == GLGE.M_AMBIENT){
shader=shader+"amblight = amblight*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[i].texture.idx+", textureCoords."+txcoord+").rgb*mask;\n";
}
}
shader=shader+"amblight *= amb;\n";
if (!anyAlpha && this.layers.length) {
if(this.layers[diffuseLayer].getTexture().className=="Texture" || this.layers[diffuseLayer].getTexture().className=="TextureCanvas" || this.layers[diffuseLayer].getTexture().className=="TextureVideo" ) {
var txcoord="xy";
var sampletype="2D";
}else{
var txcoord="xyz";
var sampletype="Cube";
}
shader=shader+"al = al*(1.0-mask) + texture"+sampletype+"(TEXTURE"+this.layers[diffuseLayer].texture.idx+", textureCoords."+txcoord+").a*al*mask;\n";
}
if(colors && this.vertexColorMode==GLGE.VC_MUL){
shader=shader+"color *= vcolor;";
}
if(this.binaryAlpha) {
shader=shader+"if(al<0.5) discard;\n";
shader=shader+"al=1.0;\n";
}else{
shader=shader+"if(al==0.0) discard;\n";
}
shader=shader+"vec3 lightvalue=amblight;\n";
if(colors && this.vertexColorMode==GLGE.VC_AMB){
shader=shader+"lightvalue = vcolor.rgb;";
}
if(colors && this.vertexColorMode==GLGE.VC_AMBMUL){
shader=shader+"lightvalue *= vcolor.rgb;";
}
shader=shader+"float dotN,spotEffect;";
shader=shader+"vec3 lightvec=vec3(0.0,0.0,0.0);";
shader=shader+"vec3 viewvec=vec3(0.0,0.0,0.0);";
shader=shader+"vec3 specvalue=vec3(0.0,0.0,0.0);";
shader=shader+"vec2 scoord=vec2(0.0,0.0);";
shader=shader+"float sDepth=0.0;";
shader=shader+"float d1=0.0;";
shader=shader+"float d2=0.0;";
shader=shader+"float spotmul=0.0;";
shader=shader+"float rnd=0.0;";
shader=shader+"float spotsampleX=0.0;";
shader=shader+"float spotsampleY=0.0;";
shader=shader+"float totalweight=0.0;";
shader=shader+"int cnt=0;";
shader=shader+"float specularSmoothStepValue=.125;\n";
shader=shader+"vec2 spotoffset=vec2(0.0,0.0);";
shader=shader+"float dp=0.0;";
shader=shader+"vec4 dist;float depth,m1,m2,prob,variance;\n";
shader=shader+"if (normal.z<0.0) {normal.z=0.0;}\n";
shader=shader+"float fogfact=1.0;";
shader=shader+"if(fogtype=="+GLGE.FOG_QUADRATIC+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+") fogfact=clamp(pow(max((fogfar - length(eyevec)) / (fogfar - fognear),0.0),2.0),0.0,1.0);\n";
shader=shader+"if(fogtype=="+GLGE.FOG_LINEAR+" || fogtype=="+GLGE.FOG_SKYLINEAR+") fogfact=clamp((fogfar - length(eyevec)) / (fogfar - fognear),0.0,1.0);\n";
if(!shadow){
shader=shader+"if (emitpass) {gl_FragColor=vec4(em,1.0);} else if (shadeless) {\n";
shader=shader+"gl_FragColor=vec4(color.rgb,al);\n";
if(this.fadeDistance>0){
shader=shader+"gl_FragColor.a=gl_FragColor.a*(1.0-min(1.0,"+this.fadeDistance.toFixed(5)+"/length(eyevec)));\n";
}
shader=shader+"} else {\n";
for(var i=0; i0.0){\n";
if(lights[i].diffuse){
shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
}
shader=shader+"}\n";
if(lights[i].specular){
shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN)*att * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3*sh);\n";
}
}
shader=shader+"spotEffect = 0.0;\n";
if(lights[i].type==GLGE.L_SPOT){
shader=shader+"spotEffect = dot(normalize(lightdir"+i+"), normalize(-lightvec"+i+"));";
shader=shader+"if (spotEffect > spotCosCutOff"+i+""+(!this.spotCutOff ? " || spotEffect>0.0" : "")+") {\n";
shader=shader+"spotEffect = pow(spotEffect, spotExp"+i+");";
//spot shadow stuff
if(lights[i].getCastShadows() && this.shadow){
shader=shader+"scoord=(((spotcoord"+i+".xy)/spotcoord"+i+".w)+1.0)/2.0;\n";
shader=shader+"if(scoord.x>0.0 && scoord.x<1.0 && scoord.y>0.0 && scoord.y<1.0){\n";
shader=shader+"dist=texture2D(TEXTURE"+(shadowlights[i])+", scoord);\n";
if(lights[i].spotSoftness==0){
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0))*"+lights[i].distance+".0;\n";
shader=shader+"if(depth0.0){\n";
if(lights[i].diffuse){
shader=shader+"lightvalue -= (1.0-spotEffect) / (lightAttenuation"+i+"[0] + lightAttenuation"+i+"[1] * lightdist"+i+" + lightAttenuation"+i+"[2] * lightdist"+i+" * lightdist"+i+");\n";
}
shader=shader+"}\n";
}else{
shader=shader+"att = spotEffect / (lightAttenuation"+i+"[0] + lightdist"+i+"*(lightAttenuation"+i+"[1] + lightAttenuation"+i+"[2] * lightdist"+i+"));\n";
shader=shader+"if(dotN>0.0){\n";
if(lights[i].diffuse){
shader=shader+"lightvalue += att * dotN * lightcolor"+i+";\n";
}
shader=shader+"}\n";
if(lights[i].specular){
shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * att * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
}
}
shader=shader+"}\n";
}
if(lights[i].type==GLGE.L_DIR){
if(this.translucency==0){
shader=shader+"dotN=max(dot(normal,normalize(-lightvec)),0.0);\n";
}else{
shader=shader+"dotN=dot(normal,normalize(-lightvec));\n";
shader=shader+"if (dotN<0.0) dotN*=-"+this.translucency.toFixed(2)+";\n";
}
if(lights[i].getCastShadows() && this.shadow){
shader=shader+"float shadowfact"+i+" = 0.0;\n";
shader=shader+"scoord=((spotcoord"+i+".xy)/spotcoord"+i+".w+1.0)/2.0;\n";
var lightWidth=1/lights[i].bufferWidth;
var lightHeight=1/lights[i].bufferHeight;
shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord );\n";
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));\n";
shader=shader+"d1 = depth;\n";
shader=shader+"d2 = depth*depth;\n";
shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2("+(lightWidth).toFixed(5)+","+(lightHeight).toFixed(5)+") );\n";
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));\n";
shader=shader+"d1 += depth;\n";
shader=shader+"d2 += depth*depth;\n";
shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2(-"+lightWidth.toFixed(5)+","+lightHeight.toFixed(5)+"));\n";
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));\n";
shader=shader+"d1 += depth;\n";
shader=shader+"d2 += depth*depth;\n";
shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2("+lightWidth.toFixed(5)+",-"+lightHeight.toFixed(5)+"));\n";
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));\n";
shader=shader+"d1 += depth;\n";
shader=shader+"d2 += depth*depth;\n";
shader=shader+"dist=texture2D(TEXTURE"+shadowlights[i]+", scoord+vec2(-"+lightWidth.toFixed(5)+",-"+lightHeight.toFixed(5)+"));\n";
shader=shader+"depth = dot(dist, vec4(0.000000059604644775390625,0.0000152587890625,0.00390625,1.0));\n";
shader=shader+"d1 += depth;\n";
shader=shader+"d2 += depth*depth;\n";
shader=shader+"d1 *= 0.2;\n";
shader=shader+"d2 *= 0.2;\n";
shader=shader+"sDepth = max(0.0, ((spotcoord"+i+".z/spotcoord"+i+".w)+1.0)/2.0-d1-"+lights[i].shadowBias+");\n";
shader=shader+"variance = min(max(d2-d1*d1, 0.0)+"+lights[i].varianceMin+", 1.0);\n";
shader=shader+"prob=variance /( variance + sDepth*sDepth );\n";
shader=shader+"prob=smoothstep("+lights[i].bleedCutoff.toFixed(2)+",1.0,prob);\n";
shader=shader+"shadowfact"+i+"=prob;\n";
}else{
shader=shader+"float shadowfact"+i+" = 1.0;\n";
}
if(lights[i].diffuse){
if(lights[i].negativeShadow){
shader=shader+"lightvalue -= lightcolor"+i+"-(dotN * lightcolor"+i+" * shadowfact"+i+");\n";
}else{
shader=shader+"shadowfact"+i+"="+this.translucency.toFixed(2)+"+"+(1-this.translucency).toFixed(2)+"*shadowfact"+i+";\n";
shader=shader+"lightvalue += dotN * lightcolor"+i+" * shadowfact"+i+";\n";
}
}
if(lights[i].specular){
shader=shader+"specvalue += smoothstep(-specularSmoothStepValue,specularSmoothStepValue,dotN) * specC * lightcolor"+i+" * spec * pow(max(dot(reflect(normalize(lightvec), normal),normalize(viewvec)),0.0), 0.3 * sh);\n";
}
}
}
shader=shader+"lightvalue = (lightvalue)*ref;\n";
shader=shader+"vec3 fc=fogcolor.rgb;\n";
shader=shader+"if(fogtype=="+GLGE.FOG_SKYLINEAR+" || fogtype=="+GLGE.FOG_SKYQUADRATIC+"){";
shader=shader+"vec4 view=projection * vec4(-eyevec,1.0);\n";
shader=shader+"vec2 fogCoords=view.xy/view.w*0.5+0.5;\n";
shader=shader+"fc=texture2D(sky,fogCoords.xy).rgb;\n";
shader=shader+"}\n";
shader=shader+"vec4 finalColor =vec4(specvalue.rgb+color.rgb*lightvalue.rgb+em.rgb,al)*fogfact+vec4(fc,al)*(1.0-fogfact);\n";
if(shaderInjection && ~shaderInjection.indexOf("GLGE_FragColor")){
shader=shader+"finalColor=GLGE_FragColor(finalColor);\n";
}
if(this.fadeDistance>0){
shader=shader+"finalColor.a=finalColor.a*(1.0-min(1.0,"+this.fadeDistance.toFixed(5)+"/length(eyevec)));\n";
}
if(this.fadeDistance<0){
shader=shader+"finalColor.a=finalColor.a*(min(1.0,"+(-this.fadeDistance).toFixed(5)+"/length(eyevec)));\n";
}
shader=shader+"gl_FragColor = finalColor;";
//shader=shader+"gl_FragColor = vec4(color.rgb,1.0);";
if(GLGE.DEBUGNORMALS) shader=shader+"gl_FragColor = vec4(normal.rgb,1.0);";
if(GLGE.DEBUGCOORD0) shader=shader+"gl_FragColor = vec4(textureCoords0.rg,0.0,1.0);";
shader=shader+"}\n"; //end emit pass test
}else{
shader=shader+"float shadowdepth = gl_FragCoord.z;\n";
shader=shader+"if(shadowtype) shadowdepth=length(eyevec)/distance;\n";
shader=shader+"vec4 rgba=fract(shadowdepth * vec4(16777216.0, 65536.0, 256.0, 1.0));\n";
shader=shader+"gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);\n";
}
shader=shader+"}\n";
return shader;
};
/**
* Set the uniforms needed to render this material
* @private
*/
GLGE.Material.prototype.textureUniforms=function(gl,shaderProgram,lights,object){
if(this.animation) this.animate();
var pc=shaderProgram.caches;
if(!pc.baseColor || pc.baseColor.r!=this.color.r || pc.baseColor.g!=this.color.g || pc.baseColor.b!=this.color.b || pc.baseColor.a!=this.color.a){
if(!this.ccache || this.ccache.r!=this.color.r || this.ccache.g!=this.color.g || this.ccache.b!=this.color.b || this.ccache.a!=this.color.a){
this.ccache=this.color;
this.glColor=new Float32Array([this.color.r,this.color.g,this.color.b,this.color.a]);
}
gl.uniform4fv(GLGE.getUniformLocation(gl,shaderProgram, "baseColor"), this.glColor);
pc.baseColor=this.color;
}
if(pc.specColor!=this.specColor){
if(this.sccache!=this.specColor){
this.sccache=this.specColor;
this.glspecColor=new Float32Array([this.specColor.r,this.specColor.g,this.specColor.b]);
}
gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "specColor"), this.glspecColor);
pc.specColor=this.specColor;
}
if(pc.emit!=this.emit){
gl.uniform3f(GLGE.getUniformLocation(gl,shaderProgram, "emit"), this.emit.r,this.emit.g,this.emit.b);
pc.emit=this.emit;
}
if(pc.specular!=this.specular){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "specular"), this.specular);
pc.specular=this.specular;
}
if(pc.shine!=this.shine){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "shine"), this.shine);
pc.shine=this.shine;
}
if(pc.reflect!=this.reflect){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "reflective"), this.reflect);
pc.reflect=this.reflect;
}
if(pc.alpha!=this.alpha){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,shaderProgram, "alpha"), this.alpha);
pc.alpha=this.alpha;
}
if(pc.shadeless==undefined || pc.shadeless!=this.shadeless){
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,shaderProgram, "shadeless"), this.shadeless);
pc.shadeless=this.shadeless;
}
/*
if(this.ambient && pc.ambient!=this.ambient){
gl.uniform3fv(GLGE.getUniformLocation(gl,shaderProgram, "amb"), new Float32Array([this.ambient.r,this.ambient.g,this.ambient.b]));
pc.ambient=this.ambient;
}
*/
var cnt=1;
var num=0;
if(!pc["lightcolor"]){
pc["lightcolor"]=[];
pc["lightAttenuation"]=[];
pc["spotCosCutOff"]=[];
pc["spotExponent"]=[];
pc["shadowbias"]=[];
pc["castshadows"]=[];
pc["shadowsamples"]=[];
pc["shadowsoftness"]=[];
}
if(lights){
for(var i=0; i1){
for(var i=1; icurrentSize && size0;
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_texturecamera.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A reflection texture will reflect in a plane for a specified transform
* @param {string} uid the unique id for this texture
* @see GLGE.Material
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.TextureCamera=function(uid){
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.TextureCamera);
GLGE.augment(GLGE.JSONLoader,GLGE.TextureCamera);
GLGE.augment(GLGE.Events,GLGE.TextureCamera);
GLGE.TextureCamera.prototype.className="Texture";
GLGE.TextureCamera.prototype.texture=null;
GLGE.TextureCamera.prototype.glTexture=null;
GLGE.TextureCamera.prototype.object=null;
GLGE.TextureCamera.prototype.camera=null;
GLGE.TextureCamera.prototype.bufferHeight=0;
GLGE.TextureCamera.prototype.bufferWidth=0;
GLGE.TextureCamera.prototype.planeOffset=0;
GLGE.TextureCamera.prototype.mirrorAxis=GLGE.NONE;
GLGE.TextureCamera.prototype.clipAxis=GLGE.NONE;
GLGE.TextureCamera.prototype.autoUpdate=true;
GLGE.TextureCamera.prototype.rendered=false;
/**
* Forces an update of the cube map texture
**/
GLGE.TextureCamera.prototype.render=function(){
this.rendered=false;
return this;
}
/**
* set the auto update flag
* @param {number} buffer width
**/
GLGE.TextureCamera.prototype.setAutoUpdate=function(auto){
this.autoUpdate=auto;
return this;
}
/**
* gets the auto update flag
* @returns the width
**/
GLGE.TextureCamera.prototype.getAutoUpdate=function(){
return this.autoUpdate;
}
/**
* sets the RTT render clipping plane offset
* @param {number} buffer width
**/
GLGE.TextureCamera.prototype.setPlaneOffset=function(planeoffset){
this.planeOffset=planeoffset;
return this;
}
/**
* gets the RTT render clipping plane offset
* @returns the width
**/
GLGE.TextureCamera.prototype.getPlaneOffset=function(){
return this.planeOffset;
}
/**
* sets the RTT render buffer width
* @param {number} buffer width
**/
GLGE.TextureCamera.prototype.setBufferWidth=function(width){
this.bufferWidth=width;
this.update=true;
return this;
}
/**
* gets the RTT render buffer width
* @returns the width
**/
GLGE.TextureCamera.prototype.getBufferWidth=function(){
return this.bufferWidth;
}
/**
* sets the RTT render buffer height
* @param {number} buffer height
**/
GLGE.TextureCamera.prototype.setBufferHeight=function(height){
this.bufferHeight=height;
this.update=true;
return this;
}
/**
* gets the RTT render buffer height
* @returns the height
**/
GLGE.TextureCamera.prototype.getBufferHeight=function(){
return this.bufferHeight;
}
/**
* sets the RTT clip axis
* @param {number} the axis
**/
GLGE.TextureCamera.prototype.setClipAxis=function(camera){
this.clipAxis=camera;
return this;
}
/**
* gets the RTT clip axis
* @returns the axis
**/
GLGE.TextureCamera.prototype.getClipAxis=function(){
return this.clipAxis;
}
/**
* sets the RTT mirror axis
* @param {number} the axis
**/
GLGE.TextureCamera.prototype.setMirrorAxis=function(camera){
this.mirrorAxis=camera;
return this;
}
/**
* gets the RTT mirror axis
* @returns the axis
**/
GLGE.TextureCamera.prototype.getMirrorAxis=function(){
return this.mirrorAxis;
}
/**
* sets the RTT camera to use
* @param {GLGE.Camera} the source camera
**/
GLGE.TextureCamera.prototype.setCamera=function(camera){
this.camera=camera;
return this;
}
/**
* gets the RTT source camera
* @returns {GLGE.Camera} the source camera
**/
GLGE.TextureCamera.prototype.getCamera=function(){
return this.camera;
}
/**
* does what is needed to get the texture
* @private
**/
GLGE.TextureCamera.prototype.doTexture=function(gl,object){
if(this.camera){
if(this.autoRender || !this.rendered || true){
this.rendered=true;
this.gl=gl;
var modelmatrix=object.getModelMatrix();
var tpmat=this.camera.pMatrix;
var tbmat=this.camera.matrix;
this.camera.pMatrix=null;
this.camera.matrix=null;
var pmatrix=this.camera.getProjectionMatrix().slice(0);
var cameramatrix=this.camera.getViewMatrix().slice(0);
this.camera.pMatrix=tpmat;
this.camera.matrix=tbmat;
var matrix;
if(this.mirrorAxis){
switch(this.mirrorAxis){
case GLGE.XAXIS:
matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(-1,1,1)),GLGE.inverseMat4(modelmatrix));
break;
case GLGE.YAXIS:
matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(1,-1,1)),GLGE.inverseMat4(modelmatrix));
break;
case GLGE.ZAXIS:
matrix=GLGE.mulMat4(GLGE.mulMat4(GLGE.mulMat4(cameramatrix,modelmatrix),GLGE.scaleMatrix(1,1,-1)),GLGE.inverseMat4(modelmatrix));
break;
}
}else{
matrix=cameramatrix;
}
if(this.clipAxis){
var clipplane
switch(this.clipAxis){
case GLGE.NEG_XAXIS:
var dirnorm=GLGE.toUnitVec3([-modelmatrix[0],-modelmatrix[4],-modelmatrix[8]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
case GLGE.POS_XAXIS:
var dirnorm=GLGE.toUnitVec3([modelmatrix[0],modelmatrix[4],modelmatrix[8]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
case GLGE.NEG_YAXIS:
var dirnorm=GLGE.toUnitVec3([-modelmatrix[1],-modelmatrix[5],-modelmatrix[9]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
case GLGE.POS_YAXIS:
var dirnorm=GLGE.toUnitVec3([modelmatrix[1],modelmatrix[5],modelmatrix[9]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
case GLGE.NEG_ZAXIS:
var dirnorm=GLGE.toUnitVec3([-modelmatrix[2],-modelmatrix[6],-modelmatrix[10]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
case GLGE.POS_ZAXIS:
var dirnorm=GLGE.toUnitVec3([modelmatrix[2],modelmatrix[6],modelmatrix[10]]);
clipplane=[dirnorm[0],dirnorm[1],dirnorm[2],-GLGE.dotVec3([modelmatrix[3],modelmatrix[7],modelmatrix[11]],dirnorm)-this.planeOffset];
break;
}
var itmvp=GLGE.transposeMat4(GLGE.inverseMat4(GLGE.mulMat4(pmatrix,matrix)));
clipplane=GLGE.mulMat4Vec4(itmvp,clipplane);
clipplane=GLGE.scaleVec4(clipplane,pmatrix[10]);
clipplane[3] -= 1;
if(clipplane[2]<0) GLGE.scaleVec4(clipplane,-1);
var suffix=[ 1,0,0,0,
0,1,0,0,
clipplane[0],clipplane[1],clipplane[2],clipplane[3],
0,0,0,1];
pmatrix=GLGE.mulMat4(suffix,pmatrix);
}
var height=(!this.bufferHeight ? gl.scene.renderer.canvas.height : this.bufferHeight);
var width=(!this.bufferWidth ? gl.scene.renderer.canvas.width : this.bufferWidth);
//create the texture if it's not already created
if(!this.glTexture || this.update){
this.createFrameBuffer(gl);
gl.scene.addRenderPass(this.frameBuffer,matrix, gl.scene.camera.getProjectionMatrix(),width,height,object, this.mirrorAxis ? true : false);
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
this.update=false;
return false;
}else{
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.scene.addRenderPass(this.frameBuffer,matrix, pmatrix,width,height,object, this.mirrorAxis ? true : false);
return true;
}
}else{
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
}
}else{
return false;
}
}
GLGE.TextureCamera.prototype.registerPasses=GLGE.TextureCamera.prototype.doTexture;
/**
* Creates the frame buffer for our texture
* @private
*/
GLGE.TextureCamera.prototype.createFrameBuffer=function(gl){
var height=(!this.bufferHeight ? gl.scene.renderer.canvas.height : this.bufferHeight);
var width=(!this.bufferWidth ? gl.scene.renderer.canvas.width : this.bufferWidth);
if(!this.frameBuffer) this.frameBuffer = gl.createFramebuffer();
if(!this.renderBuffer) this.renderBuffer = gl.createRenderbuffer();
if(!this.glTexture) this.glTexture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
var tex = new Uint8Array(width*height*4);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, this.renderBuffer);
//dpeth stencil doesn't seem to work in either webkit or mozilla so don't use for now - reflected particles will be messed up!
//gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_STENCIL,width, height);
//gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, this.renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.glTexture, 0);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_texturecameracube.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A reflection texture will reflect in a plane for a specified transform
* @param {string} uid the unique id for this texture
* @see GLGE.Material
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.TextureCameraCube=function(uid){
GLGE.Assets.registerAsset(this,uid);
this.cubeBuffers=[];
}
GLGE.augment(GLGE.QuickNotation,GLGE.TextureCameraCube);
GLGE.augment(GLGE.JSONLoader,GLGE.TextureCameraCube);
GLGE.augment(GLGE.Events,GLGE.TextureCameraCube);
GLGE.TextureCameraCube.prototype.className="TextureCube";
GLGE.TextureCameraCube.prototype.texture=null;
GLGE.TextureCameraCube.prototype.glTexture=null;
GLGE.TextureCameraCube.prototype.object=null;
GLGE.TextureCameraCube.prototype.autoUpdate=false;
GLGE.TextureCameraCube.prototype.rendered=false;
GLGE.TextureCameraCube.prototype.bufferHeight=512;
GLGE.TextureCameraCube.prototype.bufferWidth=512;
GLGE.TextureCameraCube.prototype.offsetX=0;
GLGE.TextureCameraCube.prototype.offsetY=0;
GLGE.TextureCameraCube.prototype.offsetZ=0;
GLGE.TextureCameraCube.prototype.cameraMatries=[
[0,0,-1,0,
0,1,0,0,
-1,0,0,0,
0,0,0,1],
[0,0,1,0,
0,1,0,0,
1,0,0,0,
0,0,0,1],
[-1,0,0,0,
0,0,1,0,
0,-1,0,0,
0,0,0,1],
[-1,0,0,0,
0,0,-1,0,
0,1,0,0,
0,0,0,1],
[1,0,0,0,
0,1,0,0,
0,0,-1,0,
0,0,0,1],
[-1,0,0,0,
0,1,0,0,
0,0,1,0,
0,0,0,1]
];
GLGE.TextureCameraCube.prototype.pMatrix=GLGE.makePerspective(90, 1, 0.0001, 1000);
/**
* Forces an update of the cube map texture
**/
GLGE.TextureCameraCube.prototype.render=function(){
this.rendered=false;
return this;
}
/**
* set the X center offset
* @param {number} offset X offset for cube
**/
GLGE.TextureCameraCube.prototype.setOffsetX=function(offset){
this.offsetX=offset
return this;
}
/**
* Gets the X center offset
* @returns the X offset
**/
GLGE.TextureCameraCube.prototype.getOffsetX=function(){
return this.offsetX;
}
/**
* set the Y center offset
* @param {number} offset Y offset for cube
**/
GLGE.TextureCameraCube.prototype.setOffsetY=function(offset){
this.offsetY=offset
return this;
}
/**
* Gets the Y center offset
* @returns the Y offset
**/
GLGE.TextureCameraCube.prototype.getOffsetY=function(){
return this.offsetY;
}
/**
* set the Z center offset
* @param {number} offset Z offset for cube
**/
GLGE.TextureCameraCube.prototype.setOffsetZ=function(offset){
this.offsetZ=offset
return this;
}
/**
* Gets the X center offset
* @returns the X offset
**/
GLGE.TextureCameraCube.prototype.getOffsetZ=function(){
return this.offsetZ;
}
/**
* set the auto update flag
* @param {number} buffer width
**/
GLGE.TextureCameraCube.prototype.setAutoUpdate=function(auto){
this.autoUpdate=auto
return this;
}
/**
* gets the auto update flag
* @returns the width
**/
GLGE.TextureCameraCube.prototype.getAutoUpdate=function(){
return this.autoUpdate;
}
/**
* sets the RTT render buffer width
* @param {number} buffer width
**/
GLGE.TextureCameraCube.prototype.setBufferWidth=function(width){
this.bufferWidth=width;
this.update=true;
return this;
}
/**
* gets the RTT render buffer width
* @returns the width
**/
GLGE.TextureCameraCube.prototype.getBufferWidth=function(){
return this.bufferWidth;
}
/**
* sets the RTT render buffer height
* @param {number} buffer height
**/
GLGE.TextureCameraCube.prototype.setBufferHeight=function(height){
this.bufferHeight=height;
this.update=true;
return this;
}
/**
* gets the RTT render buffer height
* @returns the height
**/
GLGE.TextureCameraCube.prototype.getBufferHeight=function(){
return this.bufferHeight;
}
/**
* registers the render passes
* @private
**/
GLGE.TextureCameraCube.prototype.doTexture=function(gl,object){
this.gl=gl;
var objMatrix=object.getModelMatrix();
var height=this.bufferHeight;
var width=this.bufferWidth;
if(!this.cubeBuffers.length || this.update){
this.createFrameBuffers(gl);
this.update=false;
return false;
}
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
if(!this.rendered || this.autoUpdate){
for(var i=0;i<6;i++){
var matrix=this.cameraMatries[i].slice(0);
var m=GLGE.mulMat4(matrix,objMatrix);
var v=GLGE.mulMat4Vec3(m,[this.offsetX,this.offsetY,this.offsetZ,1]);
matrix[3]=-v[0];
matrix[7]=-v[1];
matrix[11]=-v[2];
gl.scene.addRenderPass(this.cubeBuffers[i],matrix, this.pMatrix,width,height,object,true);
}
this.rendered=true;
}
return true;
}
GLGE.TextureCameraCube.prototype.registerPasses=GLGE.TextureCameraCube.prototype.doTexture;
/**
* Creates the frame buffer and texture
* @private
*/
GLGE.TextureCameraCube.prototype.createFrameBuffers=function(gl){
var height=this.bufferHeight;
var width=this.bufferWidth;
var renderBuffer = gl.createRenderbuffer();
this.glTexture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16,width, height);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, width,height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
var frameBuffer
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_X, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_X, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_Y, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
frameBuffer = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_CUBE_MAP_POSITIVE_Z, this.glTexture, 0);
this.cubeBuffers.push(frameBuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_texturecanvas.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A canvase texture to be included in a material
* @param {string} uid the unique id for this texture
* @see GLGE.Material
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.TextureCanvas=function(uid){
this.canvas=document.createElement("canvas");
//temp canvas to force chrome to update FIX ME when bug sorted!
this.t=document.createElement("canvas");
this.t.width=1;
this.t.height=1;
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.TextureCanvas);
GLGE.augment(GLGE.JSONLoader,GLGE.TextureCanvas);
GLGE.augment(GLGE.Events,GLGE.TextureCanvas);
GLGE.TextureCanvas.prototype.className="TextureCanvas";
GLGE.TextureCanvas.prototype.glTexture=null;
GLGE.TextureCanvas.prototype.autoUpdate=true;
/**
* Gets the auto update flag
* @return {boolean} The auto update flag
*/
GLGE.TextureCanvas.prototype.getAutoUpdate=function(){
return this.autoUpdate;
};
/**
* Sets the auto update flag
* @param {boolean} value The auto update flag
*/
GLGE.TextureCanvas.prototype.setAutoUpdate=function(value){
this.autoUpdate=value;
return this;
};
/**
* Gets the canvas used by the texture
* @return {canvas} The textures image url
*/
GLGE.TextureCanvas.prototype.getCanvas=function(){
return this.canvas;
};
/**
* Sets the canvas used by the texture
* @param {canvas} canvas The canvas to use
*/
GLGE.TextureCanvas.prototype.setCanvas=function(canvas){
this.canvas=canvas;
return this;
};
/**
* Sets the canvas height
* @param {number} value The canvas height
*/
GLGE.TextureCanvas.prototype.setHeight=function(value){
this.canvas.height=value;
return this;
};
/**
* Sets the canvas width
* @param {number} value The canvas width
*/
GLGE.TextureCanvas.prototype.setWidth=function(value){
this.canvas.width=value;
return this;
};
/**
* gets the canvas height
* @returns {number} The canvas height
*/
GLGE.TextureCanvas.prototype.getHeight=function(){
return this.canvas.height;
};
/**
* gets the canvas width
* @returns {number} The canvas width
*/
GLGE.TextureCanvas.prototype.getWidth=function(){
return this.canvas.width;
};
/**
* does the canvas texture GL stuff
* @private
**/
GLGE.TextureCanvas.prototype.doTexture=function(gl){
this.gl=gl;
//create the texture if it's not already created
if(!this.glTexture){
this.glTexture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
this.updateCanvas(gl);
}else{
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
if(this.autoUpdate || this.doUpdate) this.updateCanvas(gl);
}
this.doUpdate=false;
return true;
}
/**
* Manually updates the canvas Texture
*/
GLGE.TextureCanvas.prototype.update=function(){
this.doUpdate=true;
}
/**
* Updates the canvas texture
* @private
*/
GLGE.TextureCanvas.prototype.updateCanvas=function(gl){
var canvas = this.canvas;
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.t); //force chrome to update remove when chrome bug fixed
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, canvas);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_texturecube.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A texture to be included in a material
* @param {string} uid the unique id for this texture
* @see GLGE.Material
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.TextureCube=function(uid){
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.TextureCube);
GLGE.augment(GLGE.JSONLoader,GLGE.TextureCube);
GLGE.augment(GLGE.Events,GLGE.TextureCube);
GLGE.TextureCube.prototype.className="TextureCube";
GLGE.TextureCube.prototype.posX=null;
GLGE.TextureCube.prototype.negX=null;
GLGE.TextureCube.prototype.posY=null;
GLGE.TextureCube.prototype.negY=null;
GLGE.TextureCube.prototype.posZ=null;
GLGE.TextureCube.prototype.negZ=null;
GLGE.TextureCube.prototype.texture=null;
GLGE.TextureCube.prototype.glTexture=null;
GLGE.TextureCube.prototype.loadState=0;
/**
* Sets the url for a given image
* @param {string} url the texture image url
* @param {string} image the image element to load
*/
GLGE.TextureCube.prototype.setSrc=function(url,image,mask){
this.url=url;
this.state=0;
this[image]=new Image();
var texture=this;
this[image].onload = function(){
texture.loadState+=mask;
}
this[image].src=url;
if(this.glTexture && this.gl) {
this.gl.deleteTexture(this.glTexture);
this.glTexture=null;
}
return this;
}
/**
* Sets the positive X cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcPosX=function(url){
this.setSrc(url,"posX",1);
return this;
};
/**
* Sets the negative X cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcNegX=function(url){
this.setSrc(url,"negX",2);
return this;
};
/**
* Sets the positive Y cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcPosY=function(url){
this.setSrc(url,"posY",4);
return this;
};
/**
* Sets the negative Y cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcNegY=function(url){
if(typeof url!="string"){
this.negY=url;
this.loadState+=8;
}else{
this.setSrc(url,"negY",8);
}
return this;
};
/**
* Sets the positive Z cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcPosZ=function(url){
this.setSrc(url,"posZ",16);
return this;
};
/**
* Sets the negative Z cube image
* @param {string} url the texture image url
*/
GLGE.TextureCube.prototype.setSrcNegZ=function(url){
this.setSrc(url,"negZ",32);
return this;
};
/**
* Sets the textures image location
* @private
**/
GLGE.TextureCube.prototype.doTexture=function(gl,object){
this.gl=gl;
//create the texture if it's not already created
if(!this.glTexture) this.glTexture=gl.createTexture();
//if the image is loaded then set in the texture data
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
if(this.loadState==63 && this.state==0){
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posX);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_X, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negX);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posY);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negY);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_POSITIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.posZ);
gl.texImage2D(gl.TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.negZ);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_MIN_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_CUBE_MAP, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.generateMipmap(gl.TEXTURE_CUBE_MAP);
gl.bindTexture(gl.TEXTURE_CUBE_MAP, null);
this.state=1;
}
gl.bindTexture(gl.TEXTURE_CUBE_MAP, this.glTexture);
if(this.state==1) return true;
else return false;
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_texturevideo.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class A video texture to be included in a material
* @param {string} uid the unique id for this texture
* @see GLGE.Material
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.TextureVideo=function(uid){
this.video=document.createElement("video");
this.video.style.display="none";
this.video.setAttribute("loop","loop");
this.video.autoplay=true;
//looping isn't working in firefox so quick fix!
this.video.addEventListener("ended", function() { this.play(); }, true);
//video needs to be part of page to work for some reason :-s
document.getElementsByTagName("body")[0].appendChild(this.video);
//used to get webkit working
this.canvas=document.createElement("canvas");
this.ctx=this.canvas.getContext("2d");
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.TextureVideo);
GLGE.augment(GLGE.JSONLoader,GLGE.TextureVideo);
GLGE.augment(GLGE.Events,GLGE.TextureVideo);
GLGE.TextureVideo.prototype.className="TextureVideo";
GLGE.TextureVideo.prototype.glTexture=null;
/**
* Gets the canvas used by the texture
* @return {video} The textures image url
*/
GLGE.TextureVideo.prototype.getVideo=function(){
return this.video;
};
/**
* Sets the video used by the texture
* @param {video} canvas The canvas to use
*/
GLGE.TextureVideo.prototype.setVideo=function(video){
this.video=video;
return this;
};
/**
* Sets the source used for the video
* @param {string} src The URL of the video
*/
GLGE.TextureVideo.prototype.setSrc=function(src){
this.video.src=src;
return this;
};
/**
* gets the source used for the video
* @returns {string} The URL of the video
*/
GLGE.TextureVideo.prototype.getSrc=function(src){
return this.video.src;
};
/**
* does the canvas texture GL stuff
* @private
**/
GLGE.TextureVideo.prototype.doTexture=function(gl){
this.gl=gl;
//create the texture if it's not already created
if(!this.glTexture){
this.glTexture=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
this.updateTexture(gl);
}else{
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
this.updateTexture(gl);
}
return true;
}
/**
* Updates the canvas texture
* @private
*/
GLGE.TextureVideo.prototype.updateTexture=function(gl){
var video = this.video;
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
//TODO: fix this when minefield is upto spec
if(video.readyState>0){
if(video.height<=0){
video.style.display="";
video.height=video.offsetHeight;
video.width=video.offsetWidth;
video.style.display="none";
}
this.canvas.height=video.height;
this.canvas.width=video.width;
this.ctx.drawImage(video, 0, 0);
try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.canvas);}
catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.canvas,null);}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
/*
use when video is working in webkit
try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video);}
catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, video,null);}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
*/
}
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_lod.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @name GLGE.ObjectLod#downloadComplete
* @event fires when all the assets for this LOD have finished loading
* @param {object} data
*/
/**
* @class Creates a new load for a multimaterial
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
* @augments GLGE.Events
*/
GLGE.ObjectLod=function(uid){
this.setMaterial(GLGE.DEFAULT_MATERIAL);
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.QuickNotation,GLGE.ObjectLod);
GLGE.augment(GLGE.JSONLoader,GLGE.ObjectLod);
GLGE.augment(GLGE.Events,GLGE.ObjectLod);
GLGE.ObjectLod.prototype.mesh=null;
GLGE.ObjectLod.prototype.className="ObjectLod";
GLGE.ObjectLod.prototype.material=null;
GLGE.ObjectLod.prototype.program=null;
GLGE.ObjectLod.prototype.GLShaderProgramPick=null;
GLGE.ObjectLod.prototype.GLShaderProgramShadow=null;
GLGE.ObjectLod.prototype.GLShaderProgram=null;
GLGE.ObjectLod.prototype.pixelSize=0;
/**
* sets the mesh
* @param {GLGE.Mesh} mesh
*/
GLGE.ObjectLod.prototype.setMesh=function(mesh){
if(typeof mesh=="string") mesh=GLGE.Assets.get(mesh);
//remove event listener from current material
if(this.mesh){
this.mesh.removeEventListener("shaderupdate",this.meshupdated);
this.mesh.removeEventListener("boundupdate",this.boundupdated);
}
var multiMaterial=this;
this.meshupdated=function(event){
multiMaterial.GLShaderProgram=null;
};
this.boundupdated=function(event){
multiMaterial.fireEvent("boundupdate",{});
};
//set event listener for new material
mesh.addEventListener("shaderupdate",this.meshupdated);
mesh.addEventListener("boundupdate",this.boundupdated);
this.GLShaderProgram=null;
this.mesh=mesh;
return this;
}
/**
* Checks if resources have finished downloading
* @returns {boolean}
*/
GLGE.ObjectLod.prototype.isComplete=function(){
return this.material.isComplete();
}
/**
* gets the mesh
* @returns {GLGE.Mesh}
*/
GLGE.ObjectLod.prototype.getMesh=function(){
return this.mesh;
}
/**
* sets the material
* @param {GLGE.Material} material
*/
GLGE.ObjectLod.prototype.setMaterial=function(material){
if(typeof material=="string") material=GLGE.Assets.get(material);
//remove event listener from current material
if(this.material){
this.material.removeEventListener("shaderupdate",this.materialupdated);
this.material.removeEventListener("downloadComplete",this.downloadComplete);
}
var ObjectLOD=this;
this.materialupdated=function(event){
ObjectLOD.GLShaderProgram=null;
};
//set event listener for new material
material.addEventListener("shaderupdate",this.materialupdated);
this.downloadComplete=function(){
ObjectLOD.fireEvent("downloadComplete");
};
material.addEventListener("downloadComplete",this.downloadComplete);
this.GLShaderProgram=null;
this.material=material;
return this;
}
/**
* gets the material
* @returns {GLGE.Material}
*/
GLGE.ObjectLod.prototype.getMaterial=function(){
return this.material;
}
/**
* gets the pixelsize limit for this lod
* @returns {number}
*/
GLGE.ObjectLod.prototype.getPixelSize=function(){
return this.pixelSize;
}
/**
* sets the pixelsize limit for this lod
* @returns {number}
*/
GLGE.ObjectLod.prototype.setPixelSize=function(value){
this.pixelSize=parseFloat(value);
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_object.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @name GLGE.Object#downloadComplete
* @event fires when all the assets for this class have finished loading
* @param {object} data
*/
/**
* @name GLGE.Object#willRender
* @event fires when all the assets will be rendered
* @param {object} data
*/
/**
* @name GLGE.Object#willRender
* @event fires when all the assets will culled
* @param {object} data
*/
/**
* @class An object that can be rendered in a scene
* @augments GLGE.Animatable
* @augments GLGE.Placeable
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.Object=function(uid){
this.multimaterials=[];
this.renderCaches=[];
var that=this;
this.downloadComplete=function(){
if(that.isComplete()) that.fireEvent("downloadComplete");
}
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.Placeable,GLGE.Object);
GLGE.augment(GLGE.Animatable,GLGE.Object);
GLGE.augment(GLGE.QuickNotation,GLGE.Object);
GLGE.augment(GLGE.JSONLoader,GLGE.Object);
GLGE.Object.prototype.className="Object";
GLGE.Object.prototype.mesh=null;
GLGE.Object.prototype.skeleton=null;
GLGE.Object.prototype.scene=null;
GLGE.Object.prototype.transformMatrix=GLGE.identMatrix();
GLGE.Object.prototype.material=null;
GLGE.Object.prototype.gl=null;
GLGE.Object.prototype.multimaterials=null;
GLGE.Object.prototype.zTrans=false;
GLGE.Object.prototype.renderCaches=null;
GLGE.Object.prototype.id="";
GLGE.Object.prototype.pickable=true;
GLGE.Object.prototype.drawType=GLGE.DRAW_TRIS;
GLGE.Object.prototype.pointSize=1;
GLGE.Object.prototype.lineWidth=1;
GLGE.Object.prototype.cull=true;
GLGE.Object.prototype.culled=true;
GLGE.Object.prototype.visible=true;
GLGE.Object.prototype.depthTest=true;
GLGE.Object.prototype.meshFrame1=0;
GLGE.Object.prototype.meshFrame2=0;
GLGE.Object.prototype.meshBlendFactor=0;
GLGE.Object.prototype.noCastShadows=null;
GLGE.Object.prototype.noDepthMask=false;
GLGE.Object.prototype.shadowAlpha=true;
GLGE.Object.prototype.blending=[ "SRC_ALPHA","ONE_MINUS_SRC_ALPHA"];
//shadow fragment
var shfragStr=[];
shfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
shfragStr.push("uniform float distance;\n");
shfragStr.push("uniform bool shadowtype;\n");
shfragStr.push("varying vec3 eyevec;\n");
shfragStr.push("void main(void)\n ");
shfragStr.push("{\n");
shfragStr.push("float depth = gl_FragCoord.z;\n");
shfragStr.push("if(shadowtype) depth=length(eyevec)/distance;\n");
shfragStr.push("vec4 rgba=fract(depth * vec4(16777216.0, 65536.0, 256.0, 1.0));\n");
shfragStr.push("gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);\n");
shfragStr.push("}\n");
GLGE.Object.prototype.shfragStr=shfragStr.join("");
//normal fragment
var nfragStr=[];
nfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
nfragStr.push("varying vec3 n;\n");
nfragStr.push("void main(void)\n");
nfragStr.push("{\n");
nfragStr.push("float depth = gl_FragCoord.z / gl_FragCoord.w;\n");
nfragStr.push("gl_FragColor=vec4(normalize(n)/2.0+0.5,depth/1000.0);\n");
nfragStr.push("}\n");
GLGE.Object.prototype.nfragStr=nfragStr.join("");
//picking fragment
var pkfragStr=[];
pkfragStr.push("#ifdef GL_ES\nprecision highp float;\n#endif\n");
pkfragStr.push("uniform float far;\n");
pkfragStr.push("uniform vec3 pickcolor;\n");
pkfragStr.push("varying vec3 n;\n");
pkfragStr.push("varying vec4 UVCoord;\n");
pkfragStr.push("void main(void)\n");
pkfragStr.push("{\n");
pkfragStr.push("float Xcoord = gl_FragCoord.x+0.5;\n");
pkfragStr.push("if(Xcoord>0.0) gl_FragColor = vec4(pickcolor,1.0);\n");
pkfragStr.push("if(Xcoord>1.0) gl_FragColor = vec4(n,1.0);\n");
pkfragStr.push("if(Xcoord>2.0){");
pkfragStr.push("vec3 rgb=fract((gl_FragCoord.z/gl_FragCoord.w) * vec3(65536.0, 256.0, 1.0));\n");
pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
pkfragStr.push("}");
//x tex coord
pkfragStr.push("if(Xcoord>3.0){");
pkfragStr.push("vec3 rgb=fract(UVCoord.x * vec3(65536.0, 256.0, 1.0));\n");
pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
pkfragStr.push("}");
//y tex coord
pkfragStr.push("if(Xcoord>4.0){");
pkfragStr.push("vec3 rgb=fract(UVCoord.y * vec3(65536.0, 256.0, 1.0));\n");
pkfragStr.push("gl_FragColor=vec4(rgb-rgb.rrg*vec3(0.0,0.00390625,0.00390625),1.0);\n");
pkfragStr.push("}");
pkfragStr.push("}\n");
GLGE.Object.prototype.pkfragStr=pkfragStr.join("");
GLGE.Object.prototype.noDepthMask
/**
* Sets the depth mask for the object default is true
* @param {boolean} mask flag to depth masking
*/
GLGE.Object.prototype.setDepthMask=function(mask){
this.noDepthMask=!mask;
return this;
}
/**
* Gets the objects depth mask flag
* @returns flag to indicate the depth mask
*/
GLGE.Object.prototype.getDepthMask=function(){
return !this.noDepthMask;
}
/**
* Sets the object visibility
* @param {boolean} visable flag to indicate the objects visibility
*/
GLGE.Object.prototype.setVisible=function(visible){
this.visible=visible;
return this;
}
/**
* Gets the object visibility
* @returns flag to indicate the objects visibility
*/
GLGE.Object.prototype.getVisible=function(){
return this.visible;
}
/**
* Sets the object blending mode
* @param {array} gl blending funcs as strings, eg. [ "ONE", "ONE"]
*/
GLGE.Object.prototype.setBlending=function(blending){
this.blending=blending;
return this;
}
/**
* Gets the object blending mode
* @returns gl blending funcs
*/
GLGE.Object.prototype.getBlending=function(){
return this.blending;
}
/**
* Sets the first mesh frame to use when using an animated mesh
* @param {boolean} frame the inital frame
*/
GLGE.Object.prototype.setMeshFrame1=function(frame){
this.meshFrame1=frame;
return this;
}
/**
* Sets the second mesh frame to use when using an animated mesh
* @param {boolean} frame the final frame
*/
GLGE.Object.prototype.setMeshFrame2=function(frame){
this.meshFrame2=frame;
return this;
}
/**
* blending between frames
* @param {boolean} frame value 0-1 morth between frame1 and frame2
*/
GLGE.Object.prototype.setMeshBlendFactor=function(factor){
this.meshBlendFactor=factor;
return this;
}
/**
* Gets blending between frames
* @returns blender factor
*/
GLGE.Object.prototype.getMeshBlendFactor=function(){
return this.meshBlendFactor;
}
/**
* Gets the pickable flag for the object
*/
GLGE.Object.prototype.getPickable=function(){
return this.pickable;
}
/**
* Sets the pickable flag for the object
* @param {boolean} value the culling flag
*/
GLGE.Object.prototype.setPickable=function(pickable){
this.pickable=pickable;
return this;
}
/**
* Gets the depth test flag for the object
*/
GLGE.Object.prototype.getDepthTest=function(){
return this.depthTest;
}
/**
* Sets the depth test flag for the object
* @param {boolean} value the culling flag
*/
GLGE.Object.prototype.setDepthTest=function(test){
this.depthTest=test;
return this;
}
/**
* Gets the culling flag for the object
*/
GLGE.Object.prototype.getCull=function(){
return this.cull;
}
/**
* Sets the culling flag for the object
* @param {boolean} value the culling flag
*/
GLGE.Object.prototype.setCull=function(cull){
this.cull=cull;
return this;
}
/**
* Gets the objects draw type
*/
GLGE.Object.prototype.getDrawType=function(){
return this.drawType;
}
/**
* Sets the objects draw type
* @param {GLGE.number} value the draw type of this object
*/
GLGE.Object.prototype.setDrawType=function(value){
this.drawType=value;
return this;
}
/**
* Gets the objects draw point size
*/
GLGE.Object.prototype.getPointSize=function(){
return this.pointSize;
}
/**
* Sets the objects draw points size
* @param {GLGE.number} value the point size to render
*/
GLGE.Object.prototype.setPointSize=function(value){
this.pointSize=parseFloat(value);
return this;
}
/**
* Gets the objects line width
*/
GLGE.Object.prototype.getLineWidth=function(){
return this.lineWidth;
}
/**
* Sets the objects line width
* @param {GLGE.number} value the line width
*/
GLGE.Object.prototype.setLineWidth=function(value){
this.lineWidth=parseFloat(value);
return this;
}
/**
* Sets a custom usinform on this object
* @param {string} type the uniform type eg 1i, 3fv, Matrix4fv, etc
* @param {string} name the uniform name
* @param {array} value the value of the uniform
*/
GLGE.Object.prototype.setUniform=function(type,name,value){
if(!this.uniforms) this.uniforms={};
this.uniforms[name]={type:type,value:value};
}
/**
* Gets the value of a custom uniform
* @param {string} name the name of the uniform to return
* @returns {number} the value of the uniform
*/
GLGE.Object.prototype.getUniform=function(name){
if(!this.uniforms) this.uniforms={};
return this.uniforms[name].value
}
/**
* Gets the type of a custom uniform
* @param {string} name the name of the uniform to return
* @returns {number} the type of the uniform
*/
GLGE.Object.prototype.getUniformType=function(name){
if(!this.uniforms) this.uniforms={};
return this.uniforms[name].type;
}
/**
* Sets the code to inject into the vertex shader
* @param {string} shader the glsl code to inject into the vertex shader of this object GLGE will call the function GLGE_Position(vec4 position) to modify the position
*/
GLGE.Object.prototype.setVertexShaderInjection=function(shader){
this.shaderVertexInjection=shader;
this.updateProgram();
return this;
}
/**
* Gets the glsl code injected into the vertex shader of this object
* @returns {string} shader the glsl code injected into the vertex shader of this object
*/
GLGE.Object.prototype.getVertexShaderInjection=function(shader){
return this.shaderVertexInjection;
}
/**
* Gets the objects skeleton
* @returns GLGE.Group
*/
GLGE.Object.prototype.getSkeleton=function(){
return this.skeleton;
}
/**
* Sets the objects skeleton
* @param {GLGE.Group} value the skeleton group to set
*/
GLGE.Object.prototype.setSkeleton=function(value){
this.skeleton=value;
this.bones=null;
return this;
}
GLGE.Object.prototype.getBoundingVolume=function(local){
if(!local) local=0;
if(!this.boundingVolume) this.boundingVolume=[];
if(!this.boundmatrix) this.boundmatrix=[];
var matrix=this.getModelMatrix();
if(matrix!=this.boundmatrix[local] || !this.boundingVolume[local]){
var multimaterials=this.multimaterials;
var boundingVolume;
for(var i=0;i1){
vertexStr.push("attribute vec"+this.mesh.buffers[i].size+" "+this.mesh.buffers[i].name+";\n");
}else{
vertexStr.push("attribute float "+this.mesh.buffers[i].name+";\n");
}
if(this.mesh.buffers[i].name=="UV") UV=true;
if(this.mesh.buffers[i].name=="color") colors=true;
if(this.mesh.buffers[i].name=="joints1") joints1=this.mesh.buffers[i];
if(this.mesh.buffers[i].name=="joints2") joints2=this.mesh.buffers[i];
}
if(this.mesh.framePositions.length>1){
var morph=true;
vertexStr.push("attribute vec3 position2;\n");
vertexStr.push("attribute vec3 normal2;\n");
vertexStr.push("uniform float framesBlend;\n");
if(tangent) vertexStr.push("attribute vec3 tangent2;\n");
}
if(tangent) vertexStr.push("attribute vec3 tangent;\n");
vertexStr.push("uniform mat4 worldView;\n");
vertexStr.push("uniform mat4 projection;\n");
vertexStr.push("uniform mat4 worldInverseTranspose;\n");
vertexStr.push("uniform mat4 envMat;\n");
//vertexStr.push("uniform vec3 cameraPos;\n");
vertexStr.push("uniform float cascadeLevel;\n");
for(var i=0; i0){
vertexStr.push("uniform vec4 jointMat["+(3*this.mesh.joints.length)+"];\n");
}
if(this.material) vertexStr.push(this.material.getVertexVarying(vertexStr));
vertexStr.push("varying vec3 n;\n");
vertexStr.push("varying vec3 t;\n");
if(colors) vertexStr.push("varying vec4 vcolor;\n");
vertexStr.push("varying vec4 UVCoord;\n");
vertexStr.push("varying vec3 OBJCoord;\n");
if(this.shaderVertexInjection){
vertexStr.push(this.shaderVertexInjection);
}
vertexStr.push("void main(void)\n");
vertexStr.push("{\n");
if(colors) vertexStr.push("vcolor=color;\n");
if(UV) vertexStr.push("UVCoord=UV;\n");
else vertexStr.push("UVCoord=vec4(0.0,0.0,0.0,0.0);\n");
vertexStr.push("OBJCoord = position;\n");
vertexStr.push("vec3 tang;\n");
vertexStr.push("vec4 pos = vec4(0.0, 0.0, 0.0, 1.0);\n");
vertexStr.push("vec4 norm = vec4(0.0, 0.0, 0.0, 1.0);\n");
if(tangent) vertexStr.push("vec4 tang4 = vec4(0.0, 0.0, 0.0, 1.0);\n");
if(joints1){
if(joints1.size==1){
vertexStr.push("pos += vec4(dot(jointMat[int(3.0*joints1)],vec4(position,1.0)),\n"+
" dot(jointMat[int(3.0*joints1+1.0)],vec4(position,1.0)),\n"+
" dot(jointMat[int(3.0*joints1+2.0)],vec4(position,1.0)),1.0)*weights1;\n");
vertexStr.push("norm += vec4(dot(jointMat[int(3.0*joints1)].xyz,normal),\n"+
" dot(jointMat[int(3.0*joints1+1.0)].xyz,normal),\n"+
" dot(jointMat[int(3.0*joints1+2.0)].xyz,normal),1.0)*weights1;\n");
if (tangent)
vertexStr.push("tang4 += vec4(dot(jointMat[int(3.0*joints1)].xyz,tangent),\n"+
" dot(jointMat[int(3.0*joints1+1.0)].xyz,tangent),\n"+
" dot(jointMat[int(3.0*joints1+2.0)].xyz,tangent),1.0)*weights1;\n");
}else{
for(var i=0;i-1){
vertexStr.push("pos=GLGE_Position(vec4(pos.xyz, 1.0));\n");
}
vertexStr.push("pos = worldView * vec4(pos.xyz, 1.0);\n");
vertexStr.push("norm = worldInverseTranspose * vec4(norm.xyz, 1.0);\n");
if(tangent) vertexStr.push("tang = (worldInverseTranspose*vec4(tang4.xyz,1.0)).xyz;\n");
}else{
if(morph){
vertexStr.push("vec4 pos4=vec4(mix(position,position2,framesBlend),1.0);\n");
}else{
vertexStr.push("vec4 pos4=vec4(position,1.0);\n");
}
if(this.shaderVertexInjection && this.shaderVertexInjection.indexOf("GLGE_Position")>-1){
vertexStr.push("pos4=GLGE_Position(pos4);\n");
}
//vertexStr.push("pos4.xyz = (pos4.xyz-cameraPos.xyz)/(pow(length(pos4.xyz-cameraPos.xyz),0.5))+cameraPos.xyz;\n");
for(var i=0; i> 16 & 0xFF;
var g = pickindex >> 8 & 0xFF;
var r = pickindex & 0xFF;
GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "pickcolor"), r/255,g/255,b/255);
break;
}
//set the line width
gl.lineWidth(this.lineWidth);
//set custom uinforms
for(var key in this.uniforms){
var uniform=this.uniforms[key];
if(uniform.type=="Matrix4fv"){
GLGE.setUniformMatrix(gl,"Matrix4fv",GLGE.getUniformLocation(gl,program, key),false,uniform.value);
}else{
GLGE.setUniform(gl,uniform.type,GLGE.getUniformLocation(gl,program, key),uniform.value);
}
}
if(!program.caches) program.caches={};
if(!program.glarrays) program.glarrays={};
var pc=program.caches;
var pgl=program.glarrays;
var scene=gl.scene;
var camera=scene.camera;
if(pc.far!=camera.far){
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "far"), camera.far);
pc.far=camera.far;
}
if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_EMIT){
if(pc.ambientColor!=scene.ambientColor){
var ambientColor=scene.ambientColor;
GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "amb"), ambientColor.r,ambientColor.g,ambientColor.b);
pc.ambientColor=ambientColor;
}
if(pc.fogFar!=scene.fogFar){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "fogfar"), scene.fogFar);
pc.fogFar=scene.fogFar;
}
if(pc.fogNear!=scene.fogNear){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "fognear"), scene.fogNear);
pc.fogNear=scene.fogNear;
}
if(pc.fogType!=scene.fogType){
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,program, "fogtype"), scene.fogType);
pc.fogType=scene.fogType;
}
if(pc.fogType!=scene.fogcolor){
GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,program, "fogcolor"), scene.fogColor.r,scene.fogColor.g,scene.fogColor.b);
pc.fogcolor=scene.fogcolor;
}
}
if(pc.meshBlendFactor!=this.meshBlendFactor){
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,program, "framesBlend"), this.meshBlendFactor);
pc.meshBlendFactor=this.meshBlendFactor;
}
var cameraMatrix=camera.getViewMatrix();
var objMatrix=modelMatrix=this.getModelMatrix();
if(!pc.mvMatrix) pc.mvMatrix={cameraMatrix:null,modelMatrix:null};
var mvCache=pc.mvMatrix;
if(mvCache.cameraMatrix!=cameraMatrix || mvCache.modelMatrix!=modelMatrix){
//generate and set the modelView matrix
if(!this.caches.mvMatrix) this.caches.mvMatrix=GLGE.mulMat4(cameraMatrix,modelMatrix);
mvMatrix=this.caches.mvMatrix;
if(this.mesh.joints){
mvMatrix=cameraMatrix;
}
var mvUniform = GLGE.getUniformLocation(gl,program, "worldView");
var M1=GLGE.transposeMat4(mvMatrix);
if(!pgl.mvMatrix){
pgl.mvMatrixT=new Float32Array(M1);
}else{
GLGE.mat4gl(M1,pgl.mvMatrixT);
}
//GLGE.reuseMatrix4(M1);
pgl.mvMatrix=mvMatrix;
GLGE.setUniformMatrix(gl,"Matrix4fv",mvUniform, false, program.glarrays.mvMatrixT);
//invCamera matrix
var icUniform = GLGE.getUniformLocation(gl,program, "envMat");
if(icUniform){
if(!this.caches.envMat){
var envMat = GLGE.inverseMat4(cameraMatrix);
envMat[3]=0;
envMat[7]=0;
envMat[11]=0;
this.caches.envMat = envMat;
}
envMat=this.caches.envMat;
M1=GLGE.transposeMat4(envMat);
if(!program.glarrays.envMat){
pgl.envMatT=new Float32Array(M1);
}else{
GLGE.mat4gl(M1,pgl.envMatT);
}
pgl.envMat=envMat;
GLGE.setUniformMatrix(gl,"Matrix4fv",icUniform, false, pgl.envMatT);
}
//normalising matrix
if(!this.caches.normalMatrix){
var normalMatrix = GLGE.inverseMat4(mvMatrix);
this.caches.normalMatrix = normalMatrix;
}
normalMatrix=this.caches.normalMatrix;
var nUniform = GLGE.getUniformLocation(gl,program, "worldInverseTranspose");
if(!pgl.normalMatrix) pgl.normalMatrix=new Float32Array(normalMatrix);
else GLGE.mat4gl(normalMatrix,pgl.normalMatrix);
GLGE.setUniformMatrix(gl,"Matrix4fv",nUniform, false, pgl.normalMatrix);
var cUniform = GLGE.getUniformLocation(gl,program, "view");
M1=GLGE.transposeMat4(cameraMatrix);
if(!pgl.cameraMatrix){
pgl.cameraMatrixT=new Float32Array(M1);
}else{
GLGE.mat4gl(M1,pgl.cameraMatrixT);
}
//GLGE.reuseMatrix4(M1);
pgl.cameraMatrix=cameraMatrix;
GLGE.setUniformMatrix(gl,"Matrix4fv",cUniform, false, pgl.cameraMatrixT);
mvCache.cameraMatrix=cameraMatrix;
mvCache.modelMatrix=modelMatrix;
}
var pUniform = GLGE.getUniformLocation(gl,program, "projection");
M1=GLGE.transposeMat4(camera.getProjectionMatrix());
if(!pgl.pMatrix){
pgl.pMatrixT=new Float32Array(M1);
}else{
GLGE.mat4gl(M1,pgl.pMatrixT);
}
//GLGE.reuseMatrix4(M1);
pgl.pMatrix=camera.getProjectionMatrix();
GLGE.setUniformMatrix(gl,"Matrix4fv",pUniform, false, pgl.pMatrixT);
//light
//dont' need lighting for picking
if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_SHADOW || renderType==GLGE.RENDER_DEPTH || renderType==GLGE.RENDER_EMIT){
var pos,lpos;
var lights=gl.lights
if(!pc.lights) pc.lights=[];
if(!pgl.lights) pgl.lights=[];
if(!this.caches.lights) this.caches.lights=[];
var lightCache=pc.lights;
for(var i=0; i1 && !pixelsize){
var camerapos=gl.scene.camera.getPosition();
var modelpos=this.getPosition();
var dist=GLGE.lengthVec3([camerapos.x-modelpos.x,camerapos.y-modelpos.y,camerapos.z-modelpos.z]);
dist=GLGE.mulMat4Vec4(gl.scene.camera.getProjectionMatrix(),[this.getBoundingVolume().getSphereRadius(),0,-dist,1]);
pixelsize=dist[0]/dist[3]*gl.scene.renderer.canvas.width;
}
var lod=this.multimaterials[i].getLOD(pixelsize);
if(lod.mesh && lod.mesh.loaded){
if(renderType==GLGE.RENDER_NULL){
if(lod.material) lod.material.registerPasses(gl,this);
break;
}
if(!lod.GLShaderProgram){
this.createShaders(lod);
}else{
this.GLShaderProgramPick=lod.GLShaderProgramPick;
this.GLShaderProgramShadow=lod.GLShaderProgramShadow;
this.GLShaderProgram=lod.GLShaderProgram;
}
this.mesh=lod.mesh;
this.material=lod.material;
var drawType;
switch(this.drawType){
case GLGE.DRAW_LINES:
drawType=gl.LINES;
break;
case GLGE.DRAW_POINTS:
drawType=gl.POINTS;
break;
case GLGE.DRAW_LINELOOPS:
drawType=gl.LINE_LOOP;
break;
case GLGE.DRAW_LINESTRIPS:
drawType=gl.LINE_STRIP;
break;
case GLGE.DRAW_TRIANGLESTRIP:
drawType=gl.TRIANGLE_STRIP;
break;
default:
drawType=gl.TRIANGLES;
break;
}
switch(renderType){
case GLGE.RENDER_DEFAULT:
case GLGE.RENDER_EMIT:
if(gl.program!=this.GLShaderProgram){
gl.useProgram(this.GLShaderProgram);
gl.program=this.GLShaderProgram;
}
this.mesh.GLAttributes(gl,this.GLShaderProgram,this.meshFrame1,this.meshFrame2);
break;
case GLGE.RENDER_SHADOW:
case GLGE.RENDER_DEPTH:
if(gl.program!=this.GLShaderProgramShadow){
gl.useProgram(this.GLShaderProgramShadow,this.meshFrame1,this.meshFrame2);
gl.program=this.GLShaderProgramShadow;
}
if(!distance) distance=gl.scene.camera.getFar();
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,this.GLShaderProgramShadow, "distance"), distance);
this.mesh.GLAttributes(gl,this.GLShaderProgramShadow,this.meshFrame1,this.meshFrame2);
break;
case GLGE.RENDER_NORMAL:
if(gl.program!=this.GLShaderProgramNormal){
gl.useProgram(this.GLShaderProgramNormal);
gl.program=this.GLShaderProgramNormal;
}
this.mesh.GLAttributes(gl,this.GLShaderProgramNormal,this.meshFrame1,this.meshFrame2);
break;
case GLGE.RENDER_PICK:
if(gl.program!=this.GLShaderProgramPick){
gl.useProgram(this.GLShaderProgramPick);
gl.program=this.GLShaderProgramPick;
}
this.mesh.GLAttributes(gl,this.GLShaderProgramPick,this.meshFrame1,this.meshFrame2);
drawType=gl.TRIANGLES;
break;
}
//render the object
this.GLUniforms(gl,renderType,pickindex);
switch (this.mesh.windingOrder) {
case GLGE.Mesh.WINDING_ORDER_UNKNOWN:
if (gl.scene.renderer.cullFaces){
gl.cullFace(gl.scene.mirror ? gl.FRONT : gl.BACK);
gl.enable(gl.CULL_FACE);
}else{
gl.disable(gl.CULL_FACE);
}
break;
case GLGE.Mesh.WINDING_ORDER_CLOCKWISE:
gl.cullFace(gl.scene.mirror ? gl.FRONT : gl.BACK);
gl.enable(gl.CULL_FACE);
break;
case GLGE.Mesh.WINDING_ORDER_COUNTER:
gl.cullFace(gl.scene.mirror ? gl.BACK : gl.FRONT);
gl.enable(gl.CULL_FACE);
default:
break;
}
if(renderType==GLGE.RENDER_PICK) gl.disable(gl.CULL_FACE);
if(this.noDepthMask) gl.depthMask(false);
if(this.mesh.GLfaces){
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.mesh.GLfaces);
gl.drawElements(drawType, this.mesh.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
}else{
gl.drawArrays(drawType, 0, this.mesh.positions.length/3);
}
gl.depthMask(true);
switch (this.mesh.windingOrder) {
case GLGE.Mesh.WINDING_ORDER_UNKNOWN:
if (gl.scene.renderer.cullFaces)
gl.enable(gl.CULL_FACE);
break;
case GLGE.Mesh.WINDING_ORDER_COUNTER:
gl.cullFace(gl.BACK);
default:
break;
}
var matrix=this.matrix;
var caches=this.caches;
this.matrix=matrix;
this.caches=caches;
}
}
}
})(GLGE);
/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_text.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Text that can be rendered in a scene
* @augments GLGE.Animatable
* @augments GLGE.Placeable
* @augments GLGE.QuickNotation
* @augments GLGE.JSONLoader
*/
GLGE.Text=function(uid){
this.canvas=document.createElement("canvas");
this.scaleCanvas=document.createElement("canvas");
this.color={r:1.0,g:1.0,b:1.0};
GLGE.Assets.registerAsset(this,uid);
}
GLGE.augment(GLGE.Placeable,GLGE.Text);
GLGE.augment(GLGE.Animatable,GLGE.Text);
GLGE.augment(GLGE.QuickNotation,GLGE.Text);
GLGE.augment(GLGE.JSONLoader,GLGE.Text);
GLGE.Text.prototype.className="Text";
GLGE.Text.prototype.zTrans=true;
GLGE.Text.prototype.canvas=null;
GLGE.Text.prototype.aspect=1.0;
GLGE.Text.prototype.color=null;
GLGE.Text.prototype.text="";
GLGE.Text.prototype.font="Times";
GLGE.Text.prototype.size=100;
GLGE.Text.prototype.pickType=GLGE.TEXT_TEXTPICK;
GLGE.Text.prototype.pickable=true;
GLGE.Text.prototype.alpha=1;
GLGE.Text.prototype.dirty=true;
/**
* Gets the pick type for this text
* @returns {string} the pick type
*/
GLGE.Text.prototype.getPickType=function(){
return this.pickType;
};
/**
* Sets the pick type GLGE.TEXT_BOXPICK for picking based on bound box or GLGE.TEXT_TEXTPICK for pixel perfect text picking
* @param {Number} value the picking type
*/
GLGE.Text.prototype.setPickType=function(value){
this.pickType=value;
return this;
};
/**
* Gets the font of the text
* @returns {string} the font of the text
*/
GLGE.Text.prototype.getFont=function(){
return this.size;
};
/**
* Sets the font of the text
* @param {Number} value the font of the text
*/
GLGE.Text.prototype.setFont=function(value){
this.font=value;
this.dirty=true;
return this;
};
/**
* Gets the size of the text
* @returns {string} the size of the text
*/
GLGE.Text.prototype.getSize=function(){
return this.size;
};
/**
* Sets the size of the text
* @param {Number} value the size of the text
*/
GLGE.Text.prototype.setSize=function(value){
this.size=value;
this.dirty=true;
return this;
};
/**
* Gets the rendered text
* @returns {string} the text rendered
*/
GLGE.Text.prototype.getText=function(){
return this.text;
};
/**
* Sets the text to be rendered
* @param {Number} value the text to render
*/
GLGE.Text.prototype.setText=function(value){
this.text=value;
this.dirty=true;
return this;
};
/**
* Sets the base colour of the text
* @param {string} color The colour of the material
*/
GLGE.Text.prototype.setColor=function(color){
color=GLGE.colorParse(color);
this.color={r:color.r,g:color.g,b:color.b};
return this;
};
/**
* Sets the red base colour of the text
* @param {Number} r The new red level 0-1
*/
GLGE.Text.prototype.setColorR=function(value){
this.color.r=value;
return this;
};
/**
* Sets the green base colour of the text
* @param {Number} g The new green level 0-1
*/
GLGE.Text.prototype.setColorG=function(value){
this.color.g=value;
return this;
};
/**
* Sets the blue base colour of the text
* @param {Number} b The new blue level 0-1
*/
GLGE.Text.prototype.setColorB=function(value){
this.color.b=value;
return this;
};
/**
* Gets the current base color of the text
* @return {[r,g,b]} The current base color
*/
GLGE.Text.prototype.getColor=function(){
return this.color;
return this;
};
/**
* Sets the alpha
* @param {Number} b The new alpha level 0-1
*/
GLGE.Text.prototype.setAlpha=function(value){
this.alpha=value;
return this;
};
/**
* Gets the alpha
* @returns The alpha level
*/
GLGE.Text.prototype.getAlpha=function(){
return this.alpha;
};
/**
* Sets the Z Transparency of this text
* @param {boolean} value Does this object need blending?
*/
GLGE.Text.prototype.setZtransparent=function(value){
this.zTrans=value;
return this;
}
/**
* Gets the z transparency
* @returns boolean
*/
GLGE.Text.prototype.isZtransparent=function(){
return this.zTrans;
}
/**
* Creates the shader program for the object
* @private
*/
GLGE.Text.prototype.GLGenerateShader=function(gl){
if(this.GLShaderProgram) gl.deleteProgram(this.GLShaderProgram);
//Vertex Shader
var vertexStr="";
vertexStr+="attribute vec3 position;\n";
vertexStr+="attribute vec2 uvcoord;\n";
vertexStr+="varying vec2 texcoord;\n";
vertexStr+="uniform mat4 Matrix;\n";
vertexStr+="uniform mat4 PMatrix;\n";
vertexStr+="varying vec4 pos;\n";
vertexStr+="void main(void){\n";
vertexStr+="texcoord=uvcoord;\n";
vertexStr+="pos = Matrix * vec4(position,1.0);\n";
vertexStr+="gl_Position = PMatrix * pos;\n";
vertexStr+="}\n";
//Fragment Shader
var fragStr="#ifdef GL_ES\nprecision highp float;\n#endif\n";
fragStr=fragStr+"uniform sampler2D TEXTURE;\n";
fragStr=fragStr+"varying vec2 texcoord;\n";
fragStr=fragStr+"uniform mat4 Matrix;\n";
fragStr=fragStr+"varying vec4 pos;\n";
fragStr=fragStr+"uniform float far;\n";
fragStr=fragStr+"uniform bool depthrender;\n";
fragStr=fragStr+"uniform float distance;\n";
fragStr=fragStr+"uniform int picktype;\n";
fragStr=fragStr+"uniform vec3 pickcolor;\n";
fragStr=fragStr+"uniform vec3 color;\n";
fragStr=fragStr+"uniform float alpha;\n";
fragStr=fragStr+"void main(void){\n";
fragStr=fragStr+"float ob=pow(min(1.0,abs(dot(normalize(Matrix[2].rgb),vec3(0.0,0.0,1.0)))*2.0),1.5);\n";
fragStr=fragStr+"float a=texture2D(TEXTURE,texcoord).a*alpha*ob;\n";
fragStr=fragStr+"if(picktype=="+GLGE.TEXT_BOXPICK+"){gl_FragColor = vec4(pickcolor,1.0);}"
fragStr=fragStr+"else if(picktype=="+GLGE.TEXT_TEXTPICK+"){if(alpha<1.0) discard; gl_FragColor = vec4(pickcolor,alpha);}"
fragStr=fragStr+"else{gl_FragColor = vec4(color.rgb,a);};\n";
fragStr=fragStr+"if (depthrender) { if(a<0.5) discard; float depth = gl_FragCoord.z / gl_FragCoord.w;\n";
fragStr=fragStr+"vec4 rgba=fract(depth/distance * vec4(16777216.0, 65536.0, 256.0, 1.0));\n";
fragStr=fragStr+"gl_FragColor=rgba-rgba.rrgb*vec4(0.0,0.00390625,0.00390625,0.00390625);}\n";
fragStr=fragStr+"}\n";
this.GLFragmentShader=gl.createShader(gl.FRAGMENT_SHADER);
this.GLVertexShader=gl.createShader(gl.VERTEX_SHADER);
gl.shaderSource(this.GLFragmentShader, fragStr);
gl.compileShader(this.GLFragmentShader);
if (!gl.getShaderParameter(this.GLFragmentShader, gl.COMPILE_STATUS)) {
GLGE.error(gl.getShaderInfoLog(this.GLFragmentShader));
return;
}
//set and compile the vertex shader
//need to set str
gl.shaderSource(this.GLVertexShader, vertexStr);
gl.compileShader(this.GLVertexShader);
if (!gl.getShaderParameter(this.GLVertexShader, gl.COMPILE_STATUS)) {
GLGE.error(gl.getShaderInfoLog(this.GLVertexShader));
return;
}
this.GLShaderProgram = gl.createProgram();
gl.attachShader(this.GLShaderProgram, this.GLVertexShader);
gl.attachShader(this.GLShaderProgram, this.GLFragmentShader);
gl.linkProgram(this.GLShaderProgram);
}
/**
* Initiallize all the GL stuff needed to render to screen
* @private
*/
GLGE.Text.prototype.GLInit=function(gl){
this.gl=gl;
this.createPlane(gl);
this.GLGenerateShader(gl);
this.glTexture=gl.createTexture();
this.dirty=true;
}
/**
* Updates the canvas texture
* @private
*/
GLGE.Text.prototype.updateCanvas=function(gl){
var canvas = this.canvas;
canvas.width=1;
canvas.height=this.size*1.2;
var ctx = canvas.getContext("2d");
ctx.font = this.size+"px "+this.font;
canvas.width=ctx.measureText(this.text).width;
canvas.height=this.size*1.2;
ctx = canvas.getContext("2d");
ctx.textBaseline="top";
ctx.font = (this.extra||"") + " " + this.size+"px "+this.font;
this.aspect=canvas.width/canvas.height;
ctx.fillText(this.text, 0, 0);
var height=Math.pow(2,Math.ceil(Math.log(canvas.height))/(Math.log(2)));
var width=Math.pow(2,Math.ceil(Math.log(canvas.width))/(Math.log(2)));
this.scaleCanvas.height=height;
this.scaleCanvas.width=width;
this.scaleContext=this.scaleCanvas.getContext("2d");
this.scaleContext.clearRect(0,0,width,height);
this.scaleContext.drawImage(canvas, 0, 0, width, height);
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
//TODO: fix this when minefield is upto spec
try{gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas);}
catch(e){gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, this.scaleCanvas,null);}
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR_MIPMAP_LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.generateMipmap(gl.TEXTURE_2D);
gl.bindTexture(gl.TEXTURE_2D, null);
this.dirty=false;
}
/**
* Renders the text to the render buffer
* @private
*/
GLGE.Text.prototype.GLRender=function(gl,renderType,pickindex){
if(!this.gl){
this.GLInit(gl);
}
if(this.dirty) this.updateCanvas(gl);
if(renderType==GLGE.RENDER_DEFAULT || renderType==GLGE.RENDER_PICK || renderType==GLGE.RENDER_SHADOW){
//if look at is set then look
if(this.lookAt) this.Lookat(this.lookAt);
if(gl.program!=this.GLShaderProgram){
gl.useProgram(this.GLShaderProgram);
gl.program=this.GLShaderProgram;
}
var attribslot;
//disable all the attribute initially arrays - do I really need this?
for(var i=0; i<8; i++) gl.disableVertexAttribArray(i);
attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "position");
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
gl.enableVertexAttribArray(attribslot);
gl.vertexAttribPointer(attribslot, this.posBuffer.itemSize, gl.FLOAT, false, 0, 0);
attribslot=GLGE.getAttribLocation(gl,this.GLShaderProgram, "uvcoord");
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
gl.enableVertexAttribArray(attribslot);
gl.vertexAttribPointer(attribslot, this.uvBuffer.itemSize, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl["TEXTURE0"]);
gl.bindTexture(gl.TEXTURE_2D, this.glTexture);
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "TEXTURE"),0);
if(!pickindex) pickindex=0;
var b = pickindex >> 16 & 0xFF;
var g = pickindex >> 8 & 0xFF;
var r = pickindex & 0xFF;
GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "pickcolor"),r/255,g/255,b/255);
if(renderType==GLGE.RENDER_PICK){
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), this.pickType);
}else{
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "picktype"), 0);
}
var distance=gl.scene.camera.getFar();
GLGE.setUniform(gl,"1f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "distance"), distance);
if(renderType==GLGE.RENDER_SHADOW){
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 1);
}else{
GLGE.setUniform(gl,"1i",GLGE.getUniformLocation(gl,this.GLShaderProgram, "depthrender"), 0);
}
if(!this.GLShaderProgram.glarrays) this.GLShaderProgram.glarrays={};
//generate and set the modelView matrix
var scalefactor=this.size/100;
var mMatrix=GLGE.mulMat4(gl.scene.camera.getViewMatrix(),GLGE.mulMat4(this.getModelMatrix(),GLGE.scaleMatrix(this.aspect*scalefactor,scalefactor,scalefactor)));
var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "Matrix");
if(!this.GLShaderProgram.glarrays.mMatrix) this.GLShaderProgram.glarrays.mMatrix=new Float32Array(mMatrix);
else GLGE.mat4gl(mMatrix,this.GLShaderProgram.glarrays.mMatrix);
GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.mMatrix);
var mUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "PMatrix");
if(!this.GLShaderProgram.glarrays.pMatrix) this.GLShaderProgram.glarrays.pMatrix=new Float32Array(gl.scene.camera.getProjectionMatrix());
else GLGE.mat4gl(gl.scene.camera.getProjectionMatrix(),this.GLShaderProgram.glarrays.pMatrix);
GLGE.setUniformMatrix(gl,"Matrix4fv",mUniform, true, this.GLShaderProgram.glarrays.pMatrix);
var farUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "far");
GLGE.setUniform(gl,"1f",farUniform, gl.scene.camera.getFar());
var alphaUniform = GLGE.getUniformLocation(gl,this.GLShaderProgram, "alpha");
GLGE.setUniform(gl,"1f",alphaUniform, this.alpha);
//set the color
GLGE.setUniform3(gl,"3f",GLGE.getUniformLocation(gl,this.GLShaderProgram, "color"), this.color.r,this.color.g,this.color.b);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
gl.drawElements(gl.TRIANGLES, this.GLfaces.numItems, gl.UNSIGNED_SHORT, 0);
gl.scene.lastMaterial=null;
}
}
/**
* creates the plane mesh to draw
* @private
*/
GLGE.Text.prototype.createPlane=function(gl){
//create the vertex positions
if(!this.posBuffer) this.posBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.posBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([1,1,0,-1,1,0,-1,-1,0,1,-1,0]), gl.STATIC_DRAW);
this.posBuffer.itemSize = 3;
this.posBuffer.numItems = 4;
//create the vertex uv coords
if(!this.uvBuffer) this.uvBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([0,0,1,0,1,1,0,1]), gl.STATIC_DRAW);
this.uvBuffer.itemSize = 2;
this.uvBuffer.numItems = 4;
//create the faces
if(!this.GLfaces) this.GLfaces = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.GLfaces);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array([2,1,0,0,3,2]), gl.STATIC_DRAW);
this.GLfaces.itemSize = 1;
this.GLfaces.numItems = 6;
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_renderer.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Sets the scene to render
* @param {object} canvas The canvas element to render to
* @augments GLGE.QuickNotation
*/
GLGE.Renderer=function(canvas,error,props){
this.viewport=[];
this.canvas=canvas;
if(!props) props={alpha:true,depth:true,stencil:true,antialias:true,premultipliedAlpha:true};
try {
this.gl = canvas.getContext("experimental-webgl",props);
} catch(e) {}
try {
if(!this.gl) this.gl = canvas.getContext("webgl",props);
} catch(e) {}
if(!this.gl) {
console.log("GLGE err:", typeof(globalNoWebGLError)=="undefined")
if( (!error) && (typeof(globalNoWebGLError)=="undefined")){
var div=document.createElement("div");
div.setAttribute("style","position: absolute; top: 10px; left: 10px; font-family: sans-serif; font-size: 14px; padding: 10px;background-color: #fcffcb;color: #800; width: 200px; border:2px solid #f00");
div.innerHTML="WebGL compatible Browser Required(Firefox 4 or Chrome 9 and up) or you may need to update your graphics card driver.";
document.getElementsByTagName("body")[0].appendChild(div);
throw "cannot create webgl context";
}else{
error();
throw "cannot create webgl context";
}
}
//firefox is doing something here?
try{
this.gl.canvas=canvas;
}catch(e){};
//this.gl = WebGLDebugUtils.makeDebugContext(this.gl);
//this.gl.setTracing(true);
//chome compatibility
//TODO: Remove this when chome is right
if (!this.gl.getProgramParameter)
{
this.gl.getProgramParameter = this.gl.getProgrami
}
if (!this.gl.getShaderParameter)
{
this.gl.getShaderParameter = this.gl.getShaderi
}
// End of Chrome compatibility code
this.gl.uniformMatrix4fvX=this.gl.uniformMatrix4fv
this.gl.uniformMatrix4fv=function(uniform,transpose,array){
if(!transpose){
this.uniformMatrix4fvX(uniform,false,array);
}else{
GLGE.mat4gl(GLGE.transposeMat4(array),array);
this.uniformMatrix4fvX(uniform,false,array);
}
}
var gl=this.gl;
gl.af = gl.getExtension("MOZ_EXT_texture_filter_anisotropic") || gl.getExtension("WEBKIT_EXT_texture_filter_anisotropic") || gl.getExtension("EXT_texture_filter_anisotropic");;
//set up defaults
this.gl.clearDepth(1.0);
this.gl.clearStencil(0);
this.gl.enable(this.gl.DEPTH_TEST);
this.gl.depthFunc(this.gl.LEQUAL);
this.gl.blendFuncSeparate(this.gl.SRC_ALPHA,this.gl.ONE_MINUS_SRC_ALPHA,this.gl.ZERO,this.gl.ONE);
};
GLGE.augment(GLGE.QuickNotation,GLGE.Renderer);
GLGE.Renderer.prototype.gl=null;
GLGE.Renderer.prototype.scene=null;
GLGE.C_STENCIL=1;
GLGE.C_DEPTH=2;
GLGE.C_COLOR=4;
GLGE.C_ALL=7;
GLGE.Renderer.prototype.clearType=GLGE.C_ALL;
/**
* Sets the width of the viewport to render
* @param width the width of the viewport to render
*/
GLGE.Renderer.prototype.setViewportWidth=function(width){
this.viewport[0]=width;
return this;
};
/**
* Sets the height of the viewport to render
* @param height the height of the viewport to render
*/
GLGE.Renderer.prototype.setViewportHeight=function(height){
this.viewport[1]=height;
return this;
};
/**
* Sets the left offset of the viewport to render
* @param left the left offset of the viewport to render
*/
GLGE.Renderer.prototype.setViewportOffsetX=function(left){
this.viewport[2]=left;
return this;
};
/**
* Sets the top offset of the viewport to render
* @param top the top offset of the viewport to render
*/
GLGE.Renderer.prototype.setViewportOffsetY=function(top){
this.viewport[3]=top;
return this;
};
/**
* Clears all viewport data and defaults back to canvas size
*/
GLGE.Renderer.prototype.clearViewport=function(){
this.viewport=[];
};
/**
* Gets the width of the viewport to render
* @returns the viewport width
*/
GLGE.Renderer.prototype.getViewportWidth=function(){
if(this.viewport.length>0){
return this.viewport[0];
}else{
return this.canvas.width;
}
};
/**
* Gets the height of the viewport to render
* @returns the viewport height
*/
GLGE.Renderer.prototype.getViewportHeight=function(){
if(this.viewport.length>0){
return this.viewport[1];
}else{
return this.canvas.height;
}
};
/**
* Gets the left offset of the viewport to render
* @returns the left viewport offset
*/
GLGE.Renderer.prototype.getViewportOffsetX=function(){
if(this.viewport.length>0){
return this.viewport[2];
}else{
return 0;
}
};
/**
* Gets the top offset of the viewport to render
* @returns the top viewport offset
*/
GLGE.Renderer.prototype.getViewportOffsetY=function(){
if(this.viewport.length>0){
return this.viewport[3];
}else{
return 0;
}
};
/**
* Sets the clear type for rendering GLGE.C_ALL, GLGE.C_STENCIL, GLGE.C_DEPTH, GLGE.C_COLOR
* @param type how to clear the viewport for the next render
*/
GLGE.Renderer.prototype.setClearType=function(type){
this.clearType=type;
return this;
};
/**
* Gets the clear type for rendering GLGE.C_ALL, GLGE.C_STENCIL, GLGE.C_DEPTH, GLGE.C_COLOR
* @returns how to clear the viewport for the next render
*/
GLGE.Renderer.prototype.getClearType=function(){
return this.clearType;
};
/**
* Clears the viewport
* @private
*/
GLGE.Renderer.prototype.GLClear=function(){
var gl=this.gl;
var clearType=this.clearType;
var clear=0;
if((clearType & GLGE.C_COLOR) == GLGE.C_COLOR){
clear=clear | gl.COLOR_BUFFER_BIT;
}
if((clearType & GLGE.C_DEPTH) == GLGE.C_DEPTH){
clear=clear | gl.DEPTH_BUFFER_BIT;
}
if((clearType & GLGE.C_STENCIL) == GLGE.C_STENCIL){
clear=clear | gl.STENCIL_BUFFER_BIT;
}
gl.clear(clear);
};
/**
* Gets the scene which is set to be rendered
* @returns the current render scene
*/
GLGE.Renderer.prototype.getScene=function(){
return this.scene;
};
/**
* Sets the scene to render
* @param {GLGE.Scene} scene The scene to be rendered
*/
GLGE.Renderer.prototype.setScene=function(scene){
scene.renderer=this;
this.scene=scene;
if(!scene.gl) scene.GLInit(this.gl);
//this.render();
scene.camera.updateMatrix(); //reset camera matrix to force cache update
return this;
};
/**
* Renders the current scene to the canvas
*/
GLGE.Renderer.prototype.render=function(){
if(this.transitonFilter){
var now=+new Date;
if(now max[i]) {
max[i] = v[i];
}
}
}
/**
* creates a look at matrix for directional lights
* @private
*/
GLGE.Light.prototype.lightLook=function(pos, dir, up) {
var lftN=GLGE.toUnitVec3(GLGE.crossVec3(dir,up));
var upN=GLGE.toUnitVec3(GLGE.crossVec3(lftN,dir));
var dirN=GLGE.toUnitVec3(dir);
var m=[];
m[0] = lftN[0]; m[4] = upN[0]; m[8] = -dirN[0]; m[12] = 0.0;
m[1] = lftN[1]; m[5] = upN[1]; m[9] = -dirN[1]; m[13] = 0.0;
m[2] = lftN[2]; m[6] = upN[2]; m[10] = -dirN[2]; m[14] = 0.0;
m[3] = -GLGE.dotVec3(lftN,pos);
m[7] = -GLGE.dotVec3(upN,pos);
m[11] = GLGE.dotVec3(dirN,pos);
m[15] = 1.0;
return m;
}
/**
* transforms points by matrix mat
* @private
*/
GLGE.Light.prototype.transformPoints=function(points,mat){
var transformed=[];
for(var i=0;i0 && d2>0) || (d1<0 && d2<0)){
return false;
}else{
var D=GLGE.subVec3(edge[1],edge[0]);
D=GLGE.scaleVec3(D,-d1/(d2-d1));
return GLGE.addVec3(edge[0],D);
}
};
/**
* is point contained within planes
* @private
*/
GLGE.Light.prototype.pointInPlanes=function(point,planes){
var tiny=-0.001;
for(var i=0;ibidx){
return 1;
}else if(aidxbidx){
return 1;
}else if(aidxbidx){
return 1;
}else if(aidx0){
var pass=this.passes.pop();
gl.bindFramebuffer(gl.FRAMEBUFFER, pass.frameBuffer);
this.camera.matrix=pass.cameraMatrix;
this.camera.setProjectionMatrix(pass.projectionMatrix);
this.mirror=pass.mirror;
this.renderPass(gl,renderObjects,0,0,pass.width,pass.height,GLGE.RENDER_DEFAULT,pass.self);
}
this.mirror=false;
this.camera.matrix=cameraMatrix;
this.camera.setProjectionMatrix(cameraPMatrix);
gl.bindFramebuffer(gl.FRAMEBUFFER, this.filter ? this.framebuffer : this.transbuffer);
this.renderPass(gl,renderObjects,this.renderer.getViewportOffsetX(),this.renderer.getViewportOffsetY(),this.renderer.getViewportWidth(),this.renderer.getViewportHeight());
this.applyFilter(gl,renderObjects, this.transbuffer);
this.allowPasses=true;
}
/**
* gets the passes needed to render this scene
* @private
*/
GLGE.Scene.prototype.getPasses=function(gl,renderObjects){
for(var i=0; isizeTimeLife[2] && (time-sizeTimeLife[2])-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initPosGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "initAcc");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initAccGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "endAcc");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.endAccGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "initColor");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initColorGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "endColor");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.endColorGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "sizeTimeLife");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.sizeAndOffsetGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 4, gl.FLOAT, false, 0, 0);
}
var attrib=GLGE.getAttribLocation(gl,this.program, "initVel");
if(attrib>-1){
gl.bindBuffer(gl.ARRAY_BUFFER, this.attribute.initVelGL);
gl.enableVertexAttribArray(attrib);
gl.vertexAttribPointer(attrib, 3, gl.FLOAT, false, 0, 0);
}
}
/**
* Renders the particle system
* @private
*/
GLGE.ParticleSystem.prototype.GLRender=function(gl){
if(!this.attribute) this.generateParticles(gl);
if(!this.program) this.generateProgram(gl);
gl.program=this.program;
gl.useProgram(this.program);
this.setAttributes(gl);
this.setUniforms(gl);
gl.depthMask(false);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.facesGL);
gl.drawElements(gl.TRIANGLES,this.facesGL.num, gl.UNSIGNED_SHORT, 0);
gl.depthMask(true);
gl.scene.lastMaterial=null;
}
/**
* @function Adds a particle system to the scene
* @param {GLGE.ParticleSystem} the particle system to add
*/
GLGE.Scene.prototype.addParticleSystem=GLGE.Scene.prototype.addGroup;
/**
* @function Adds a particle system to the group
* @param {GLGE.ParticleSystem} the particle system to add
*/
GLGE.Group.prototype.addParticleSystem=GLGE.Group.prototype.addGroup;
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_md2.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @name GLGE.MD2#md2AnimFinished
* @event fired when the the animation has finished
* @param {object} data
*/
/**
* @class A quake MD2 model class
* @augments GLGE.Object
*/
GLGE.MD2=function(uid){
this.MD2Started=+new Date;
this.setAnimation(new GLGE.AnimationVector);
GLGE.Object.call(this,uid);
}
GLGE.augment(GLGE.Object,GLGE.MD2);
GLGE.MD2.prototype.loadingCache={};
GLGE.MD2.prototype.headersCache={};
GLGE.MD2.prototype.meshCache={};
GLGE.MD2.prototype.MD2Animations={};
GLGE.MD2.prototype.MD2StartFrame=0;
GLGE.MD2.prototype.MD2EndFrame=0;
GLGE.MD2.prototype.MD2Loop=true;
GLGE.MD2.prototype.MD2AnimFinished=false;
GLGE.MD2.prototype.headerNames=[
"ident",
"version",
"skinwidth",
"skinheight",
"framesize",
"num_skins",
"num_xyz",
"num_st",
"num_tris",
"num_glcmds",
"num_frames",
"ofs_skins",
"ofs_st",
"ofs_tris",
"ofs_frames",
"ofs_glcmds",
"ofs_end"];
GLGE.MD2.prototype.preNormals = [
[-0.525731, 0.000000, 0.850651], [-0.442863, 0.238856, 0.864188], [-0.295242, 0.000000, 0.955423],
[-0.309017, 0.500000, 0.809017], [-0.162460, 0.262866, 0.951056], [ 0.000000, 0.000000, 1.000000],
[ 0.000000, 0.850651, 0.525731], [-0.147621, 0.716567, 0.681718], [ 0.147621, 0.716567, 0.681718],
[ 0.000000, 0.525731, 0.850651], [ 0.309017, 0.500000, 0.809017], [ 0.525731, 0.000000, 0.850651],
[ 0.295242, 0.000000, 0.955423], [ 0.442863, 0.238856, 0.864188], [ 0.162460, 0.262866, 0.951056],
[-0.681718, 0.147621, 0.716567], [-0.809017, 0.309017, 0.500000], [-0.587785, 0.425325, 0.688191],
[-0.850651, 0.525731, 0.000000], [-0.864188, 0.442863, 0.238856], [-0.716567, 0.681718, 0.147621],
[-0.688191, 0.587785, 0.425325], [-0.500000, 0.809017, 0.309017], [-0.238856, 0.864188, 0.442863],
[-0.425325, 0.688191, 0.587785], [-0.716567, 0.681718, -0.147621], [-0.500000, 0.809017, -0.309017],
[-0.525731, 0.850651, 0.000000], [ 0.000000, 0.850651, -0.525731], [-0.238856, 0.864188, -0.442863],
[ 0.000000, 0.955423, -0.295242], [-0.262866, 0.951056, -0.162460], [ 0.000000, 1.000000, 0.000000],
[ 0.000000, 0.955423, 0.295242], [-0.262866, 0.951056, 0.162460], [ 0.238856, 0.864188, 0.442863],
[ 0.262866, 0.951056, 0.162460], [ 0.500000, 0.809017, 0.309017], [ 0.238856, 0.864188, -0.442863],
[ 0.262866, 0.951056, -0.162460], [ 0.500000, 0.809017, -0.309017], [ 0.850651, 0.525731, 0.000000],
[ 0.716567, 0.681718, 0.147621], [ 0.716567, 0.681718, -0.147621], [ 0.525731, 0.850651, 0.000000],
[ 0.425325, 0.688191, 0.587785], [ 0.864188, 0.442863, 0.238856], [ 0.688191, 0.587785, 0.425325],
[ 0.809017, 0.309017, 0.500000], [ 0.681718, 0.147621, 0.716567], [ 0.587785, 0.425325, 0.688191],
[ 0.955423, 0.295242, 0.000000], [ 1.000000, 0.000000, 0.000000], [ 0.951056, 0.162460, 0.262866],
[ 0.850651, -0.525731, 0.000000], [ 0.955423, -0.295242, 0.000000], [ 0.864188, -0.442863, 0.238856],
[ 0.951056, -0.162460, 0.262866], [ 0.809017, -0.309017, 0.500000], [ 0.681718, -0.147621, 0.716567],
[ 0.850651, 0.000000, 0.525731], [ 0.864188, 0.442863, -0.238856], [ 0.809017, 0.309017, -0.500000],
[ 0.951056, 0.162460, -0.262866], [ 0.525731, 0.000000, -0.850651], [ 0.681718, 0.147621, -0.716567],
[ 0.681718, -0.147621, -0.716567], [ 0.850651, 0.000000, -0.525731], [ 0.809017, -0.309017, -0.500000],
[ 0.864188, -0.442863, -0.238856], [ 0.951056, -0.162460, -0.262866], [ 0.147621, 0.716567, -0.681718],
[ 0.309017, 0.500000, -0.809017], [ 0.425325, 0.688191, -0.587785], [ 0.442863, 0.238856, -0.864188],
[ 0.587785, 0.425325, -0.688191], [ 0.688191, 0.587785, -0.425325], [-0.147621, 0.716567, -0.681718],
[-0.309017, 0.500000, -0.809017], [ 0.000000, 0.525731, -0.850651], [-0.525731, 0.000000, -0.850651],
[-0.442863, 0.238856, -0.864188], [-0.295242, 0.000000, -0.955423], [-0.162460, 0.262866, -0.951056],
[ 0.000000, 0.000000, -1.000000], [ 0.295242, 0.000000, -0.955423], [ 0.162460, 0.262866, -0.951056],
[-0.442863, -0.238856, -0.864188], [-0.309017, -0.500000, -0.809017], [-0.162460, -0.262866, -0.951056],
[ 0.000000, -0.850651, -0.525731], [-0.147621, -0.716567, -0.681718], [ 0.147621, -0.716567, -0.681718],
[ 0.000000, -0.525731, -0.850651], [ 0.309017, -0.500000, -0.809017], [ 0.442863, -0.238856, -0.864188],
[ 0.162460, -0.262866, -0.951056], [ 0.238856, -0.864188, -0.442863], [ 0.500000, -0.809017, -0.309017],
[ 0.425325, -0.688191, -0.587785], [ 0.716567, -0.681718, -0.147621], [ 0.688191, -0.587785, -0.425325],
[ 0.587785, -0.425325, -0.688191], [ 0.000000, -0.955423, -0.295242], [ 0.000000, -1.000000, 0.000000],
[ 0.262866, -0.951056, -0.162460], [ 0.000000, -0.850651, 0.525731], [ 0.000000, -0.955423, 0.295242],
[ 0.238856, -0.864188, 0.442863], [ 0.262866, -0.951056, 0.162460], [ 0.500000, -0.809017, 0.309017],
[ 0.716567, -0.681718, 0.147621], [ 0.525731, -0.850651, 0.000000], [-0.238856, -0.864188, -0.442863],
[-0.500000, -0.809017, -0.309017], [-0.262866, -0.951056, -0.162460], [-0.850651, -0.525731, 0.000000],
[-0.716567, -0.681718, -0.147621], [-0.716567, -0.681718, 0.147621], [-0.525731, -0.850651, 0.000000],
[-0.500000, -0.809017, 0.309017], [-0.238856, -0.864188, 0.442863], [-0.262866, -0.951056, 0.162460],
[-0.864188, -0.442863, 0.238856], [-0.809017, -0.309017, 0.500000], [-0.688191, -0.587785, 0.425325],
[-0.681718, -0.147621, 0.716567], [-0.442863, -0.238856, 0.864188], [-0.587785, -0.425325, 0.688191],
[-0.309017, -0.500000, 0.809017], [-0.147621, -0.716567, 0.681718], [-0.425325, -0.688191, 0.587785],
[-0.162460, -0.262866, 0.951056], [ 0.442863, -0.238856, 0.864188], [ 0.162460, -0.262866, 0.951056],
[ 0.309017, -0.500000, 0.809017], [ 0.147621, -0.716567, 0.681718], [ 0.000000, -0.525731, 0.850651],
[ 0.425325, -0.688191, 0.587785], [ 0.587785, -0.425325, 0.688191], [ 0.688191, -0.587785, 0.425325],
[-0.955423, 0.295242, 0.000000], [-0.951056, 0.162460, 0.262866], [-1.000000, 0.000000, 0.000000],
[-0.850651, 0.000000, 0.525731], [-0.955423, -0.295242, 0.000000], [-0.951056, -0.162460, 0.262866],
[-0.864188, 0.442863, -0.238856], [-0.951056, 0.162460, -0.262866], [-0.809017, 0.309017, -0.500000],
[-0.864188, -0.442863, -0.238856], [-0.951056, -0.162460, -0.262866], [-0.809017, -0.309017, -0.500000],
[-0.681718, 0.147621, -0.716567], [-0.681718, -0.147621, -0.716567], [-0.850651, 0.000000, -0.525731],
[-0.688191, 0.587785, -0.425325], [-0.587785, 0.425325, -0.688191], [-0.425325, 0.688191, -0.587785],
[-0.425325, -0.688191, -0.587785], [-0.587785, -0.425325, -0.688191], [-0.688191, -0.587785, -0.425325]
];
GLGE.MD2.prototype.MD2FrameRate=6;
/**
* Gets the absolute path given an import path and the path it's relative to
* @param {string} path the path to get the absolute path for
* @param {string} relativeto the path the supplied path is relativeto
* @returns {string} absolute path
* @private
*/
GLGE.MD2.prototype.getAbsolutePath=function(path,relativeto){
if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
return path;
}
else
{
if(!relativeto){
relativeto=window.location.href;
}
if (relativeto.indexOf("://")==-1){
return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
}
//find the path compoents
var bits=relativeto.split("/");
var domain=bits[2];
var proto=bits[0];
var initpath=[];
for(var i=3;i> 7)),
exponent = (((b0 << 1) & 0xff) | (b1 >> 7)) - 127,
mantissa = ((b1 & 0x7f) << 16) | (b2 << 8) | b3;
if (mantissa == 0 && exponent == -127) {
return 0.0;
}
if (exponent == -127) { // Denormalized
return sign * mantissa * Math.pow(2, -126 - 23);
}
return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
}
/**
* process the frame data
* @private
*/
GLGE.MD2.prototype.parseFrames=function(){
var vertsArray = this.byteArray;
var startFrame=0;
var MD2Animations={};
for(var j=0;j0) this.addMD3Childred();
this.loaded=true;
this.fireEvent("loaded",{url:this.url});
}
/**
* Adds the child md3 object
* @private
*/
GLGE.MD3.prototype.addMD3Childred=function(){
for(var i=0; i0x8000) value=value-0x10000;
return value;
}
/**
* get 32 bit signed int at location
* @private
*/
GLGE.MD3.prototype.getSint32At=function(index){
var value=this.byteArray[index]|(this.byteArray[index+1]<<8)|(this.byteArray[index+2]<<16)|(this.byteArray[index+3]<<24);
if(value>0x80000000) value=value-0x100000000;
return value;
}
/**
* Get 32 bit float at location
* @private
*/
GLGE.MD3.prototype.getFloat32At=function(index){
var b3=this.byteArray[index];
var b2=this.byteArray[index+1];
var b1=this.byteArray[index+2];
var b0=this.byteArray[index+3];
sign = 1 - (2 * (b0 >> 7)),
exponent = (((b0 << 1) & 0xff) | (b1 >> 7)) - 127,
mantissa = ((b1 & 0x7f) << 16) | (b2 << 8) | b3;
if (mantissa == 0 && exponent == -127) {
return 0.0;
}
if (exponent == -127) { // Denormalized
return sign * mantissa * Math.pow(2, -126 - 23);
}
return sign * (1 + mantissa * Math.pow(2, -23)) * Math.pow(2, exponent);
}
/**
* Get 32 bit float at location
* @private
*/
GLGE.MD3.prototype.getStringAt=function(index,size){
var name="";
for(var i=index;i-1) this.textures.splice(idx,1);
}
GLGE.Filter2d.prototype.createBuffer=function(gl,width,height){
if(!width) width=gl.canvas.width;
if(!height) height=gl.canvas.height;
var frameBuffer = gl.createFramebuffer();
var renderBuffer = gl.createRenderbuffer();
var texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
var tex = new Uint8Array(width*height*4);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, tex);
gl.bindFramebuffer(gl.FRAMEBUFFER, frameBuffer);
gl.bindRenderbuffer(gl.RENDERBUFFER, renderBuffer);
gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderBuffer);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
gl.bindRenderbuffer(gl.RENDERBUFFER, null);
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindTexture(gl.TEXTURE_2D, null);
return [frameBuffer,renderBuffer,texture];
}
GLGE.Filter2d.prototype.getFrameBuffer=function(gl){
if(!this.passes) return null;
if(!this.gl) this.gl=gl;
if(!this.buffers){
this.buffers=this.createBuffer(gl);
}
return this.buffers[0];
}
GLGE.Filter2d.prototype.getEmitBuffer=function(gl){
if(!this.passes) return null;
if(!this.gl) this.gl=gl;
if(!this.emitBuffers){
this.emitBuffers=this.createBuffer(gl,this.getEmitBufferWidth(),this.getEmitBufferHeight());
}
return this.emitBuffers[0];
}
GLGE.Filter2d.prototype.setEmitBufferWidth=function(value){
this.emitBufferWidth=value;
this.emitBuffers=null;
}
GLGE.Filter2d.prototype.getEmitBufferWidth=function(){
return (this.emitBufferWidth ? this.emitBufferWidth : this.gl.canvas.width);
}
GLGE.Filter2d.prototype.setEmitBufferHeight=function(value){
this.emitBufferHeight=value;
this.emitBuffers=null;
}
GLGE.Filter2d.prototype.getEmitBufferHeight=function(){
return (this.emitBufferHeight ? this.emitBufferHeight : this.gl.canvas.height);
}
GLGE.Filter2d.prototype.getDepthBuffer=function(gl){
if(!this.passes) return null;
if(!this.gl) this.gl=gl;
if(!this.depthBuffers){
this.depthBuffers=this.createBuffer(gl,this.getDepthBufferWidth(),this.getDepthBufferHeight());
}
return this.depthBuffers[0];
}
GLGE.Filter2d.prototype.setDepthBufferWidth=function(value){
this.depthBufferWidth=value;
this.depthBuffers=null;
}
GLGE.Filter2d.prototype.getDepthBufferWidth=function(){
return (this.depthBufferWidth ? this.depthBufferWidth : this.gl.canvas.width);
}
GLGE.Filter2d.prototype.setDepthBufferHeight=function(value){
this.depthBufferHeight=value;
this.depthBuffers=null;
}
GLGE.Filter2d.prototype.getDepthBufferHeight=function(){
return (this.depthBufferHeight ? this.depthBufferHeight : this.gl.canvas.height);
}
GLGE.Filter2d.prototype.setNormalBufferWidth=function(value){
this.normalBufferWidth=value;
this.normalBuffers=null;
}
GLGE.Filter2d.prototype.getNormalBufferWidth=function(){
return (this.normalBufferWidth ? this.normalBufferWidth : this.gl.canvas.width);
}
GLGE.Filter2d.prototype.setNormalBufferHeight=function(value){
this.normalBufferHeight=value;
this.normalBuffers=null;
}
GLGE.Filter2d.prototype.getNormalBufferHeight=function(){
return (this.normalBufferHeight ? this.normalBufferHeight : this.gl.canvas.height);
}
GLGE.Filter2d.prototype.getNormalBuffer=function(gl){
if(!this.gl) this.gl=gl;
if(!this.normalBuffers){
this.normalBuffers=this.createBuffer(gl,this.getNormalBufferWidth(),this.getNormalBufferHeight());
}
return this.normalBuffers[0];
}
GLGE.Filter2d.prototype.setUniform=function(type,name,value){
if(!this.uniforms) this.uniforms={};
this.uniforms[name]={type:type,value:value};
}
GLGE.Filter2d.prototype.getUniform=function(name){
if(!this.uniforms) this.uniforms={};
return this.uniforms[name].value
}
GLGE.Filter2d.prototype.getUniformType=function(name){
if(!this.uniforms) this.uniforms={};
return this.uniforms[name].type;
}
GLGE.Filter2d.prototype.addPassFile=function(url){
var req = new XMLHttpRequest();
var filter=this;
if(req) {
req.open("GET", url, false);
req.send("");
filter.addPass(req.responseText);
}
}
GLGE.Filter2d.prototype.addPass=function(GLSL,width,height){
if(!this.passes) this.passes=[];
this.passes.push({GLSL:GLSL,height:height,width:width});
}
/**
* Creates the preserve texture
* @private
*/
GLGE.Filter2d.prototype.createPersistTexture=function(gl){
this.persistTexture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, this.persistTexture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.canvas.width,gl.canvas.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
}
//does all passes and renders result to screen
GLGE.Filter2d.prototype.GLRender=function(gl,buffer){
gl.disable(gl.BLEND);
if(!buffer) buffer=null;
if(this.passes){
for(var i=0;i lumaMax)) gl_FragColor = vec4(rgbA,1.0);");
pass3.push(" else gl_FragColor = vec4(rgbB,1.0);");
pass3.push(" if(length(rgbM)>"+this.fxaacutoff.toFixed(2)+") gl_FragColor = vec4(rgbM,1.0);");
pass3.push(" if(length(rgbM)<"+this.fxaastartintensity.toFixed(2)+") gl_FragColor = vec4(rgbM,1.0);");
pass3.push("}");
this.addPass(pass3.join("\n"));
}
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_filter_ao.js
* @author me@paulbrunt.co.uk
*/
(function(GLGE){
/**
* @class Postprocessing Ambient Occlusion filter
* @augments GLGE.Filter2d
*/
GLGE.FilterAO=function(){
this.setUniform("1f","cavitygamma",1/3);
this.setUniform("1f","whiteMul",2);
this.setUniform("1f","aogamma",1/3);
this.setUniform("1f","maxDist",0.025);
this.passes=[];
};
GLGE.augment(GLGE.Filter2d,GLGE.FilterAO);
GLGE.FilterAO.prototype.renderNormal=true;
GLGE.FilterAO.prototype.quality=1;
GLGE.FilterAO.prototype.range=80;
GLGE.FilterAO.prototype.samples=16;
GLGE.FilterAO.prototype.useRender=true;
GLGE.FilterAO.prototype.getNormalBufferHeight=function(){
return (this.normalBufferHeight ? this.normalBufferHeight : (this.gl.canvas.height*this.quality|0));
}
GLGE.FilterAO.prototype.getNormalBufferWidth=function(){
return (this.normalBufferWidth ? this.normalBufferWidth : (this.gl.canvas.width*this.quality|0));
}
GLGE.FilterAO.prototype.setUseRender=function(value){
this.useRender=value;
this.normalBuffers=null;
this.passes=[];
return this;
}
GLGE.FilterAO.prototype.setSamples=function(value){
this.samples=value;
this.normalBuffers=null;
this.passes=[];
return this;
}
GLGE.FilterAO.prototype.setQuality=function(value){
this.quality=value;
this.normalBuffers=null;
this.passes=[];
return this;
}
GLGE.FilterAO.prototype.setRange=function(value){
this.range=value;
if(this.gl){
this.setUniform("1f","blurX",this.range/this.getNormalBufferWidth()*this.quality/this.samples);
this.setUniform("1f","blurY",this.range/this.getNormalBufferHeight()/this.samples);
}
return this;
}
GLGE.FilterAO.prototype.setCavityGamma=function(value){
this.setUniform("1f","cavitygamma",1/value);
return this;
}
GLGE.FilterAO.prototype.setAmbientMultiplier=function(value){
this.setUniform("1f","whiteMul",value);
return this;
}
GLGE.FilterAO.prototype.setAmbientGamma=function(value){
this.setUniform("1f","aogamma",1/value);
return this;
}
GLGE.FilterAO.prototype.setMaximumDistance=function(value){
this.setUniform("1f","maxDist",value);
return this;
}
GLGE.FilterAO.prototype.GLRender=function(gl,buffer){
this.gl=gl;
if(this.passes.length==0){
this.createPasses();
}
return GLGE.Filter2d.prototype.GLRender.call(this,gl,buffer)
}
GLGE.FilterAO.prototype.createPasses=function(){
if(!this.gl) return;
var width=this.getNormalBufferWidth();
var height=this.getNormalBufferHeight();
var size=(this.samples/4)|0;
var weights=[];
for(var i=-size,cnt=0; i<=size;i++,cnt++){
var n=size-Math.abs(i)+1;
weights[cnt]=n/(size*size+size);
}
weights[size]=0;
this.setUniform("1f","blurX",this.range/width*this.quality/this.samples);
this.setUniform("1f","blurY",this.range/height/this.samples);
var pass1=[];
pass1.push("precision highp float;");
pass1.push("uniform sampler2D GLGE_NORMAL;");
pass1.push("uniform float maxDist;");
pass1.push("varying vec2 texCoord;");
pass1.push("uniform float blurX;");
pass1.push("float rand(vec2 co){");
pass1.push("return (fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453)-0.5)*2.0;");
pass1.push("}");
pass1.push("void main(void){");
pass1.push("vec4 n=texture2D(GLGE_NORMAL,texCoord.xy).rgba;");
pass1.push("vec4 color=vec4(0.0,0.0,0.0,n.a);");
pass1.push("float blurSize=blurX/(n.a*n.a+1.0);");
pass1.push("float offset=rand(texCoord.xy)*blurSize+texCoord.x;");
pass1.push("vec3 samp;");
pass1.push("float delta;");
for(var i=-size,cnt=0;i<=size;i++,cnt++){
if(i==0) continue;
pass1.push("samp = texture2D(GLGE_NORMAL, vec2("+i+".0*blurSize+offset, texCoord.y)).rga;");
pass1.push("delta=abs(n.a-samp.b);");
pass1.push("if(delta lumaMax)) gl_FragColor = vec4(rgbA,1.0);");
pass3.push(" else gl_FragColor = vec4(rgbB,1.0);");
pass3.push(" if(length(rgbM)>10.0) gl_FragColor = vec4(rgbM,1.0);");
pass3.push("}");
this.passes=[];
this.addPass(pass1.join(""),width,height);
this.addPass(pass2.join(""));
this.addPass(pass3.join("\n"));
}
})(GLGE);/*
GLGE WebGL Graphics Engine
Copyright (c) 2010, Paul Brunt
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 GLGE 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.
*/
/**
* @fileOverview
* @name glge_collada.js
* @author me@paulbrunt.co.uk
*/
if(typeof(GLGE) == "undefined"){
/**
* @namespace Holds the functionality of the library
*/
GLGE = {};
}
(function(GLGE){
GLGE.ColladaDocuments=[];
/**
* @class Class to represent a collada object
* @augments GLGE.Group
*/
GLGE.Collada=function(uid){
GLGE.Group.call(this);
this.children=[];
this.actions={};
this.boneIdx=0;
this.actionsIdx=0;
GLGE.Assets.registerAsset(this,uid);
};
GLGE.augment(GLGE.Group,GLGE.Collada);
GLGE.Collada.prototype.type=GLGE.G_NODE;
GLGE.Collada.prototype.useLights=false;
GLGE.Collada.prototype.useCamera=false
GLGE.Collada.prototype.useBinaryAlpha=false;
/**
* Gets the absolute path given an import path and the path it's relative to
* @param {string} path the path to get the absolute path for
* @param {string} relativeto the path the supplied path is relativeto
* @returns {string} absolute path
* @private
*/
GLGE.Collada.prototype.getAbsolutePath=function(path,relativeto){
if(path.substr(0,7)=="http://" || path.substr(0,7)=="file://" || path.substr(0,7)=="https://"){
return path;
}
else
{
if(!relativeto){
relativeto=window.location.href;
}
if (relativeto.indexOf("://")==-1){
return relativeto.slice(0,relativeto.lastIndexOf("/"))+"/"+path;
}
//find the path compoents
var bits=relativeto.split("/");
var domain=bits[2];
var proto=bits[0];
var initpath=[];
for(var i=3;i0) polygons[i].getElementsByTagName("p")[0].data=tris;
}
//create a mesh for each set of faces
var triangles=[];
var tris=meshNode.getElementsByTagName("triangles");
for(i=0;i0) triangles.push(polygons[i])};
for(i=0;ib?b:a);
}
var MAXVERTS=21843;
MAXVERTS*=3;//always must be a multiple of 3 (3 vertices)
var nummesh=((faces.length-faces.length%MAXVERTS)/MAXVERTS)+(faces.length%MAXVERTS?1:0);
var trimesh=[];
var vstride=3;
var nstride=3;
var tstride=2;
for (var index=0;index8){
var newjoints=[];
var newweights=[];
for(var j=0;j
*
* The material getter below borked if there is e.g. a scene node with the same name as the material.
* This is used to fix that by only looking for materials in the library_materials element.
*/
function getChildElementById( dNode, id ) {
var dResult = null;
if ( dNode.getAttribute('id') == id )
return dNode;
for ( var i = 0; i < dNode.childNodes.length; i++ ) {
if ( dNode.childNodes[i].nodeType == 1 ) {
dResult = getChildElementById( dNode.childNodes[i], id ); //note: 1-level deep would suffice here, doesn't need to recurse into further childs. but this works.
if ( dResult != null )
break;
}
}
return dResult;
}
var MaterialCache={};
/**
* Gets the sampler for a texture
* @param {string} id the id or the material element
* @private
*/
GLGE.Collada.prototype.getMaterial=function(id,bvi){
// JHD: Added "else" and enclosing brackets
if (!MaterialCache[this.url]) {
MaterialCache[this.url] = {};
} else if (MaterialCache[this.url][id]) {
return MaterialCache[this.url][id];
}
var materialLib=this.xml.getElementsByTagName("library_materials")[0];
var materialNode=getChildElementById(materialLib, id); //this.xml.getElementById(id);
if (!materialNode) {
var returnMaterial=new GLGE.Material();
MaterialCache[this.url][id]=returnMaterial;
return returnMaterial;
}
var effectid=materialNode.getElementsByTagName("instance_effect")[0].getAttribute("url").substr(1);
var effect=this.xml.getElementById(effectid);
var common=effect.getElementsByTagName("profile_COMMON")[0];
//glge only supports one technique currently so try and match as best we can
var technique=common.getElementsByTagName("technique")[0];
var returnMaterial=new GLGE.Material();
returnMaterial.setBinaryAlpha(this.useBinaryAlpha);
returnMaterial.setSpecular(0);
MaterialCache[this.url][id]=returnMaterial;
var child;
var color;
//do ambient lighting
var ambient=technique.getElementsByTagName("ambient");
if(ambient.length>0){
child=ambient[0].firstChild;
do{
switch(child.tagName){
case "color":
color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
returnMaterial.setAmbient({r:color[0],g:color[1],b:color[2]});
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
returnMaterial.setAmbient({r:color[0],g:color[1],b:color[2]});
break;
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_AMBIENT,bvi);
break;
}
}while(child=child.nextSibling);
}
//do diffuse color
var diffuse=technique.getElementsByTagName("diffuse");
if(diffuse.length>0){
child=diffuse[0].firstChild;
do{
switch(child.tagName){
case "color":
color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
returnMaterial.setColor({r:color[0],g:color[1],b:color[2]});
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
returnMaterial.setColor({r:color[0],g:color[1],b:color[2]});
break;
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_COLOR,bvi);
break;
}
}while(child=child.nextSibling);
}
var bump=technique.getElementsByTagName("bump");
if(bump.length>0){
child=bump[0].firstChild;
do{
switch(child.tagName){
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_NOR,bvi);
break;
}
}while(child=child.nextSibling);
}
//do shininess
var shininess=technique.getElementsByTagName("shininess");
if(shininess.length>0){
returnMaterial.setSpecular(1);
child=technique.getElementsByTagName("shininess")[0].firstChild;
do{
switch(child.tagName){
case "float":
if(parseFloat(child.firstChild.nodeValue)>1) returnMaterial.setShininess(parseFloat(child.firstChild.nodeValue));
else returnMaterial.setShininess(parseFloat(child.firstChild.nodeValue)*128);
break;
case "param":
var value=parseFloat(this.getFloat(common,child.getAttribute("ref")));
if(value>1) returnMaterial.setShininess(value);
else returnMaterial.setShininess(value*128);
break;
// MCB: texture is invalid here. should remove this case.
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_SHINE,bvi);
break;
}
}while(child=child.nextSibling);
}
//do specular color
var specular=technique.getElementsByTagName("specular");
if(specular.length>0){
returnMaterial.setSpecular(1);
child=specular[0].firstChild;
do{
switch(child.tagName){
case "color":
color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
returnMaterial.setSpecularColor({r:color[0],g:color[1],b:color[2]});
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
returnMaterial.setSpecularColor({r:color[0],g:color[1],b:color[2]});
break;
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_SPECCOLOR,bvi);
break;
}
}while(child=child.nextSibling);
}
//do reflectivity
/*
var reflectivity=technique.getElementsByTagName("reflectivity");
if(reflectivity.length>0){
child=reflectivity[0].firstChild;
do{
switch(child.tagName){
case "float":
//returnMaterial.setReflectivity(parseFloat(child.firstChild.nodeValue))
break;
case "param":
//returnMaterial.setReflectivity(parseFloat(this.getFloat(common,child.getAttribute("ref"))));
break;
// MCB: texture is invalid here. should remove this case.
case "texture":
var imageid=this.getSurface(common,this.getSampler(common,child.getAttribute("texture")));
textureImage=this.getImage(imageid);
var texture=new GLGE.Texture(textureImage);
returnMaterial.addTexture(texture);
returnMaterial.addMaterialLayer(new GLGE.MaterialLayer(texture,GLGE.M_REFLECT,GLGE.UV1));
break;
}
}while(child=child.nextSibling);
}*/
//do emission color
var emission=technique.getElementsByTagName("emission");
if(emission.length>0){
child=emission[0].firstChild;
do{
switch(child.tagName){
case "color":
color=child.firstChild.nodeValue.split(" ");
returnMaterial.setEmit({r:color[0],g:color[1],b:color[2]});
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).split(" ");
returnMaterial.setEmit(color[0]);
break;
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_EMIT,bvi);
break;
}
}while(child=child.nextSibling);
}
//do reflective color
var reflective=technique.getElementsByTagName("reflective");
if(reflective.length>0){
child=reflective[0].firstChild;
do{
switch(child.tagName){
case "color":
color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
//TODO returnMaterial.setReflectiveColor({r:color[0],g:color[1],b:color[2]});
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
//TODO returnMaterial.setReflectiveColor({r:color[0],g:color[1],b:color[2]});
break;
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_REFLECT,bvi);
break;
}
}while(child=child.nextSibling);
}
//do transparency
var transparency=technique.getElementsByTagName("transparency");
if(transparency.length>0){
child=transparency[0].firstChild;
do{
switch(child.tagName){
case "float":
//TODO returnMaterial.setTransparency(parseFloat(child.firstChild.nodeValue))
//Causing issues with a couple of models
if(child.firstChild.nodeValue<1){
returnMaterial.setAlpha(parseFloat(child.firstChild.nodeValue));
returnMaterial.trans=true;
}
break;
case "param":
//TODO returnMaterial.setTransparency(parseFloat(this.getFloat(common,child.getAttribute("ref"))));
break;
}
}while(child=child.nextSibling);
}
//do transparent color
var transparent=technique.getElementsByTagName("transparent");
if(transparent.length>0){
var opaque=transparent[0].getAttribute("opaque");
if(!opaque) opaque="A_ONE"; // schema default
child=transparent[0].firstChild;
do{
switch(child.tagName){
// MCB: float is invalid here. should remove this case.
case "float":
var alpha=parseFloat(child.firstChild.nodeValue);
if(alpha<1){
returnMaterial.setAlpha(parseFloat(child.firstChild.nodeValue));
returnMaterial.trans=true;
}
break;
case "color":
color=child.firstChild.nodeValue.replace(/\s+/g,' ').split(" ");
var alpha=this.getMaterialAlpha(color,opaque,1);
//TODO var alpha=this.getMaterialAlpha(color,opaque,returnMaterial.getTransparency());
if(alpha<1){
returnMaterial.setAlpha(alpha);
returnMaterial.trans=true;
}
break;
case "param":
color=this.getFloat4(common,child.getAttribute("ref")).replace(/\s+/g,' ').split(" ");
var alpha=this.getMaterialAlpha(color,opaque,1);
//TODO var alpha=this.getMaterialAlpha(color,opaque,returnMaterial.getTransparency());
if(alpha<1){
returnMaterial.setAlpha(alpha);
returnMaterial.trans=true;
}
break;
// MCB: this case assumes opaque="A_ONE" and transparency="1.0"
case "texture":
this.createMaterialLayer(child,returnMaterial,common,GLGE.M_ALPHA,bvi);
returnMaterial.trans=true;
break;
}
}while(child=child.nextSibling);
}
return returnMaterial;
};
/**
* gets the material alpha from the transparent color
* @param {color} the transparent color
* @param {opaque} the transparent color opaque attribute value
* @param {transparency} the transparency value
* @private
*/
GLGE.Collada.prototype.getMaterialAlpha=function(color,opaque,transparency){
var returnAlpha;
switch(opaque){
case "A_ONE":
returnAlpha=parseFloat(color[3])*transparency;
break;
case "A_ZERO":
returnAlpha=1-parseFloat(color[3])*transparency;
break;
case "RGB_ONE":
var luminance=parseFloat(color[0])*0.212671
+parseFloat(color[1])*0.715160
+parseFloat(color[2])*0.072169;
returnAlpha=luminance*transparency;
break;
case "RGB_ZERO":
var luminance=parseFloat(color[0])*0.212671
+parseFloat(color[1])*0.715160
+parseFloat(color[2])*0.072169;
returnAlpha=1-luminance*transparency;
break;
}
return returnAlpha;
};
GLGE.Collada.prototype.setMaterialOntoMesh=function(meshes,node) {
var materials=node.getElementsByTagName("instance_material");
var objMaterials={};
for(var i=0; i=0;--i)
if (str[i]>="0"&&str[i]<="9")
retval=str[i]+retval;
if (retval.length==0) return "0";
return retval;
}
bvi[bvis[j].getAttribute("semantic")]=getLastNumber(bvis[j].getAttribute("semantic"));
}
}
mat=this.getMaterial(materials[i].getAttribute("target").substr(1),bvi);
objMaterials[materials[i].getAttribute("symbol")]=mat;
}
//create GLGE object
var obj=new GLGE.Object();
for(i=0; i