From ae22b78c2c69ca7a398b56ad0d741f3d8bfe720d Mon Sep 17 00:00:00 2001 From: alteredq Date: Wed, 12 Oct 2011 13:41:36 +0200 Subject: [PATCH] Added MorphAnimMesh. Added MathUtils. Added morph to rendering testbed. Simplified shadowmap shader snippet gamma handling. --- build/Three.js | 217 ++++++++++++++------------- build/custom/ThreeExtras.js | 6 +- build/custom/ThreeWebGL.js | 2 +- examples/webgl_shading_physical.html | 70 ++++++--- src/extras/MathUtils.js | 19 +++ src/objects/MorphAnimMesh.js | 89 +++++++++++ src/renderers/WebGLShaders.js | 20 +-- utils/build.py | 2 + 8 files changed, 283 insertions(+), 142 deletions(-) create mode 100644 src/extras/MathUtils.js create mode 100644 src/objects/MorphAnimMesh.js diff --git a/build/Three.js b/build/Three.js index 832e058f..f2a09d76 100644 --- a/build/Three.js +++ b/build/Three.js @@ -134,8 +134,11 @@ f=this.bones[e],h.parent===-1?this.addChild(f):this.bones[h.parent].addChild(f); THREE.SkinnedMesh.prototype.update=function(b,c,e){if(this.visible){this.matrixAutoUpdate&&(c|=this.updateMatrix());if(c||this.matrixWorldNeedsUpdate)b?this.matrixWorld.multiply(b,this.matrix):this.matrixWorld.copy(this.matrix),this.matrixWorldNeedsUpdate=!1,c=!0;var f,h=this.children.length;for(f=0;fthis.duration||this.time<0){this.direction*=-1;if(this.time>this.duration)this.time=this.duration,this.directionBackwards=!0;if(this.time<0)this.time=0,this.directionBackwards=!1}}else this.time%=this.duration;b=THREE.MathUtils.clamp(Math.floor(this.time/c),0,this.geometry.morphTargets.length-1);if(b!=this.currentKeyframe)this.morphTargetInfluences[this.lastKeyframe]= +0,this.morphTargetInfluences[this.currentKeyframe]=1,this.morphTargetInfluences[b]=0,this.lastKeyframe=this.currentKeyframe,this.currentKeyframe=b;c=this.time%c/c;this.directionBackwards&&(c=1-c);this.morphTargetInfluences[this.currentKeyframe]=c;this.morphTargetInfluences[this.lastKeyframe]=1-c};THREE.Ribbon=function(b,c){THREE.Object3D.call(this);this.geometry=b;this.materials=c instanceof Array?c:[c]};THREE.Ribbon.prototype=new THREE.Object3D;THREE.Ribbon.prototype.constructor=THREE.Ribbon; +THREE.LOD=function(){THREE.Object3D.call(this);this.LODs=[]};THREE.LOD.prototype=new THREE.Object3D;THREE.LOD.prototype.constructor=THREE.LOD;THREE.LOD.prototype.supr=THREE.Object3D.prototype;THREE.LOD.prototype.addLevel=function(b,c){c===void 0&&(c=0);for(var c=Math.abs(c),e=0;e1){b=e.matrixWorldInverse;b=-(b.n31*this.position.x+b.n32*this.position.y+b.n33*this.position.z+b.n34);this.LODs[0].object3D.visible=!0;for(var f=1;f=this.LODs[f].visibleAtDistance)this.LODs[f-1].object3D.visible=!1, this.LODs[f].object3D.visible=!0;else break;for(;f 0\nu color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\n#endif",skinning_vertex:"#ifdef USE_SKINNING\ngl_Position = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;\ngl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;\ngl_Position = projectionMatrix * viewMatrix * objectMatrix * gl_Position;\n#endif", morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\nuniform float morphTargetInfluences[ 8 ];\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0, 0.0, 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\nmorphed += position;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );\n#endif", default_vertex:"#ifndef USE_MORPHTARGETS\n#ifndef USE_SKINNING\ngl_Position = projectionMatrix * mvPosition;\n#endif\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform float shadowDarkness;\nuniform float shadowBias;\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif", -shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_SOFT\nconst float xPixelOffset = 1.0 / SHADOWMAP_WIDTH;\nconst float yPixelOffset = 1.0 / SHADOWMAP_HEIGHT;\n#endif\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nshadowCoord.z += shadowBias;\nif ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nfor ( float y = -1.25; y <= 1.25; y += 1.25 )\nfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\nvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadow += 1.0;\n}\nshadow /= 9.0;\n#ifdef GAMMA_OUTPUT\nvec3 darkening = vec3( ( 1.0 - shadowDarkness * shadow ) );\ndarkening *= darkening;\nshadowColor = shadowColor * darkening;\n#else\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );\n#endif\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( shadowDarkness );\n#endif\n}\n}\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", +shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_SOFT\nconst float xPixelOffset = 1.0 / SHADOWMAP_WIDTH;\nconst float yPixelOffset = 1.0 / SHADOWMAP_HEIGHT;\n#endif\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nshadowCoord.z += shadowBias;\nif ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nfor ( float y = -1.25; y <= 1.25; y += 1.25 )\nfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\nvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadow += 1.0;\n}\nshadow /= 9.0;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( shadowDarkness );\n#endif\n}\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; THREE.UniformsUtils={merge:function(b){var c,e,f,h={};for(c=0;ce?e:b},mapLinear:function(b,c,e,f,h){return(b-c)*(h-f)/(e-c)+f}};THREE.SceneUtils={showHierarchy:function(b,c){THREE.SceneUtils.traverseHierarchy(b,function(b){b.visible=c})},traverseHierarchy:function(b,c){var e,f,h=b.children.length;for(f=0;fthis.heightMax?this.heightMax:this.object.position.y)-this.heightMin)*this.heightCoef:0;var e=this.tdiff*this.movementSpeed;(this.moveForward||this.autoForward&& -!this.moveBackward)&&this.object.translateZ(-(e+this.autoSpeedFactor));this.moveBackward&&this.object.translateZ(e);this.moveLeft&&this.object.translateX(-e);this.moveRight&&this.object.translateX(e);this.moveUp&&this.object.translateY(e);this.moveDown&&this.object.translateY(-e);e=this.tdiff*this.lookSpeed;this.activeLook||(e=0);this.lon+=this.mouseX*e;this.lookVertical&&(this.lat-=this.mouseY*e);this.lat=Math.max(-85,Math.min(85,this.lat));this.phi=(90-this.lat)*Math.PI/180;this.theta=this.lon* -Math.PI/180;var b=this.target,c=this.object.position;b.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);b.y=c.y+100*Math.cos(this.phi);b.z=c.z+100*Math.sin(this.phi)*Math.sin(this.theta)}b=1;this.constrainVertical&&(b=Math.PI/(this.verticalMax-this.verticalMin));this.lon+=this.mouseX*e;this.lookVertical&&(this.lat-=this.mouseY*e*b);this.lat=Math.max(-85,Math.min(85,this.lat));this.phi=(90-this.lat)*Math.PI/180;this.theta=this.lon*Math.PI/180;if(this.constrainVertical)this.phi=(this.phi-0)*(this.verticalMax- -this.verticalMin)/(Math.PI-0)+this.verticalMin;b=this.target;c=this.object.position;b.x=c.x+100*Math.sin(this.phi)*Math.cos(this.theta);b.y=c.y+100*Math.cos(this.phi);b.z=c.z+100*Math.sin(this.phi)*Math.sin(this.theta);this.object.lookAt(b)};this.domElement.addEventListener("contextmenu",function(b){b.preventDefault()},!1);this.domElement.addEventListener("mousemove",e(this,this.onMouseMove),!1);this.domElement.addEventListener("mousedown",e(this,this.onMouseDown),!1);this.domElement.addEventListener("mouseup", +!1;break;case 39:case 68:this.moveRight=!1;break;case 82:this.moveUp=!1;break;case 70:this.moveDown=!1}};this.update=function(){var b=(new Date).getTime();this.tdiff=(b-this.lastUpdate)/1E3;this.lastUpdate=b;if(!this.freeze){this.autoSpeedFactor=this.heightSpeed?this.tdiff*((this.object.position.ythis.heightMax?this.heightMax:this.object.position.y)-this.heightMin)*this.heightCoef:0;var c=this.tdiff*this.movementSpeed;(this.moveForward||this.autoForward&& +!this.moveBackward)&&this.object.translateZ(-(c+this.autoSpeedFactor));this.moveBackward&&this.object.translateZ(c);this.moveLeft&&this.object.translateX(-c);this.moveRight&&this.object.translateX(c);this.moveUp&&this.object.translateY(c);this.moveDown&&this.object.translateY(-c);c=this.tdiff*this.lookSpeed;this.activeLook||(c=0);this.lon+=this.mouseX*c;this.lookVertical&&(this.lat-=this.mouseY*c);this.lat=Math.max(-85,Math.min(85,this.lat));this.phi=(90-this.lat)*Math.PI/180;this.theta=this.lon* +Math.PI/180;var b=this.target,e=this.object.position;b.x=e.x+100*Math.sin(this.phi)*Math.cos(this.theta);b.y=e.y+100*Math.cos(this.phi);b.z=e.z+100*Math.sin(this.phi)*Math.sin(this.theta)}b=1;this.constrainVertical&&(b=Math.PI/(this.verticalMax-this.verticalMin));this.lon+=this.mouseX*c;this.lookVertical&&(this.lat-=this.mouseY*c*b);this.lat=Math.max(-85,Math.min(85,this.lat));this.phi=(90-this.lat)*Math.PI/180;this.theta=this.lon*Math.PI/180;if(this.constrainVertical)this.phi=(this.phi-0)*(this.verticalMax- +this.verticalMin)/(Math.PI-0)+this.verticalMin;b=this.target;e=this.object.position;b.x=e.x+100*Math.sin(this.phi)*Math.cos(this.theta);b.y=e.y+100*Math.cos(this.phi);b.z=e.z+100*Math.sin(this.phi)*Math.sin(this.theta);this.object.lookAt(b)};this.domElement.addEventListener("contextmenu",function(b){b.preventDefault()},!1);this.domElement.addEventListener("mousemove",e(this,this.onMouseMove),!1);this.domElement.addEventListener("mousedown",e(this,this.onMouseDown),!1);this.domElement.addEventListener("mouseup", e(this,this.onMouseUp),!1);this.domElement.addEventListener("keydown",e(this,this.onKeyDown),!1);this.domElement.addEventListener("keyup",e(this,this.onKeyUp),!1)}; -THREE.PathControls=function(b,c){function e(b){if((b*=2)<1)return 0.5*b*b;return-0.5*(--b*(b-2)-1)}function f(b,e){return function(){e.apply(b,arguments)}}function h(b,e,c,f){var k={name:c,fps:0.6,length:f,hierarchy:[]},h,m=e.getControlPointsArray(),n=e.getLength(),y=m.length,E=0;h=y-1;e={parent:-1,keys:[]};e.keys[0]={time:0,pos:m[0],rot:[0,0,0,1],scl:[1,1,1]};e.keys[h]={time:f,pos:m[h],rot:[0,0,0,1],scl:[1,1,1]};for(h=1;h=0?b:b+m;b=this.verticalAngleMap.srcRange; c=this.verticalAngleMap.dstRange;var f=c[1]-c[0];this.phi=e(((this.phi-b[0])*(c[1]-c[0])/(b[1]-b[0])+c[0]-c[0])/f)*f+c[0];b=this.horizontalAngleMap.srcRange;c=this.horizontalAngleMap.dstRange;f=c[1]-c[0];this.theta=e(((this.theta-b[0])*(c[1]-c[0])/(b[1]-b[0])+c[0]-c[0])/f)*f+c[0];b=this.target.position;b.x=100*Math.sin(this.phi)*Math.cos(this.theta);b.y=100*Math.cos(this.phi);b.z=100*Math.sin(this.phi)*Math.sin(this.theta);this.object.lookAt(this.target.position)};this.onMouseMove=function(b){this.domElement=== -document?(this.mouseX=b.pageX-this.viewHalfX,this.mouseY=b.pageY-this.viewHalfY):(this.mouseX=b.pageX-this.domElement.offsetLeft-this.viewHalfX,this.mouseY=b.pageY-this.domElement.offsetTop-this.viewHalfY)};this.init=function(){this.spline=new THREE.Spline;this.spline.initFromArray(this.waypoints);this.useConstantSpeed&&this.spline.reparametrizeByArcLength(this.resamplingCoef);if(this.createDebugDummy){var b=new THREE.MeshLambertMaterial({color:30719}),e=new THREE.MeshLambertMaterial({color:65280}), -c=new THREE.CubeGeometry(10,10,20),m=new THREE.CubeGeometry(2,2,10);this.animationParent=new THREE.Mesh(c,b);b=new THREE.Mesh(m,e);b.position.set(0,10,0);this.animation=h(this.animationParent,this.spline,this.id,this.duration);this.animationParent.add(this.object);this.animationParent.add(this.target);this.animationParent.add(b)}else this.animation=h(this.animationParent,this.spline,this.id,this.duration),this.animationParent.add(this.target),this.animationParent.add(this.object);if(this.createDebugPath){var b= -this.debugPath,e=this.spline,c=k(e,10),m=k(e,10),n=new THREE.LineBasicMaterial({color:16711680,linewidth:3});lineObj=new THREE.Line(c,n);particleObj=new THREE.ParticleSystem(m,new THREE.ParticleBasicMaterial({color:16755200,size:3}));lineObj.scale.set(1,1,1);b.add(lineObj);particleObj.scale.set(1,1,1);b.add(particleObj);m=new THREE.SphereGeometry(1,16,8);n=new THREE.MeshBasicMaterial({color:65280});for(i=0;i0){var e=this.getContainerDimensions(),c=e.size[0]/2,m=e.size[1]/2;this.moveState.yawLeft=-(b.pageX-e.offset[0]-c)/c;this.moveState.pitchDown=(b.pageY-e.offset[1]-m)/m;this.updateRotationVector()}};this.mouseup=function(b){b.preventDefault();b.stopPropagation();if(this.dragToLook)this.mouseStatus--,this.moveState.yawLeft=this.moveState.pitchDown=0;else switch(b.button){case 0:this.moveForward= -!1;break;case 2:this.moveBackward=!1}this.updateRotationVector()};this.update=function(){var b=(new Date).getTime();if(this.lastUpdate==-1)this.lastUpdate=b;this.tdiff=(b-this.lastUpdate)/1E3;this.lastUpdate=b;var b=this.tdiff*this.movementSpeed,e=this.tdiff*this.rollSpeed;this.object.translateX(this.moveVector.x*b);this.object.translateY(this.moveVector.y*b);this.object.translateZ(this.moveVector.z*b);this.tmpQuaternion.set(this.rotationVector.x*e,this.rotationVector.y*e,this.rotationVector.z*e, +!0;break;case 2:this.object.moveBackward=!0}};this.mousemove=function(b){if(!this.dragToLook||this.mouseStatus>0){var c=this.getContainerDimensions(),e=c.size[0]/2,m=c.size[1]/2;this.moveState.yawLeft=-(b.pageX-c.offset[0]-e)/e;this.moveState.pitchDown=(b.pageY-c.offset[1]-m)/m;this.updateRotationVector()}};this.mouseup=function(b){b.preventDefault();b.stopPropagation();if(this.dragToLook)this.mouseStatus--,this.moveState.yawLeft=this.moveState.pitchDown=0;else switch(b.button){case 0:this.moveForward= +!1;break;case 2:this.moveBackward=!1}this.updateRotationVector()};this.update=function(){var b=(new Date).getTime();if(this.lastUpdate==-1)this.lastUpdate=b;this.tdiff=(b-this.lastUpdate)/1E3;this.lastUpdate=b;var b=this.tdiff*this.movementSpeed,c=this.tdiff*this.rollSpeed;this.object.translateX(this.moveVector.x*b);this.object.translateY(this.moveVector.y*b);this.object.translateZ(this.moveVector.z*b);this.tmpQuaternion.set(this.rotationVector.x*c,this.rotationVector.y*c,this.rotationVector.z*c, 1).normalize();this.object.quaternion.multiplySelf(this.tmpQuaternion);this.object.matrix.setPosition(this.object.position);this.object.matrix.setRotationFromQuaternion(this.object.quaternion);this.object.matrixWorldNeedsUpdate=!0};this.updateMovementVector=function(){var b=this.moveState.forward||this.autoForward&&!this.moveState.back?1:0;this.moveVector.x=-this.moveState.left+this.moveState.right;this.moveVector.y=-this.moveState.down+this.moveState.up;this.moveVector.z=-b+this.moveState.back}; this.updateRotationVector=function(){this.rotationVector.x=-this.moveState.pitchDown+this.moveState.pitchUp;this.rotationVector.y=-this.moveState.yawRight+this.moveState.yawLeft;this.rotationVector.z=-this.moveState.rollRight+this.moveState.rollLeft};this.getContainerDimensions=function(){return this.domElement!=document?{size:[this.domElement.offsetWidth,this.domElement.offsetHeight],offset:[this.domElement.offsetLeft,this.domElement.offsetTop]}:{size:[window.innerWidth,window.innerHeight],offset:[0, 0]}};this.domElement.addEventListener("mousemove",e(this,this.mousemove),!1);this.domElement.addEventListener("mousedown",e(this,this.mousedown),!1);this.domElement.addEventListener("mouseup",e(this,this.mouseup),!1);this.domElement.addEventListener("keydown",e(this,this.keydown),!1);this.domElement.addEventListener("keyup",e(this,this.keyup),!1);this.updateMovementVector();this.updateRotationVector()}; @@ -476,16 +479,16 @@ b;this.object.position.y+=this.object.matrix.n22*b;this.object.position.z+=this. this.object.matrix.n22,this.object.matrix.n32);f.multiplyScalar(b);this.forward.addSelf(f);this.forward.normalize()};this.domElement.addEventListener("contextmenu",function(b){b.preventDefault()},!1);this.domElement.addEventListener("mousemove",function(b){o=(b.clientX-v)/window.innerWidth;x=(b.clientY-z)/window.innerHeight},!1);this.domElement.addEventListener("mousedown",function(b){b.preventDefault();b.stopPropagation();switch(b.button){case 0:u=1;break;case 2:u=-1}},!1);this.domElement.addEventListener("mouseup", function(b){b.preventDefault();b.stopPropagation();switch(b.button){case 0:u=0;break;case 2:u=0}},!1);this.domElement.addEventListener("keydown",function(b){switch(b.keyCode){case 38:case 87:u=1;break;case 37:case 65:t=-1;break;case 40:case 83:u=-1;break;case 39:case 68:t=1;break;case 81:m=!0;n=1;break;case 69:m=!0;n=-1;break;case 82:w=1;break;case 70:w=-1}},!1);this.domElement.addEventListener("keyup",function(b){switch(b.keyCode){case 38:case 87:u=0;break;case 37:case 65:t=0;break;case 40:case 83:u= 0;break;case 39:case 68:t=0;break;case 81:m=!1;break;case 69:m=!1;break;case 82:w=0;break;case 70:w=0}},!1)}; -THREE.TrackballControls=function(b,c){function e(b,e){return function(){e.apply(b,arguments)}}this.object=b;this.domElement=c!==void 0?c:document;this.screen={width:window.innerWidth,height:window.innerHeight,offsetLeft:0,offsetTop:0};this.radius=(this.screen.width+this.screen.height)/4;this.rotateSpeed=1;this.zoomSpeed=1.2;this.panSpeed=0.3;this.staticMoving=this.noPan=this.noZoom=!1;this.dynamicDampingFactor=0.2;this.minDistance=0;this.maxDistance=Infinity;this.keys=[65,83,68];this.target=new THREE.Vector3(0, -0,0);var f=!1,h=this.STATE.NONE,k=new THREE.Vector3,m=new THREE.Vector3,n=new THREE.Vector3,u=new THREE.Vector2,t=new THREE.Vector2,w=new THREE.Vector2,o=new THREE.Vector2;this.handleEvent=function(b){if(typeof this[b.type]=="function")this[b.type](b)};this.getMouseOnScreen=function(b,e){return new THREE.Vector2((b-this.screen.offsetLeft)/this.radius*0.5,(e-this.screen.offsetTop)/this.radius*0.5)};this.getMouseProjectionOnBall=function(b,e){var c=new THREE.Vector3((b-this.screen.width*0.5-this.screen.offsetLeft)/ -this.radius,(this.screen.height*0.5+this.screen.offsetTop-e)/this.radius,0),f=c.length();f>1?c.normalize():c.z=Math.sqrt(1-f*f);k.copy(this.object.position).subSelf(this.target);f=this.object.up.clone().setLength(c.y);f.addSelf(this.object.up.clone().crossSelf(k).setLength(c.x));f.addSelf(k.setLength(c.z));return f};this.rotateCamera=function(){var b=Math.acos(m.dot(n)/m.length()/n.length());if(b){var e=(new THREE.Vector3).cross(m,n).normalize(),c=new THREE.Quaternion;b*=this.rotateSpeed;c.setFromAxisAngle(e, --b);c.multiplyVector3(k);c.multiplyVector3(this.object.up);c.multiplyVector3(n);this.staticMoving?m=n:(c.setFromAxisAngle(e,b*(this.dynamicDampingFactor-1)),c.multiplyVector3(m))}};this.zoomCamera=function(){var b=1+(t.y-u.y)*this.zoomSpeed;b!==1&&b>0&&(k.multiplyScalar(b),this.staticMoving?u=t:u.y+=(t.y-u.y)*this.dynamicDampingFactor)};this.panCamera=function(){var b=o.clone().subSelf(w);if(b.lengthSq()){b.multiplyScalar(k.length()*this.panSpeed);var e=k.clone().crossSelf(this.object.up).setLength(b.x); -e.addSelf(this.object.up.clone().setLength(b.y));this.object.position.addSelf(e);this.target.addSelf(e);this.staticMoving?w=o:w.addSelf(b.sub(o,w).multiplyScalar(this.dynamicDampingFactor))}};this.checkDistances=function(){if(!this.noZoom||!this.noPan)this.object.position.lengthSq()>this.maxDistance*this.maxDistance&&this.object.position.setLength(this.maxDistance),k.lengthSq()1?e.normalize():e.z=Math.sqrt(1-f*f);k.copy(this.object.position).subSelf(this.target);f=this.object.up.clone().setLength(e.y);f.addSelf(this.object.up.clone().crossSelf(k).setLength(e.x));f.addSelf(k.setLength(e.z));return f};this.rotateCamera=function(){var b=Math.acos(m.dot(n)/m.length()/n.length());if(b){var c=(new THREE.Vector3).cross(m,n).normalize(),e=new THREE.Quaternion;b*=this.rotateSpeed;e.setFromAxisAngle(c, +-b);e.multiplyVector3(k);e.multiplyVector3(this.object.up);e.multiplyVector3(n);this.staticMoving?m=n:(e.setFromAxisAngle(c,b*(this.dynamicDampingFactor-1)),e.multiplyVector3(m))}};this.zoomCamera=function(){var b=1+(t.y-u.y)*this.zoomSpeed;b!==1&&b>0&&(k.multiplyScalar(b),this.staticMoving?u=t:u.y+=(t.y-u.y)*this.dynamicDampingFactor)};this.panCamera=function(){var b=o.clone().subSelf(w);if(b.lengthSq()){b.multiplyScalar(k.length()*this.panSpeed);var c=k.clone().crossSelf(this.object.up).setLength(b.x); +c.addSelf(this.object.up.clone().setLength(b.y));this.object.position.addSelf(c);this.target.addSelf(c);this.staticMoving?w=o:w.addSelf(b.sub(o,w).multiplyScalar(this.dynamicDampingFactor))}};this.checkDistances=function(){if(!this.noZoom||!this.noPan)this.object.position.lengthSq()>this.maxDistance*this.maxDistance&&this.object.position.setLength(this.maxDistance),k.lengthSq()0){this.vertices.push(new THREE.Vertex(new THREE.Vector3(0,-m,0)));for(n=0;nb&&(b+=Math.PI*2),anglec=(e+b)/2,new THREE.Vector2(-Math.cos(anglec),-Math.sin(anglec));return f.multiplyScalar(m).addSelf(n).subSelf(b).clone()}function h(b){for(H=b.length;--H>=0;){ka=H;na=H-1;na<0&&(na=b.length- -1);for(var e=0,c=v+w*2,e=0;eb&&(b+=Math.PI*2),anglec=(c+b)/2,new THREE.Vector2(-Math.cos(anglec),-Math.sin(anglec));return f.multiplyScalar(m).addSelf(n).subSelf(b).clone()}function h(b){for(H=b.length;--H>=0;){ka=H;na=H-1;na<0&&(na=b.length- +1);for(var c=0,e=v+w*2,c=0;c=0;Q--){Z=Q/w;$=u*(1-Z);Z=t*Math.sin(Z*Math.PI/2);H=0;for(T=F.length;H0;)this.smooth(b)}; -THREE.SubdivisionModifier.prototype.smooth=function(b){function c(b,e,c,f,n,t){var u=new THREE.Face4(b,e,c,f,null,n.color,n.material);if(m.useOldVertexColors){u.vertexColors=[];for(var v,p,w,x=0;x<4;x++){w=t[x];v=new THREE.Color;v.setRGB(0,0,0);for(var y=0;y>7)-127;f|=(h&127)<<16|k<<8;if(f==0&&n==-127)return 0;return(1-2*(m>>7))*(1+f*Math.pow(2,-23))*Math.pow(2,n)}function h(b,e){var c=w(b,e),f=w(b,e+1),k=w(b,e+2);return(w(b,e+3)<<24)+(k<<16)+(f<<8)+c}function u(b,e){var c=w(b,e);return(w(b,e+1)<<8)+c}function t(b,e){var c=w(b,e);return c>127?c-256:c}function w(b,e){return b.charCodeAt(e)&255}function o(e){var c, -f,k;c=h(b,e);f=h(b,e+M);k=h(b,e+K);e=u(b,e+B);E.faces.push(new THREE.Face3(c,f,k,null,null,E.materials[e]))}function x(e){var c,f,k,m,o,p;c=h(b,e);f=h(b,e+M);k=h(b,e+K);m=u(b,e+B);o=h(b,e+L);p=h(b,e+Y);e=h(b,e+H);m=E.materials[m];var t=G[p*3],v=G[p*3+1];p=G[p*3+2];var w=G[e*3],x=G[e*3+1],e=G[e*3+2];E.faces.push(new THREE.Face3(c,f,k,[new THREE.Vector3(G[o*3],G[o*3+1],G[o*3+2]),new THREE.Vector3(t,v,p),new THREE.Vector3(w,x,e)],null,m))}function v(e){var c,f,k,m;c=h(b,e);f=h(b,e+T);k=h(b,e+Q);m=h(b, -e+Z);e=u(b,e+$);E.faces.push(new THREE.Face4(c,f,k,m,null,null,E.materials[e]))}function z(e){var c,f,k,m,o,t,v,w;c=h(b,e);f=h(b,e+T);k=h(b,e+Q);m=h(b,e+Z);o=u(b,e+$);t=h(b,e+P);v=h(b,e+p);w=h(b,e+V);e=h(b,e+fa);o=E.materials[o];var x=G[v*3],y=G[v*3+1];v=G[v*3+2];var S=G[w*3],A=G[w*3+1];w=G[w*3+2];var z=G[e*3],B=G[e*3+1],e=G[e*3+2];E.faces.push(new THREE.Face4(c,f,k,m,[new THREE.Vector3(G[t*3],G[t*3+1],G[t*3+2]),new THREE.Vector3(x,y,v),new THREE.Vector3(S,A,w),new THREE.Vector3(z,B,e)],null,o))} -function A(e){var c,f,k,m;c=h(b,e);f=h(b,e+ea);k=h(b,e+ha);e=J[c*2];m=J[c*2+1];c=J[f*2];var o=E.faceVertexUvs[0];f=J[f*2+1];var p=J[k*2];k=J[k*2+1];var t=[];t.push(new THREE.UV(e,m));t.push(new THREE.UV(c,f));t.push(new THREE.UV(p,k));o.push(t)}function y(e){var c,f,k,m,o,p;c=h(b,e);f=h(b,e+ga);k=h(b,e+ka);m=h(b,e+na);e=J[c*2];o=J[c*2+1];c=J[f*2];p=J[f*2+1];f=J[k*2];var t=E.faceVertexUvs[0];k=J[k*2+1];var u=J[m*2];m=J[m*2+1];var v=[];v.push(new THREE.UV(e,o));v.push(new THREE.UV(c,p));v.push(new THREE.UV(f, -k));v.push(new THREE.UV(u,m));t.push(v)}var E=this,F=0,C,G=[],J=[],M,K,B,L,Y,H,T,Q,Z,$,P,p,V,fa,ea,ha,ga,ka,na,aa,W,U,ia,ja,ta;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(E,f,e);C={signature:b.substr(F,8),header_bytes:w(b,F+8),vertex_coordinate_bytes:w(b,F+9),normal_coordinate_bytes:w(b,F+10),uv_coordinate_bytes:w(b,F+11),vertex_index_bytes:w(b,F+12),normal_index_bytes:w(b,F+13),uv_index_bytes:w(b,F+14),material_index_bytes:w(b,F+15),nvertices:h(b,F+16),nnormals:h(b,F+16+4),nuvs:h(b, +THREE.BinaryLoader.prototype.createBinModel=function(b,c,e,f){var h=function(c){function e(b,c){var f=w(b,c),k=w(b,c+1),h=w(b,c+2),m=w(b,c+3),n=(m<<1&255|h>>7)-127;f|=(h&127)<<16|k<<8;if(f==0&&n==-127)return 0;return(1-2*(m>>7))*(1+f*Math.pow(2,-23))*Math.pow(2,n)}function h(b,c){var e=w(b,c),f=w(b,c+1),k=w(b,c+2);return(w(b,c+3)<<24)+(k<<16)+(f<<8)+e}function u(b,c){var e=w(b,c);return(w(b,c+1)<<8)+e}function t(b,c){var e=w(b,c);return e>127?e-256:e}function w(b,c){return b.charCodeAt(c)&255}function o(c){var e, +f,k;e=h(b,c);f=h(b,c+M);k=h(b,c+K);c=u(b,c+B);E.faces.push(new THREE.Face3(e,f,k,null,null,E.materials[c]))}function x(c){var e,f,k,m,o,p;e=h(b,c);f=h(b,c+M);k=h(b,c+K);m=u(b,c+B);o=h(b,c+L);p=h(b,c+Y);c=h(b,c+H);m=E.materials[m];var t=G[p*3],v=G[p*3+1];p=G[p*3+2];var w=G[c*3],x=G[c*3+1],c=G[c*3+2];E.faces.push(new THREE.Face3(e,f,k,[new THREE.Vector3(G[o*3],G[o*3+1],G[o*3+2]),new THREE.Vector3(t,v,p),new THREE.Vector3(w,x,c)],null,m))}function v(c){var e,f,k,m;e=h(b,c);f=h(b,c+T);k=h(b,c+Q);m=h(b, +c+Z);c=u(b,c+$);E.faces.push(new THREE.Face4(e,f,k,m,null,null,E.materials[c]))}function z(c){var e,f,k,m,o,t,v,w;e=h(b,c);f=h(b,c+T);k=h(b,c+Q);m=h(b,c+Z);o=u(b,c+$);t=h(b,c+P);v=h(b,c+p);w=h(b,c+V);c=h(b,c+fa);o=E.materials[o];var x=G[v*3],y=G[v*3+1];v=G[v*3+2];var S=G[w*3],A=G[w*3+1];w=G[w*3+2];var z=G[c*3],B=G[c*3+1],c=G[c*3+2];E.faces.push(new THREE.Face4(e,f,k,m,[new THREE.Vector3(G[t*3],G[t*3+1],G[t*3+2]),new THREE.Vector3(x,y,v),new THREE.Vector3(S,A,w),new THREE.Vector3(z,B,c)],null,o))} +function A(c){var e,f,k,m;e=h(b,c);f=h(b,c+ea);k=h(b,c+ha);c=J[e*2];m=J[e*2+1];e=J[f*2];var o=E.faceVertexUvs[0];f=J[f*2+1];var p=J[k*2];k=J[k*2+1];var t=[];t.push(new THREE.UV(c,m));t.push(new THREE.UV(e,f));t.push(new THREE.UV(p,k));o.push(t)}function y(c){var e,f,k,m,o,p;e=h(b,c);f=h(b,c+ga);k=h(b,c+ka);m=h(b,c+na);c=J[e*2];o=J[e*2+1];e=J[f*2];p=J[f*2+1];f=J[k*2];var t=E.faceVertexUvs[0];k=J[k*2+1];var u=J[m*2];m=J[m*2+1];var v=[];v.push(new THREE.UV(c,o));v.push(new THREE.UV(e,p));v.push(new THREE.UV(f, +k));v.push(new THREE.UV(u,m));t.push(v)}var E=this,F=0,C,G=[],J=[],M,K,B,L,Y,H,T,Q,Z,$,P,p,V,fa,ea,ha,ga,ka,na,aa,W,U,ia,ja,ta;THREE.Geometry.call(this);THREE.Loader.prototype.init_materials(E,f,c);C={signature:b.substr(F,8),header_bytes:w(b,F+8),vertex_coordinate_bytes:w(b,F+9),normal_coordinate_bytes:w(b,F+10),uv_coordinate_bytes:w(b,F+11),vertex_index_bytes:w(b,F+12),normal_index_bytes:w(b,F+13),uv_index_bytes:w(b,F+14),material_index_bytes:w(b,F+15),nvertices:h(b,F+16),nnormals:h(b,F+16+4),nuvs:h(b, F+16+8),ntri_flat:h(b,F+16+12),ntri_smooth:h(b,F+16+16),ntri_flat_uv:h(b,F+16+20),ntri_smooth_uv:h(b,F+16+24),nquad_flat:h(b,F+16+28),nquad_smooth:h(b,F+16+32),nquad_flat_uv:h(b,F+16+36),nquad_smooth_uv:h(b,F+16+40)};F+=C.header_bytes;M=C.vertex_index_bytes;K=C.vertex_index_bytes*2;B=C.vertex_index_bytes*3;L=C.vertex_index_bytes*3+C.material_index_bytes;Y=C.vertex_index_bytes*3+C.material_index_bytes+C.normal_index_bytes;H=C.vertex_index_bytes*3+C.material_index_bytes+C.normal_index_bytes*2;T=C.vertex_index_bytes; -Q=C.vertex_index_bytes*2;Z=C.vertex_index_bytes*3;$=C.vertex_index_bytes*4;P=C.vertex_index_bytes*4+C.material_index_bytes;p=C.vertex_index_bytes*4+C.material_index_bytes+C.normal_index_bytes;V=C.vertex_index_bytes*4+C.material_index_bytes+C.normal_index_bytes*2;fa=C.vertex_index_bytes*4+C.material_index_bytes+C.normal_index_bytes*3;ea=C.uv_index_bytes;ha=C.uv_index_bytes*2;ga=C.uv_index_bytes;ka=C.uv_index_bytes*2;na=C.uv_index_bytes*3;e=C.vertex_index_bytes*3+C.material_index_bytes;ta=C.vertex_index_bytes* -4+C.material_index_bytes;aa=C.ntri_flat*e;W=C.ntri_smooth*(e+C.normal_index_bytes*3);U=C.ntri_flat_uv*(e+C.uv_index_bytes*3);ia=C.ntri_smooth_uv*(e+C.normal_index_bytes*3+C.uv_index_bytes*3);ja=C.nquad_flat*ta;e=C.nquad_smooth*(ta+C.normal_index_bytes*4);ta=C.nquad_flat_uv*(ta+C.uv_index_bytes*4);F+=function(e){for(var f,k,h,n=C.vertex_coordinate_bytes*3,o=e+C.nvertices*n;e=0){y=o.invBindMatrices[v];p.invBindMatrix=y;p.skinningMatrix=new THREE.Matrix4;p.skinningMatrix.multiply(p.world,y);p.weights=[];for(y=0;y1){o=new THREE.MeshFaceMaterial;for(j=0;j1){o=new THREE.MeshFaceMaterial;for(j=0;j1?c[1].substr(0,e):"0";c[1].length=0,m=k.indexOf("(")>=0,n;if(h)f=k.split("."),k=f.shift(),f.shift();else if(m){n=k.split("(");k=n.shift(); -for(f=0;fe){u=t.output[p];break}m=u!==void 0?u instanceof THREE.Matrix4? -m.multiply(m,u):m.multiply(m,n.matrix):m.multiply(m,n.matrix)}else m=m.multiply(m,n.matrix);e=m;c.push({time:b,pos:[e.n14,e.n24,e.n34],rotq:[0,0,0,1],scl:[1,1,1]})}this.keys=c}this.updateMatrix();return this};o.prototype.updateMatrix=function(){this.matrix.identity();for(var b=0;b1?e[1].substr(0,c):"0";e[1].length=0,m=k.indexOf("(")>=0,n;if(h)f=k.split("."),k=f.shift(),f.shift();else if(m){n=k.split("(");k=n.shift(); +for(f=0;fc){u=t.output[p];break}m=u!==void 0?u instanceof THREE.Matrix4? +m.multiply(m,u):m.multiply(m,n.matrix):m.multiply(m,n.matrix)}else m=m.multiply(m,n.matrix);c=m;e.push({time:b,pos:[c.n14,c.n24,c.n34],rotq:[0,0,0,1],scl:[1,1,1]})}this.keys=e}this.updateMatrix();return this};o.prototype.updateMatrix=function(){this.matrix.identity();for(var b=0;b0&&(this[c.nodeName]=parseFloat(f[0].textContent))}}this.create();return this};Y.prototype.create=function(){var b={},e=this.transparency!==void 0&&this.transparency<1,c;for(c in this)switch(c){case "ambient":case "emission":case "diffuse":case "specular":var f=this[c];if(f instanceof L)if(f.isTexture()){if(this.effect.sampler&&this.effect.surface&&this.effect.sampler.source==this.effect.surface.sid&&(f=la[this.effect.surface.init_from]))b.map=THREE.ImageUtils.loadTexture(Ga+f.init_from), -b.map.wrapS=THREE.RepeatWrapping,b.map.wrapT=THREE.RepeatWrapping,b.map.repeat.x=1,b.map.repeat.y=-1}else c=="diffuse"?b.color=f.color.getHex():e||(b[c]=f.color.getHex());break;case "shininess":case "reflectivity":b[c]=this[c];break;case "transparency":if(e)b.transparent=!0,b.opacity=this[c],e=!0}b.shading=za;return this.material=new THREE.MeshLambertMaterial(b)};H.prototype.parse=function(b){for(var e=0;e=0,f=b.indexOf("(")>=0,k,h;if(c)e=b.split("."),b=e.shift(),h=e.shift();else if(f){k=b.split("(");b=k.shift();for(e=0;e0&&(this[e.nodeName]=parseFloat(f[0].textContent))}}this.create();return this};Y.prototype.create=function(){var b={},c=this.transparency!==void 0&&this.transparency<1,e;for(e in this)switch(e){case "ambient":case "emission":case "diffuse":case "specular":var f=this[e];if(f instanceof L)if(f.isTexture()){if(this.effect.sampler&&this.effect.surface&&this.effect.sampler.source==this.effect.surface.sid&&(f=la[this.effect.surface.init_from]))b.map=THREE.ImageUtils.loadTexture(Ga+f.init_from), +b.map.wrapS=THREE.RepeatWrapping,b.map.wrapT=THREE.RepeatWrapping,b.map.repeat.x=1,b.map.repeat.y=-1}else e=="diffuse"?b.color=f.color.getHex():c||(b[e]=f.color.getHex());break;case "shininess":case "reflectivity":b[e]=this[e];break;case "transparency":if(c)b.transparent=!0,b.opacity=this[e],c=!0}b.shading=za;return this.material=new THREE.MeshLambertMaterial(b)};H.prototype.parse=function(b){for(var c=0;c=0,f=b.indexOf("(")>=0,k,h;if(e)c=b.split("."),b=c.shift(),h=c.shift();else if(f){k=b.split("(");b=k.shift();for(c=0;c1&&(Y=[new THREE.MeshFaceMaterial]);object=new THREE.Mesh(M,Y);object.name=v;object.position.set(C[0],C[1],C[2]);q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]);object.scale.set(s[0],s[1],s[2]);object.visible=F.visible;V.scene.add(object);V.objects[v]=object;F.meshCollider&&(b=THREE.CollisionUtils.MeshColliderWBox(object),V.scene.collisions.colliders.push(b)); if(F.castsShadow)b=new THREE.ShadowVolume(M),V.scene.add(b),b.position=object.position,b.rotation=object.rotation,b.scale=object.scale;F.trigger&&F.trigger.toLowerCase()!="none"&&(b={type:F.trigger,object:F},V.triggers[object.name]=b)}}else C=F.position,r=F.rotation,q=F.quaternion,s=F.scale,q=0,object=new THREE.Object3D,object.name=v,object.position.set(C[0],C[1],C[2]),q?(object.quaternion.set(q[0],q[1],q[2],q[3]),object.useQuaternion=!0):object.rotation.set(r[0],r[1],r[2]),object.scale.set(s[0], -s[1],s[2]),object.visible=F.visible!==void 0?F.visible:!1,V.scene.add(object),V.objects[v]=object,V.empties[v]=object,F.trigger&&F.trigger.toLowerCase()!="none"&&(b={type:F.trigger,object:F},V.triggers[object.name]=b)}function u(b){return function(c){V.geometries[b]=c;n();Z-=1;e.onLoadComplete();w()}}function t(b){return function(e){V.geometries[b]=e}}function w(){e.callbackProgress({totalModels:P,totalTextures:p,loadedModels:P-Z,loadedTextures:p-$},V);e.onLoadProgress();Z==0&&$==0&&c(V)}var o,x, +s[1],s[2]),object.visible=F.visible!==void 0?F.visible:!1,V.scene.add(object),V.objects[v]=object,V.empties[v]=object,F.trigger&&F.trigger.toLowerCase()!="none"&&(b={type:F.trigger,object:F},V.triggers[object.name]=b)}function u(b){return function(c){V.geometries[b]=c;n();Z-=1;e.onLoadComplete();w()}}function t(b){return function(c){V.geometries[b]=c}}function w(){e.callbackProgress({totalModels:P,totalTextures:p,loadedModels:P-Z,loadedTextures:p-$},V);e.onLoadProgress();Z==0&&$==0&&c(V)}var o,x, v,z,A,y,E,F,C,G,J,M,K,B,L,Y,H,T,Q,Z,$,P,p,V;T=b.data;L=new THREE.BinaryLoader;Q=new THREE.JSONLoader;$=Z=0;V={scene:new THREE.Scene,geometries:{},materials:{},textures:{},objects:{},cameras:{},lights:{},fogs:{},triggers:{},empties:{}};b=!1;for(v in T.objects)if(F=T.objects[v],F.meshCollider){b=!0;break}if(b)V.scene.collisions=new THREE.CollisionSystem;if(T.transform){b=T.transform.position;G=T.transform.rotation;var fa=T.transform.scale;b&&V.scene.position.set(b[0],b[1],b[2]);G&&V.scene.rotation.set(G[0], G[1],G[2]);fa&&V.scene.scale.set(fa[0],fa[1],fa[2]);(b||G||fa)&&V.scene.updateMatrix()}b=function(){$-=1;w();e.onLoadComplete()};for(A in T.cameras)G=T.cameras[A],G.type=="perspective"?K=new THREE.PerspectiveCamera(G.fov,G.aspect,G.near,G.far):G.type=="ortho"&&(K=new THREE.OrthographicCamera(G.left,G.right,G.top,G.bottom,G.near,G.far)),C=G.position,G=G.target,K.position.set(C[0],C[1],C[2]),K.target=new THREE.Vector3(G[0],G[1],G[2]),V.cameras[A]=K;for(z in T.lights)A=T.lights[z],K=A.color!==void 0? A.color:16777215,G=A.intensity!==void 0?A.intensity:1,A.type=="directional"?(C=A.direction,H=new THREE.DirectionalLight(K,G),H.position.set(C[0],C[1],C[2]),H.position.normalize()):A.type=="point"?(C=A.position,d=A.distance,H=new THREE.PointLight(K,G,d),H.position.set(C[0],C[1],C[2])):A.type=="ambient"&&(H=new THREE.AmbientLight(K)),V.scene.add(H),V.lights[z]=H;for(y in T.fogs)z=T.fogs[y],z.type=="linear"?B=new THREE.Fog(0,z.near,z.far):z.type=="exp2"&&(B=new THREE.FogExp2(0,z.density)),G=z.color, @@ -645,8 +648,8 @@ V.textures[E.parameters.specularMap],b.enableSpecular.value=!0;b.uDiffuseColor.v THREE.UTF8Loader.prototype=new THREE.UTF8Loader;THREE.UTF8Loader.prototype.constructor=THREE.UTF8Loader; THREE.UTF8Loader.prototype.load=function(b){var c=new XMLHttpRequest,e=b.model,f=b.callback,h=b.scale!==void 0?b.scale:1,k=b.offsetX!==void 0?b.offsetX:0,m=b.offsetY!==void 0?b.offsetY:0,n=b.offsetZ!==void 0?b.offsetZ:0;c.onreadystatechange=function(){c.readyState==4?c.status==200||c.status==0?THREE.UTF8Loader.prototype.createModel(c.responseText,f,h,k,m,n):alert("Couldn't load ["+e+"] ["+c.status+"]"):c.readyState!=3&&c.readyState==2&&c.getResponseHeader("Content-Length")};c.open("GET",e,!0);c.send(null)}; THREE.UTF8Loader.prototype.decompressMesh=function(b){var c=b.charCodeAt(0);c>=57344&&(c-=2048);c++;for(var e=new Float32Array(8*c),f=1,h=0;h<8;h++){for(var k=0,m=0;m>1^-(n&1);e[8*m+h]=k}f+=c}c=b.length-f;k=new Uint16Array(c);for(h=m=0;hc?c:a},mapLinear:function(a,b,c,e,f){return(a-b)*(f-e)/(c-b)+e}};THREE.SceneUtils={showHierarchy:function(a,b){THREE.SceneUtils.traverseHierarchy(a,function(a){a.visible=b})},traverseHierarchy:function(a,b){var c,e,f=a.children.length;for(e=0;e 0\nu color_pars_fragment:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_fragment:"#ifdef USE_COLOR\ngl_FragColor = gl_FragColor * vec4( vColor, opacity );\n#endif",color_pars_vertex:"#ifdef USE_COLOR\nvarying vec3 vColor;\n#endif",color_vertex:"#ifdef USE_COLOR\n#ifdef GAMMA_INPUT\nvColor = color * color;\n#else\nvColor = color;\n#endif\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\nuniform mat4 boneGlobalMatrices[ MAX_BONES ];\n#endif",skinning_vertex:"#ifdef USE_SKINNING\ngl_Position = ( boneGlobalMatrices[ int( skinIndex.x ) ] * skinVertexA ) * skinWeight.x;\ngl_Position += ( boneGlobalMatrices[ int( skinIndex.y ) ] * skinVertexB ) * skinWeight.y;\ngl_Position = projectionMatrix * viewMatrix * objectMatrix * gl_Position;\n#endif", morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\nuniform float morphTargetInfluences[ 8 ];\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\nvec3 morphed = vec3( 0.0, 0.0, 0.0 );\nmorphed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];\nmorphed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];\nmorphed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];\nmorphed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];\nmorphed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];\nmorphed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];\nmorphed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];\nmorphed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];\nmorphed += position;\ngl_Position = projectionMatrix * modelViewMatrix * vec4( morphed, 1.0 );\n#endif", default_vertex:"#ifndef USE_MORPHTARGETS\n#ifndef USE_SKINNING\ngl_Position = projectionMatrix * mvPosition;\n#endif\n#endif",shadowmap_pars_fragment:"#ifdef USE_SHADOWMAP\nuniform sampler2D shadowMap[ MAX_SHADOWS ];\nuniform float shadowDarkness;\nuniform float shadowBias;\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nfloat unpackDepth( const in vec4 rgba_depth ) {\nconst vec4 bit_shift = vec4( 1.0 / ( 256.0 * 256.0 * 256.0 ), 1.0 / ( 256.0 * 256.0 ), 1.0 / 256.0, 1.0 );\nfloat depth = dot( rgba_depth, bit_shift );\nreturn depth;\n}\n#endif", -shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_SOFT\nconst float xPixelOffset = 1.0 / SHADOWMAP_WIDTH;\nconst float yPixelOffset = 1.0 / SHADOWMAP_HEIGHT;\n#endif\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nshadowCoord.z += shadowBias;\nif ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nfor ( float y = -1.25; y <= 1.25; y += 1.25 )\nfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\nvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadow += 1.0;\n}\nshadow /= 9.0;\n#ifdef GAMMA_OUTPUT\nvec3 darkening = vec3( ( 1.0 - shadowDarkness * shadow ) );\ndarkening *= darkening;\nshadowColor = shadowColor * darkening;\n#else\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );\n#endif\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( shadowDarkness );\n#endif\n}\n}\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", +shadowmap_fragment:"#ifdef USE_SHADOWMAP\n#ifdef SHADOWMAP_SOFT\nconst float xPixelOffset = 1.0 / SHADOWMAP_WIDTH;\nconst float yPixelOffset = 1.0 / SHADOWMAP_HEIGHT;\n#endif\nvec3 shadowColor = vec3( 1.0 );\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvec3 shadowCoord = vShadowCoord[ i ].xyz / vShadowCoord[ i ].w;\nshadowCoord.z += shadowBias;\nif ( shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0 ) {\n#ifdef SHADOWMAP_SOFT\nfloat shadow = 0.0;\nfor ( float y = -1.25; y <= 1.25; y += 1.25 )\nfor ( float x = -1.25; x <= 1.25; x += 1.25 ) {\nvec4 rgbaDepth = texture2D( shadowMap[ i ], vec2( x * xPixelOffset, y * yPixelOffset ) + shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadow += 1.0;\n}\nshadow /= 9.0;\nshadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );\n#else\nvec4 rgbaDepth = texture2D( shadowMap[ i ], shadowCoord.xy );\nfloat fDepth = unpackDepth( rgbaDepth );\nif ( fDepth < shadowCoord.z )\nshadowColor = shadowColor * vec3( shadowDarkness );\n#endif\n}\n}\n#ifdef GAMMA_OUTPUT\nshadowColor *= shadowColor;\n#endif\ngl_FragColor.xyz = gl_FragColor.xyz * shadowColor;\n#endif", shadowmap_pars_vertex:"#ifdef USE_SHADOWMAP\nvarying vec4 vShadowCoord[ MAX_SHADOWS ];\nuniform mat4 shadowMatrix[ MAX_SHADOWS ];\n#endif",shadowmap_vertex:"#ifdef USE_SHADOWMAP\nfor( int i = 0; i < MAX_SHADOWS; i ++ ) {\nvShadowCoord[ i ] = shadowMatrix[ i ] * objectMatrix * vec4( position, 1.0 );\n}\n#endif",alphatest_fragment:"#ifdef ALPHATEST\nif ( gl_FragColor.a < ALPHATEST ) discard;\n#endif",linear_to_gamma_fragment:"#ifdef GAMMA_OUTPUT\ngl_FragColor.xyz = sqrt( gl_FragColor.xyz );\n#endif"}; THREE.UniformsUtils={merge:function(b){var c,e,d,h={};for(c=0;c + @@ -110,6 +111,7 @@ + @@ -190,6 +192,14 @@ var sunLight, pointLight, ambientLight; + var morph; + + var composer, effectFXAA, hblur, vblur; + + var parameters, tweenDirection, tweenDay, tweenNight; + + var oldTime; + init(); animate(); @@ -368,6 +378,31 @@ addObjectColor( new THREE.SphereGeometry( 100, 32, 26 ), 0xffffff, -300, 100, 300, 0 ); + // MORPHS + + var loader = new THREE.JSONLoader(); + + loader.load( "models/animated/sittingBox.js", function( geometry ) { + + var morphMaterial = new THREE.MeshPhongMaterial( { ambient: 0x444444, color: 0x000000, specular: 0xff9900, shininess: 50, morphTargets: true } ); + morphMaterial.shading = THREE.FlatShading; + + //geometry.computeVertexNormals(); + morph = new THREE.MorphAnimMesh( geometry, morphMaterial ); + + var s = 200; + morph.scale.set( s, s, s ); + + morph.duration = 8000; + morph.mirroredLoop = true; + + morph.castShadow = true; + morph.receiveShadow = true; + + scene.add( morph ); + + } ); + // LIGHTS var sunIntensity = 0.3, @@ -485,7 +520,7 @@ parameters = { control: 0 }; - direction = -1; + tweenDirection = -1; tweenDay = new TWEEN.Tween( parameters ).to( { control: 100 }, 1000 ).easing( TWEEN.Easing.Exponential.EaseOut ); tweenNight = new TWEEN.Tween( parameters ).to( { control: 0 }, 1000 ).easing( TWEEN.Easing.Exponential.EaseOut ); @@ -522,35 +557,26 @@ switch( event.keyCode ) { - case 78: /*N*/ if ( direction == 1 ) { + case 78: /*N*/ if ( tweenDirection == 1 ) { tweenDay.stop(); tweenNight.start(); - direction = -1; + tweenDirection = -1; } else { tweenNight.stop(); tweenDay.start(); - direction = 1; + tweenDirection = 1; } break; } - }; - - // - - function map_linear( x, sa, sb, ea, eb ) { - - return ( x - sa ) * ( eb - ea ) / ( sb - sa ) + ea; - - }; - + } // @@ -565,16 +591,24 @@ function render() { + if ( oldTime === undefined ) oldTime = new Date().getTime(); + + var newTime = new Date().getTime(); + var delta = newTime - oldTime; + oldTime = newTime; + TWEEN.update(); controls.update(); - scene.fog.color.setHSV( 0.13, 0.25, map_linear( parameters.control, 0, 100, 0.1, 0.99 ) ); + if ( morph ) morph.updateAnimation( delta ); + + scene.fog.color.setHSV( 0.13, 0.25, THREE.MathUtils.mapLinear( parameters.control, 0, 100, 0.1, 0.99 ) ); renderer.setClearColor( scene.fog.color, 1 ); - sunLight.intensity = map_linear( parameters.control, 0, 100, 0.3, 1 ); - pointLight.intensity = map_linear( parameters.control, 0, 100, 1, 0.5 ); + sunLight.intensity = THREE.MathUtils.mapLinear( parameters.control, 0, 100, 0.3, 1 ); + pointLight.intensity = THREE.MathUtils.mapLinear( parameters.control, 0, 100, 1, 0.5 ); - pointLight.color.setHSV( 0.1, map_linear( parameters.control, 0, 100, 0.99, 0 ), 0.9 ); + pointLight.color.setHSV( 0.1, THREE.MathUtils.mapLinear( parameters.control, 0, 100, 0.99, 0 ), 0.9 ); renderer.shadowMapDarkness = 0.5 * sunLight.intensity; diff --git a/src/extras/MathUtils.js b/src/extras/MathUtils.js new file mode 100644 index 00000000..03db5ff0 --- /dev/null +++ b/src/extras/MathUtils.js @@ -0,0 +1,19 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.MathUtils = { + + clamp: function ( x, a, b ) { + + return ( x < a ) ? a : ( ( x > b ) ? b : x ); + + }, + + mapLinear: function( x, sa, sb, ea, eb ) { + + return ( x - sa ) * ( eb - ea ) / ( sb - sa ) + ea; + + } + +}; diff --git a/src/objects/MorphAnimMesh.js b/src/objects/MorphAnimMesh.js new file mode 100644 index 00000000..e6f6409a --- /dev/null +++ b/src/objects/MorphAnimMesh.js @@ -0,0 +1,89 @@ +/** + * @author alteredq / http://alteredqualia.com/ + */ + +THREE.MorphAnimMesh = function( geometry, materials ) { + + THREE.Mesh.call( this, geometry, materials ); + + // API + + this.duration = 1000; // milliseconds + this.mirroredLoop = false; + + // internals + + this.lastKeyframe = 0; + this.currentKeyframe = 0; + + this.time = 0; + this.offset = 0; + + this.direction = 1; + this.directionBackwards = false; + +}; + +THREE.MorphAnimMesh.prototype = new THREE.Mesh(); +THREE.MorphAnimMesh.prototype.constructor = THREE.MorphAnimMesh; + +THREE.MorphAnimMesh.prototype.updateAnimation = function ( delta ) { + + var frameTime = this.duration / this.geometry.morphTargets.length; + + this.time += this.direction * delta; + + if ( this.mirroredLoop ) { + + if ( this.time > this.duration || this.time < 0 ) { + + this.direction *= -1; + + if ( this.time > this.duration ) { + + this.time = this.duration; + this.directionBackwards = true; + + } + + if ( this.time < 0 ) { + + this.time = 0; + this.directionBackwards = false; + + } + + } + + } else { + + this.time = this.time % this.duration; + + } + + var keyframe = THREE.MathUtils.clamp( Math.floor( this.time / frameTime ), 0, this.geometry.morphTargets.length - 1 ); + + if ( keyframe != this.currentKeyframe ) { + + this.morphTargetInfluences[ this.lastKeyframe ] = 0; + this.morphTargetInfluences[ this.currentKeyframe ] = 1; + + this.morphTargetInfluences[ keyframe ] = 0; + + this.lastKeyframe = this.currentKeyframe; + this.currentKeyframe = keyframe; + + } + + var mix = ( this.time % frameTime ) / frameTime; + + if ( this.directionBackwards ) { + + mix = 1 - mix; + + } + + this.morphTargetInfluences[ this.currentKeyframe ] = mix; + this.morphTargetInfluences[ this.lastKeyframe ] = 1 - mix; + +}; diff --git a/src/renderers/WebGLShaders.js b/src/renderers/WebGLShaders.js index e242b898..b355e82b 100644 --- a/src/renderers/WebGLShaders.js +++ b/src/renderers/WebGLShaders.js @@ -702,19 +702,7 @@ THREE.ShaderChunk = { "}", "shadow /= 9.0;", - - "#ifdef GAMMA_OUTPUT", - - "vec3 darkening = vec3( ( 1.0 - shadowDarkness * shadow ) );", - "darkening *= darkening;", - - "shadowColor = shadowColor * darkening;", - - "#else", - - "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );", - - "#endif", + "shadowColor = shadowColor * vec3( ( 1.0 - shadowDarkness * shadow ) );", "#else", @@ -742,6 +730,12 @@ THREE.ShaderChunk = { "}", + "#ifdef GAMMA_OUTPUT", + + "shadowColor *= shadowColor;", + + "#endif", + "gl_FragColor.xyz = gl_FragColor.xyz * shadowColor;", "#endif" diff --git a/utils/build.py b/utils/build.py index f0398d34..fe3cd837 100644 --- a/utils/build.py +++ b/utils/build.py @@ -60,6 +60,7 @@ COMMON_FILES = [ 'objects/Mesh.js', 'objects/Bone.js', 'objects/SkinnedMesh.js', +'objects/MorphAnimMesh.js', 'objects/Ribbon.js', 'objects/LOD.js', 'objects/Sprite.js', @@ -85,6 +86,7 @@ EXTRAS_FILES = [ 'extras/ColorUtils.js', 'extras/GeometryUtils.js', 'extras/ImageUtils.js', +'extras/MathUtils.js', 'extras/SceneUtils.js', 'extras/ShaderUtils.js', 'extras/core/Curve.js',