From 7a83cba2f05d6b14c61bc0389e9a7b04a0c6d441 Mon Sep 17 00:00:00 2001 From: yomotsu Date: Sun, 1 Nov 2015 18:47:45 +0900 Subject: [PATCH] support threejs r73 --- build/meshwalk.TPS.js | 204 +- build/meshwalk.TPS.min.js | 2 +- build/meshwalk.js | 13 +- build/meshwalk.min.js | 2 +- example/1_getstarted.html | 9 +- example/2_keyboardInput.html | 19 +- example/3_cameraControl.html | 23 +- example/4_objects.html | 19 +- example/5_terrain.html | 19 +- example/6_animationController.html | 27 +- example/7_conclusion.html | 29 +- example/model/miku.json | 6634 ++++++++++++++++++++++++++++ example/model/miku.png | Bin 0 -> 2245 bytes lib/three.min.js | 1613 +++---- src/TPS/AnimationController.js | 113 +- src/TPS/KeyInputControl.js | 72 +- src/core/Octree.js | 12 +- 17 files changed, 7869 insertions(+), 941 deletions(-) create mode 100644 example/model/miku.json create mode 100644 example/model/miku.png diff --git a/build/meshwalk.TPS.js b/build/meshwalk.TPS.js index a0e15d7..3ebb84d 100644 --- a/build/meshwalk.TPS.js +++ b/build/meshwalk.TPS.js @@ -520,44 +520,123 @@ // @author yomotsu // MIT License - MW.AnimationController = function ( mesh ) { - this.mesh = mesh; + this.mesh = mesh; this.motion = {}; + this.mixer = new THREE.AnimationMixer( mesh ); + this.currentMotionName = ''; + var i, l, anim; for ( i = 0, l = this.mesh.geometry.animations.length; i < l; i ++ ) { anim = this.mesh.geometry.animations[ i ]; + this.motion[ anim.name ] = new THREE.AnimationAction( anim ); + this.motion[ anim.name ].weight = 0; + this.mixer.addAction( this.motion[ anim.name ] ); + + } + +}; + +MW.AnimationController.prototype = { + + play: function ( name ) { + + if ( this.motion[ this.currentMotionName ] ) { + + this.mixer.crossFade( + this.motion[ this.currentMotionName ], + this.motion[ name ], + .3 + ); + + } else { + + this.mixer.fadeIn( this.motion[ name ], .3 ); + + } + + this.currentMotionName = name; + + }, + + turn: function () { + + var DURATION = 200; + var TAU = 2 * Math.PI; + + var mod = function ( a, n ) { return ( a % n + n ) % n; } - this.motion[ anim.name ] = { + var getDeltaAngle = function ( current, target ) { - anim: new THREE.Animation( - mesh, - anim, - THREE.AnimationHandler.CATMULLROM - ), + var a = mod( ( current - target ), TAU ); + var b = mod( ( target - current ), TAU ); - duration: anim.length * 1000 + return a < b ? -a : b; }; - } + return function ( rad, immediate ) { -}; -MW.AnimationController.prototype.play = function ( name ) { + var that = this; + var progress = 0; + var prevRotY = this.mesh.rotation.y; + var targetRotY = rad; + var deltaY = getDeltaAngle( prevRotY, targetRotY ); + // var duration = Math.abs( deltaY ) * 100; + var start = Date.now(); + var end = start + DURATION; - var i; + if ( immediate ) { - for ( i in this.motion ) { + this.mesh.rotation.y = targetRotY; + return; - this.motion[ i ].anim.stop(); + } - } + if ( this._targetRotY === targetRotY ) { return; } + + this._targetRotY = targetRotY; + + ( function () { + + var _targetRotY = targetRotY; + + ( function interval () { + + var now = Date.now(); + var isAborted = _targetRotY !== that._targetRotY; + + if ( isAborted ) { return; } + + if ( now >= end ) { + + that.mesh.rotation.y = _targetRotY; + delete that._targetRotY; + return; + + } + + requestAnimationFrame( interval ); + progress = ( now - start ) / DURATION; + that.mesh.rotation.y = prevRotY + deltaY * progress; + + } )(); + + } )(); + + } - this.motion[ name ].anim.play(); + }(), + + update: function ( delta ) { + + this.mixer.update( delta ); + + } }; @@ -591,21 +670,22 @@ MW.AnimationController.prototype.play = function ( name ) { ns.KeyInputControl = function () { THREE.EventDispatcher.prototype.apply( this ); - this.mouseAccelarationX = 100; - this.mouseAccelarationY = 20; this.isDisabled = false; this.isUp = false; this.isDown = false; this.isLeft = false; this.isRight = false; + this.isMoveKeyHolded = false; this.frontAngle = 0; - this._mousedownListener = onkeydown.bind( this ); - this._mouseupListener = onkeyup.bind( this ); + this._keydownListener = onkeydown.bind( this ); + this._keyupListener = onkeyup.bind( this ); + this._blurListener = onblur.bind( this ); - window.addEventListener( 'keydown', this._mousedownListener, false ); - window.addEventListener( 'keyup', this._mouseupListener, false ); + window.addEventListener( 'keydown', this._keydownListener, false ); + window.addEventListener( 'keyup', this._keyupListener, false ); + window.addEventListener( 'blur', this._blurListener, false ); } @@ -631,18 +711,8 @@ MW.AnimationController.prototype.play = function ( name ) { else if ( !up && !left && !down && right ) { this.frontAngle = DEG_270; } else if ( up && !left && !down && right ) { this.frontAngle = DEG_315; } - this.frontAngle = this.frontAngle % DEG_360; - }; - - ns.KeyInputControl.prototype.getFrontAngle = function () { - - return this.frontAngle; - - }; - - function onkeydown ( e ) { @@ -674,15 +744,28 @@ MW.AnimationController.prototype.play = function ( name ) { this.jump(); break; + default: + return; + } + + var prevAngle = this.frontAngle; this.updateAngle(); - this.dispatchEvent( { type: 'movekeychange' } ); - if ( this.isUp || this.isDown || this.isLeft || this.isRight ) { + if ( prevAngle !== this.frontAngle ) { + + this.dispatchEvent( { type: 'movekeychange' } ); + + } + + if ( + ( this.isUp || this.isDown || this.isLeft || this.isRight ) && + !this.isMoveKeyHolded + ) { this.isMoveKeyHolded = true; - this.dispatchEvent( { type: 'movekeyhold' } ); + this.dispatchEvent( { type: 'movekeyon' } ); } @@ -717,10 +800,20 @@ MW.AnimationController.prototype.play = function ( name ) { case KEY_SPACE : break; + default: + return; + } + + var prevAngle = this.frontAngle; this.updateAngle(); - this.dispatchEvent( { type: 'movekeychange' } ); + + if ( prevAngle !== this.frontAngle ) { + + this.dispatchEvent( { type: 'movekeychange' } ); + + } if ( !this.isUp && !this.isDown && !this.isLeft && !this.isRight && ( @@ -735,7 +828,24 @@ MW.AnimationController.prototype.play = function ( name ) { ) ) { - this.dispatchEvent( { type: 'movekeyrelease' } ); + this.isMoveKeyHolded = false; + this.dispatchEvent( { type: 'movekeyoff' } ); + + } + + } + + function onblur ( e ) { + + this.isUp = false; + this.isDown = false; + this.isLeft = false; + this.isRight = false; + + if ( this.isMoveKeyHolded ) { + + this.isMoveKeyHolded = false; + this.dispatchEvent( { type: 'movekeyoff' } ); } @@ -756,9 +866,9 @@ MW.AnimationController.prototype.play = function ( name ) { var modulo = function ( n, d ) { return ( ( n % d ) + d ) % d; - + } - + // camera isntance of THREE.Camera // trackObject isntance of THREE.Object3D // params.el DOM element @@ -771,7 +881,7 @@ MW.AnimationController.prototype.play = function ( name ) { THREE.EventDispatcher.prototype.apply( this ); this.camera = camera; this.trackObject = trackObject; - this.el = params && params.el || window; + this.el = params && params.el || document.body; this.offset = params && params.offset || new THREE.Vector3( 0, 0, 0 ), this.radius = params && params.radius || 10; this.minRadius = params && params.minRadius || 1; @@ -798,7 +908,7 @@ MW.AnimationController.prototype.play = function ( name ) { this.el.addEventListener( 'mouseup', this._mouseupListener, false ); this.el.addEventListener( 'mousewheel', this._scrollListener, false ); this.el.addEventListener( 'DOMMouseScroll', this._scrollListener, false ); - + }; ns.TPSCameraControl.prototype = { @@ -816,8 +926,8 @@ MW.AnimationController.prototype.play = function ( name ) { this.trackObject.matrixWorld.elements[ 14 ] + this.offset.z ); position = new THREE.Vector3( - Math.cos( this.phi ) * Math.cos( this.theta + PI_HALF ), - Math.sin( this.phi ), + Math.cos( this.phi ) * Math.cos( this.theta + PI_HALF ), + Math.sin( this.phi ), Math.cos( this.phi ) * Math.sin( this.theta + PI_HALF ) ); distance = this.collisionTest( position.clone().normalize() ); @@ -941,6 +1051,7 @@ MW.AnimationController.prototype.play = function ( name ) { this._pointerLast.y = this.lat; this.el.removeEventListener( 'mousemove', this._mousedragListener, false ); this.el.addEventListener( 'mousemove', this._mousedragListener, false ); + document.body.className += ' js-TPSCameraDragging'; } @@ -948,6 +1059,7 @@ MW.AnimationController.prototype.play = function ( name ) { this.dispatchEvent( { type: 'mouseup' } ); this.el.removeEventListener( 'mousemove', this._mousedragListener, false ); + document.body.className = document.body.className.replace( / js-TPSCameraDragging/, '' ); } @@ -968,12 +1080,12 @@ MW.AnimationController.prototype.play = function ( name ) { function onscroll ( event ) { event.preventDefault(); - + if ( event.wheelDeltaY ) { // WebKit this.radius -= event.wheelDeltaY * 0.05 / 5; - + } else if ( event.wheelDelta ) { // IE diff --git a/build/meshwalk.TPS.min.js b/build/meshwalk.TPS.min.js index be7d1ab..694ca5a 100644 --- a/build/meshwalk.TPS.min.js +++ b/build/meshwalk.TPS.min.js @@ -1 +1 @@ -!function(t,i){"use strict";i.CharacterController=function(i,e){t.EventDispatcher.prototype.apply(this),this.object=i,this.center=this.object.position.clone(),this.radius=e,this.groundPadding=.5,this.maxSlopeGradient=Math.cos(t.Math.degToRad(50)),this.isGrounded=!1,this.isOnSlope=!1,this.isIdling=!1,this.isRunning=!1,this.isJumping=!1,this.direction=0,this.movementSpeed=10,this.velocity=new t.Vector3(0,-10,0),this.currentJumpPower=0,this.jumpStartTime=0,this.groundHeight=0,this.groundNormal=new t.Vector3,this.collisionCandidate,this.contactInfo=[]},i.CharacterController.prototype={constructor:i.CharacterController,update:function(t){this.isGrounded=!1,this.isOnSlope=!1,this.groundHeight=-1/0,this.groundNormal.set(0,1,0),this.updateGrounding(),this.updateJumping(),this.updatePosition(t),this.collisionDetection(),this.solvePosition(),this.updateVelocity(),this.events()},updateVelocity:function(){var i,e,s,n,h,o,a,r,c=-20,d=-Math.cos(this.direction),l=-Math.sin(this.direction),u=!1;if(this.velocity.set(l*this.movementSpeed*this.isRunning,c,d*this.movementSpeed*this.isRunning),0!==this.contactInfo.length||this.isJumping){if(!this.isGrounded||this.isOnSlope||this.isJumping)if(this.isOnSlope){var p=c,m=-p/(1-this.groundNormal.y)*.2;this.velocity.x=this.groundNormal.x*m,this.velocity.y=c,this.velocity.z=this.groundNormal.z*m}else this.isGrounded||this.isOnSlope||!this.isJumping||(this.velocity.y=this.currentJumpPower*-c);else this.velocity.y=0;for(s=new t.Vector2(l,d),h=Math.atan2(s.y,s.x),o=Math.atan2(-s.y,-s.x),a=0,r=this.contactInfo.length;r>a;a++)i=this.contactInfo[a].face.normal,this.maxSlopeGradient=.5*Math.PI&&Math.abs(o-n)<=1.5*Math.PI||(e.set(s.dot(e)*e.x,s.dot(e)*e.y),s.subVectors(s,e),this.velocity.x=s.x*this.movementSpeed*this.isRunning,this.velocity.z=s.y*this.movementSpeed*this.isRunning));u&&(this.velocity.y=Math.min(0,this.velocity.y),this.isJumping=!1)}},updateGrounding:function(){var e,s,n,h,o=this.collisionCandidate,a=new t.Vector3(this.center.x,this.center.y+this.radius,this.center.z),r=new t.Vector3(this.center.x,this.center.y-1e10,this.center.z);for(e=0,s=o.length;s>e;e++)h=i.collision.testSegmentTriangle(a,r,o[e].a,o[e].b,o[e].c),h&&!n?(n=h,n.face=o[e]):h&&h.contactPoint.y>n.contactPoint.y&&(n=h,n.face=o[e]);if(n){this.groundHeight=n.contactPoint.y,this.groundNormal.copy(n.face.normal);var c=a.y,d=this.center.y-this.radius-this.groundPadding;if(this.isJumping&&0t;t++)s=i.collision.isIntersectionSphereTriangle(this,n[t].a,n[t].b,n[t].c,n[t].normal),s&&(s.face=n[t],this.contactInfo.push(s))},solvePosition:function(){var i,e,s,n,h,o,a,r=new t.Vector3,c=new t.Vector3,d=new t.Vector3,l=new t.Vector3,u=new t.Vector3;if(0===this.contactInfo.length)return this.object.position.copy(this.center),void 0;for(o=0,a=this.contactInfo.length;a>o;o++)if(i=this.contactInfo[o].face,e=this.contactInfo[o].face.normal,s=this.contactInfo[o].distance,!(this.maxSlopeGradient=this.currentJumpPower&&p&&(this.isJumping=!1,this.isGrounded=!0),(this.isGrounded||this.isOnSlope)&&(r.copy(e).multiplyScalar(-this.radius).add(this.center),d.set(e.x,0,e.z).normalize(),n=i.a.dot(e),h=(n-(e.x*r.x+e.y*r.y+e.z*r.z))/(e.x*d.x+e.y*d.y+e.z*d.z),c.copy(d).multiplyScalar(h).add(r),l.subVectors(c,r),Math.abs(u.x)>Math.abs(l.x)&&(u.x+=l.x),Math.abs(u.z)>Math.abs(l.z)&&(u.z+=l.z))}this.center.add(u),this.object.position.copy(this.center)},events:function(){var t,i,e,s,n,h=!0;return function(){return h?(h=!1,t=this.isGrounded,i=this.isOnSlope,e=this.isIdling,s=this.isRunning,n=this.isJumping,void 0):(s||this.isRunning||!this.isGrounded||this.isIdling?!s&&this.isRunning&&!this.isJumping&&this.isGrounded||!t&&this.isGrounded&&this.isRunning||i&&!this.isOnSlope&&this.isRunning&&this.isGrounded?(this.isIdling=!1,this.dispatchEvent({type:"startWalking"})):!n&&this.isJumping?(this.isIdling=!1,this.dispatchEvent({type:"startJumping"})):!i&&this.isOnSlope?this.dispatchEvent({type:"startSliding"}):!t||this.isGrounded||this.isJumping||this.dispatchEvent({type:"startFalling"}):(this.isIdling=!0,this.dispatchEvent({type:"startIdling"})),!t&&this.isGrounded,t=this.isGrounded,i=this.isOnSlope,e=this.isIdling,s=this.isRunning,n=this.isJumping,void 0)}}(),setDirection:function(){},jump:function(){this.isJumping||!this.isGrounded||this.isOnSlope||(this.jumpStartTime=Date.now(),this.currentJumpPower=1,this.isJumping=!0)},updateJumping:function(){var t=1e3;if(this.isJumping){var i=Date.now()-this.jumpStartTime,e=i/t;this.currentJumpPower=Math.cos(Math.min(e,1)*Math.PI)}}}}(THREE,MW),MW.AnimationController=function(t){this.mesh=t,this.motion={};var i,e,s;for(i=0,e=this.mesh.geometry.animations.length;e>i;i++)s=this.mesh.geometry.animations[i],this.motion[s.name]={anim:new THREE.Animation(t,s,THREE.AnimationHandler.CATMULLROM),duration:1e3*s.length}},MW.AnimationController.prototype.play=function(t){var i;for(i in this.motion)this.motion[i].anim.stop();this.motion[t].anim.play()},function(t,i){"use strict";function e(t){if(!this.isDisabled){switch(t.keyCode){case n:case h:this.isUp=!0;break;case o:case a:this.isDown=!0;break;case r:case c:this.isLeft=!0;break;case d:case l:this.isRight=!0;break;case u:this.jump()}this.updateAngle(),this.dispatchEvent({type:"movekeychange"}),(this.isUp||this.isDown||this.isLeft||this.isRight)&&(this.isMoveKeyHolded=!0,this.dispatchEvent({type:"movekeyhold"}))}}function s(t){if(!this.isDisabled){switch(t.keyCode){case n:case h:this.isUp=!1;break;case o:case a:this.isDown=!1;break;case r:case c:this.isLeft=!1;break;case d:case l:this.isRight=!1;break;case u:}this.updateAngle(),this.dispatchEvent({type:"movekeychange"}),this.isUp||this.isDown||this.isLeft||this.isRight||t.keyCode!==n&&t.keyCode!==h&&t.keyCode!==o&&t.keyCode!==a&&t.keyCode!==r&&t.keyCode!==c&&t.keyCode!==d&&t.keyCode!==l||this.dispatchEvent({type:"movekeyrelease"})}}var n=87,h=38,o=83,a=40,r=65,c=37,d=68,l=39,u=32,p=t.Math.degToRad(0),m=t.Math.degToRad(45),g=t.Math.degToRad(90),y=t.Math.degToRad(135),f=t.Math.degToRad(180),v=t.Math.degToRad(225),M=t.Math.degToRad(270),w=t.Math.degToRad(315),x=t.Math.degToRad(360);i.KeyInputControl=function(){t.EventDispatcher.prototype.apply(this),this.mouseAccelarationX=100,this.mouseAccelarationY=20,this.isDisabled=!1,this.isUp=!1,this.isDown=!1,this.isLeft=!1,this.isRight=!1,this.frontAngle=0,this._mousedownListener=e.bind(this),this._mouseupListener=s.bind(this),window.addEventListener("keydown",this._mousedownListener,!1),window.addEventListener("keyup",this._mouseupListener,!1)},i.KeyInputControl.prototype.jump=function(){this.dispatchEvent({type:"jumpkeypress"})},i.KeyInputControl.prototype.updateAngle=function(){var t=this.isUp,i=this.isDown,e=this.isLeft,s=this.isRight;!t||e||i||s?t&&e&&!i&&!s?this.frontAngle=m:t||!e||i||s?!t&&e&&i&&!s?this.frontAngle=y:t||e||!i||s?!t&&!e&&i&&s?this.frontAngle=v:t||e||i||!s?t&&!e&&!i&&s&&(this.frontAngle=w):this.frontAngle=M:this.frontAngle=f:this.frontAngle=g:this.frontAngle=p,this.frontAngle=this.frontAngle%x},i.KeyInputControl.prototype.getFrontAngle=function(){return this.frontAngle}}(THREE,MW),function(t,i){"use strict";function e(t){this.dispatchEvent({type:"mousedown"}),this._pointerStart.x=t.clientX,this._pointerStart.y=t.clientY,this._pointerLast.x=this.lon,this._pointerLast.y=this.lat,this.el.removeEventListener("mousemove",this._mousedragListener,!1),this.el.addEventListener("mousemove",this._mousedragListener,!1)}function s(){this.dispatchEvent({type:"mouseup"}),this.el.removeEventListener("mousemove",this._mousedragListener,!1)}function n(t){var i=this.el.offsetWidth,e=this.el.offsetHeight,s=(this._pointerStart.x-t.clientX)/i*2,n=(this._pointerStart.y-t.clientY)/e*2;this.setLatLon(this._pointerLast.y+n*this.mouseAccelerationY,this._pointerLast.x+s*this.mouseAccelerationX)}function h(t){t.preventDefault(),t.wheelDeltaY?this.radius-=.05*t.wheelDeltaY/5:t.wheelDelta?this.radius-=.05*t.wheelDelta/5:t.detail&&(this.radius+=t.detail/5),this.radius=Math.max(this.radius,this.minRadius),this.radius=Math.min(this.radius,this.maxRadius)}var o=2*Math.PI,a=Math.PI/2;i.TPSCameraControl=function(i,o,a){t.EventDispatcher.prototype.apply(this),this.camera=i,this.trackObject=o,this.el=a&&a.el||window,this.offset=a&&a.offset||new t.Vector3(0,0,0),this.radius=a&&a.radius||10,this.minRadius=a&&a.minRadius||1,this.maxRadius=a&&a.maxRadius||30,this.rigidObjects=a&&a.rigidObjects||[],this.lat=0,this.lon=0,this.phi=0,this.theta=0,this.mouseAccelerationX=a&&void 0!==a.mouseAccelerationX?a.mouseAccelerationX:100,this.mouseAccelerationY=a&&void 0!==a.mouseAccelerationY?a.mouseAccelerationY:30,this._pointerStart={x:0,y:0},this._pointerLast={x:0,y:0},this.setNearPlainCornersWithPadding(),this.update(),this._mousedownListener=e.bind(this),this._mouseupListener=s.bind(this),this._mousedragListener=n.bind(this),this._scrollListener=h.bind(this),this.el.addEventListener("mousedown",this._mousedownListener,!1),this.el.addEventListener("mouseup",this._mouseupListener,!1),this.el.addEventListener("mousewheel",this._scrollListener,!1),this.el.addEventListener("DOMMouseScroll",this._scrollListener,!1)},i.TPSCameraControl.prototype={constructor:i.TPSCameraControl,update:function(){var i,e;this._center=new t.Vector3(this.trackObject.matrixWorld.elements[12]+this.offset.x,this.trackObject.matrixWorld.elements[13]+this.offset.y,this.trackObject.matrixWorld.elements[14]+this.offset.z),i=new t.Vector3(Math.cos(this.phi)*Math.cos(this.theta+a),Math.sin(this.phi),Math.cos(this.phi)*Math.sin(this.theta+a)),e=this.collisionTest(i.clone().normalize()),i.multiplyScalar(e),i.add(this._center),this.camera.position.copy(i),90===this.lat?this.camera.up.set(Math.cos(this.theta+Math.PI),0,Math.sin(this.theta+Math.PI)):-90===this.lat?this.camera.up.set(Math.cos(this.theta),0,Math.sin(this.theta)):this.camera.up.set(0,1,0),this.camera.lookAt(this._center),this.dispatchEvent({type:"updated"})},getFrontAngle:function(){return o+this.theta},setNearPlainCornersWithPadding:function(){var i=this.camera.near,e=.5*this.camera.fov,s=Math.tan(t.Math.degToRad(e))*i,n=s*this.camera.aspect;this.nearPlainCornersWithPadding=[new t.Vector3(-n-i,-s-i,0),new t.Vector3(n+i,-s-i,0),new t.Vector3(n+i,s+i,0),new t.Vector3(-n-i,s+i,0)]},setLatLon:function(i,e){this.lat=i>90?90:-90>i?-90:i,this.lon=0>e?360+e%360:e%360,this.phi=t.Math.degToRad(this.lat),this.theta=-t.Math.degToRad(this.lon)},collisionTest:function(i){var e,s,n,h,o,a=this.radius,r=new t.Matrix4,c=(new t.Matrix4).makeRotationX(this.phi),d=(new t.Matrix4).makeRotationY(this.theta);for(r.multiplyMatrices(c,d),e=0;4>e;e++)s=this.nearPlainCornersWithPadding[e].clone(),s.applyMatrix4(r),n=new t.Vector3(this._center.x+s.x,this._center.y+s.y,this._center.z+s.z),h=new t.Raycaster(n,i,this.camera.near,this.radius),o=h.intersectObjects(this.rigidObjects),0!==o.length&&o[0].distancea;a++)i=this.contactInfo[a].face.normal,this.maxSlopeGradient=.5*Math.PI&&Math.abs(h-n)<=1.5*Math.PI||(e.set(s.dot(e)*e.x,s.dot(e)*e.y),s.subVectors(s,e),this.velocity.x=s.x*this.movementSpeed*this.isRunning,this.velocity.z=s.y*this.movementSpeed*this.isRunning));l&&(this.velocity.y=Math.min(0,this.velocity.y),this.isJumping=!1)}},updateGrounding:function(){var e,s,n,o,h=this.collisionCandidate,a=new t.Vector3(this.center.x,this.center.y+this.radius,this.center.z),r=new t.Vector3(this.center.x,this.center.y-1e10,this.center.z);for(e=0,s=h.length;s>e;e++)o=i.collision.testSegmentTriangle(a,r,h[e].a,h[e].b,h[e].c),o&&!n?(n=o,n.face=h[e]):o&&o.contactPoint.y>n.contactPoint.y&&(n=o,n.face=h[e]);if(n){this.groundHeight=n.contactPoint.y,this.groundNormal.copy(n.face.normal);var c=a.y,d=this.center.y-this.radius-this.groundPadding;if(this.isJumping&&0t;t++)s=i.collision.isIntersectionSphereTriangle(this,n[t].a,n[t].b,n[t].c,n[t].normal),s&&(s.face=n[t],this.contactInfo.push(s))},solvePosition:function(){var i,e,s,n,o,h,a,r=new t.Vector3,c=new t.Vector3,d=new t.Vector3,u=new t.Vector3,l=new t.Vector3;if(0===this.contactInfo.length)return this.object.position.copy(this.center),void 0;for(h=0,a=this.contactInfo.length;a>h;h++)if(i=this.contactInfo[h].face,e=this.contactInfo[h].face.normal,s=this.contactInfo[h].distance,!(this.maxSlopeGradient=this.currentJumpPower&&p&&(this.isJumping=!1,this.isGrounded=!0),(this.isGrounded||this.isOnSlope)&&(r.copy(e).multiplyScalar(-this.radius).add(this.center),d.set(e.x,0,e.z).normalize(),n=i.a.dot(e),o=(n-(e.x*r.x+e.y*r.y+e.z*r.z))/(e.x*d.x+e.y*d.y+e.z*d.z),c.copy(d).multiplyScalar(o).add(r),u.subVectors(c,r),Math.abs(l.x)>Math.abs(u.x)&&(l.x+=u.x),Math.abs(l.z)>Math.abs(u.z)&&(l.z+=u.z))}this.center.add(l),this.object.position.copy(this.center)},events:function(){var t,i,e,s,n,o=!0;return function(){return o?(o=!1,t=this.isGrounded,i=this.isOnSlope,e=this.isIdling,s=this.isRunning,n=this.isJumping,void 0):(s||this.isRunning||!this.isGrounded||this.isIdling?!s&&this.isRunning&&!this.isJumping&&this.isGrounded||!t&&this.isGrounded&&this.isRunning||i&&!this.isOnSlope&&this.isRunning&&this.isGrounded?(this.isIdling=!1,this.dispatchEvent({type:"startWalking"})):!n&&this.isJumping?(this.isIdling=!1,this.dispatchEvent({type:"startJumping"})):!i&&this.isOnSlope?this.dispatchEvent({type:"startSliding"}):!t||this.isGrounded||this.isJumping||this.dispatchEvent({type:"startFalling"}):(this.isIdling=!0,this.dispatchEvent({type:"startIdling"})),!t&&this.isGrounded,t=this.isGrounded,i=this.isOnSlope,e=this.isIdling,s=this.isRunning,n=this.isJumping,void 0)}}(),setDirection:function(){},jump:function(){this.isJumping||!this.isGrounded||this.isOnSlope||(this.jumpStartTime=Date.now(),this.currentJumpPower=1,this.isJumping=!0)},updateJumping:function(){var t=1e3;if(this.isJumping){var i=Date.now()-this.jumpStartTime,e=i/t;this.currentJumpPower=Math.cos(Math.min(e,1)*Math.PI)}}}}(THREE,MW),MW.AnimationController=function(t){this.mesh=t,this.motion={},this.mixer=new THREE.AnimationMixer(t),this.currentMotionName="";var i,e,s;for(i=0,e=this.mesh.geometry.animations.length;e>i;i++)s=this.mesh.geometry.animations[i],this.motion[s.name]=new THREE.AnimationAction(s),this.motion[s.name].weight=0,this.mixer.addAction(this.motion[s.name])},MW.AnimationController.prototype={play:function(t){this.motion[this.currentMotionName]?this.mixer.crossFade(this.motion[this.currentMotionName],this.motion[t],.3):this.mixer.fadeIn(this.motion[t],.3),this.currentMotionName=t},turn:function(){var t=200,i=2*Math.PI,e=function(t,i){return(t%i+i)%i},s=function(t,s){var n=e(t-s,i),o=e(s-t,i);return o>n?-n:o};return function(i,e){var n=this,o=0,h=this.mesh.rotation.y,a=i,r=s(h,a),c=Date.now(),d=c+t;return e?(this.mesh.rotation.y=a,void 0):(this._targetRotY!==a&&(this._targetRotY=a,function(){var i=a;!function e(){var s=Date.now(),a=i!==n._targetRotY;if(!a){if(s>=d)return n.mesh.rotation.y=i,delete n._targetRotY,void 0;requestAnimationFrame(e),o=(s-c)/t,n.mesh.rotation.y=h+r*o}}()}()),void 0)}}(),update:function(t){this.mixer.update(t)}},function(t,i){"use strict";function e(t){if(!this.isDisabled){switch(t.keyCode){case o:case h:this.isUp=!0;break;case a:case r:this.isDown=!0;break;case c:case d:this.isLeft=!0;break;case u:case l:this.isRight=!0;break;case p:this.jump();break;default:return}var i=this.frontAngle;this.updateAngle(),i!==this.frontAngle&&this.dispatchEvent({type:"movekeychange"}),(this.isUp||this.isDown||this.isLeft||this.isRight)&&!this.isMoveKeyHolded&&(this.isMoveKeyHolded=!0,this.dispatchEvent({type:"movekeyon"}))}}function s(t){if(!this.isDisabled){switch(t.keyCode){case o:case h:this.isUp=!1;break;case a:case r:this.isDown=!1;break;case c:case d:this.isLeft=!1;break;case u:case l:this.isRight=!1;break;case p:break;default:return}var i=this.frontAngle;this.updateAngle(),i!==this.frontAngle&&this.dispatchEvent({type:"movekeychange"}),this.isUp||this.isDown||this.isLeft||this.isRight||t.keyCode!==o&&t.keyCode!==h&&t.keyCode!==a&&t.keyCode!==r&&t.keyCode!==c&&t.keyCode!==d&&t.keyCode!==u&&t.keyCode!==l||(this.isMoveKeyHolded=!1,this.dispatchEvent({type:"movekeyoff"}))}}function n(){this.isUp=!1,this.isDown=!1,this.isLeft=!1,this.isRight=!1,this.isMoveKeyHolded&&(this.isMoveKeyHolded=!1,this.dispatchEvent({type:"movekeyoff"}))}{var o=87,h=38,a=83,r=40,c=65,d=37,u=68,l=39,p=32,m=t.Math.degToRad(0),g=t.Math.degToRad(45),y=t.Math.degToRad(90),f=t.Math.degToRad(135),v=t.Math.degToRad(180),M=t.Math.degToRad(225),w=t.Math.degToRad(270),x=t.Math.degToRad(315);t.Math.degToRad(360)}i.KeyInputControl=function(){t.EventDispatcher.prototype.apply(this),this.isDisabled=!1,this.isUp=!1,this.isDown=!1,this.isLeft=!1,this.isRight=!1,this.isMoveKeyHolded=!1,this.frontAngle=0,this._keydownListener=e.bind(this),this._keyupListener=s.bind(this),this._blurListener=n.bind(this),window.addEventListener("keydown",this._keydownListener,!1),window.addEventListener("keyup",this._keyupListener,!1),window.addEventListener("blur",this._blurListener,!1)},i.KeyInputControl.prototype.jump=function(){this.dispatchEvent({type:"jumpkeypress"})},i.KeyInputControl.prototype.updateAngle=function(){var t=this.isUp,i=this.isDown,e=this.isLeft,s=this.isRight;!t||e||i||s?t&&e&&!i&&!s?this.frontAngle=g:t||!e||i||s?!t&&e&&i&&!s?this.frontAngle=f:t||e||!i||s?!t&&!e&&i&&s?this.frontAngle=M:t||e||i||!s?t&&!e&&!i&&s&&(this.frontAngle=x):this.frontAngle=w:this.frontAngle=v:this.frontAngle=y:this.frontAngle=m}}(THREE,MW),function(t,i){"use strict";function e(t){this.dispatchEvent({type:"mousedown"}),this._pointerStart.x=t.clientX,this._pointerStart.y=t.clientY,this._pointerLast.x=this.lon,this._pointerLast.y=this.lat,this.el.removeEventListener("mousemove",this._mousedragListener,!1),this.el.addEventListener("mousemove",this._mousedragListener,!1),document.body.className+=" js-TPSCameraDragging"}function s(){this.dispatchEvent({type:"mouseup"}),this.el.removeEventListener("mousemove",this._mousedragListener,!1),document.body.className=document.body.className.replace(/ js-TPSCameraDragging/,"")}function n(t){var i=this.el.offsetWidth,e=this.el.offsetHeight,s=(this._pointerStart.x-t.clientX)/i*2,n=(this._pointerStart.y-t.clientY)/e*2;this.setLatLon(this._pointerLast.y+n*this.mouseAccelerationY,this._pointerLast.x+s*this.mouseAccelerationX)}function o(t){t.preventDefault(),t.wheelDeltaY?this.radius-=.05*t.wheelDeltaY/5:t.wheelDelta?this.radius-=.05*t.wheelDelta/5:t.detail&&(this.radius+=t.detail/5),this.radius=Math.max(this.radius,this.minRadius),this.radius=Math.min(this.radius,this.maxRadius)}var h=2*Math.PI,a=Math.PI/2;i.TPSCameraControl=function(i,h,a){t.EventDispatcher.prototype.apply(this),this.camera=i,this.trackObject=h,this.el=a&&a.el||document.body,this.offset=a&&a.offset||new t.Vector3(0,0,0),this.radius=a&&a.radius||10,this.minRadius=a&&a.minRadius||1,this.maxRadius=a&&a.maxRadius||30,this.rigidObjects=a&&a.rigidObjects||[],this.lat=0,this.lon=0,this.phi=0,this.theta=0,this.mouseAccelerationX=a&&void 0!==a.mouseAccelerationX?a.mouseAccelerationX:100,this.mouseAccelerationY=a&&void 0!==a.mouseAccelerationY?a.mouseAccelerationY:30,this._pointerStart={x:0,y:0},this._pointerLast={x:0,y:0},this.setNearPlainCornersWithPadding(),this.update(),this._mousedownListener=e.bind(this),this._mouseupListener=s.bind(this),this._mousedragListener=n.bind(this),this._scrollListener=o.bind(this),this.el.addEventListener("mousedown",this._mousedownListener,!1),this.el.addEventListener("mouseup",this._mouseupListener,!1),this.el.addEventListener("mousewheel",this._scrollListener,!1),this.el.addEventListener("DOMMouseScroll",this._scrollListener,!1)},i.TPSCameraControl.prototype={constructor:i.TPSCameraControl,update:function(){var i,e;this._center=new t.Vector3(this.trackObject.matrixWorld.elements[12]+this.offset.x,this.trackObject.matrixWorld.elements[13]+this.offset.y,this.trackObject.matrixWorld.elements[14]+this.offset.z),i=new t.Vector3(Math.cos(this.phi)*Math.cos(this.theta+a),Math.sin(this.phi),Math.cos(this.phi)*Math.sin(this.theta+a)),e=this.collisionTest(i.clone().normalize()),i.multiplyScalar(e),i.add(this._center),this.camera.position.copy(i),90===this.lat?this.camera.up.set(Math.cos(this.theta+Math.PI),0,Math.sin(this.theta+Math.PI)):-90===this.lat?this.camera.up.set(Math.cos(this.theta),0,Math.sin(this.theta)):this.camera.up.set(0,1,0),this.camera.lookAt(this._center),this.dispatchEvent({type:"updated"})},getFrontAngle:function(){return h+this.theta},setNearPlainCornersWithPadding:function(){var i=this.camera.near,e=.5*this.camera.fov,s=Math.tan(t.Math.degToRad(e))*i,n=s*this.camera.aspect;this.nearPlainCornersWithPadding=[new t.Vector3(-n-i,-s-i,0),new t.Vector3(n+i,-s-i,0),new t.Vector3(n+i,s+i,0),new t.Vector3(-n-i,s+i,0)]},setLatLon:function(i,e){this.lat=i>90?90:-90>i?-90:i,this.lon=0>e?360+e%360:e%360,this.phi=t.Math.degToRad(this.lat),this.theta=-t.Math.degToRad(this.lon)},collisionTest:function(i){var e,s,n,o,h,a=this.radius,r=new t.Matrix4,c=(new t.Matrix4).makeRotationX(this.phi),d=(new t.Matrix4).makeRotationY(this.theta);for(r.multiplyMatrices(c,d),e=0;4>e;e++)s=this.nearPlainCornersWithPadding[e].clone(),s.applyMatrix4(r),n=new t.Vector3(this._center.x+s.x,this._center.y+s.y,this._center.z+s.z),o=new t.Raycaster(n,i,this.camera.near,this.radius),h=o.intersectObjects(this.rigidObjects),0!==h.length&&h[0].distancel)return!1;if(c=u.dot(p),s=m.dot(p),i=x.dot(p),l=d.y*Math.abs(b.z)+d.z*Math.abs(b.y),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(M),s=m.dot(M),i=x.dot(M),l=d.y*Math.abs(f.z)+d.z*Math.abs(f.y),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(w),s=m.dot(w),i=x.dot(w),l=d.x*Math.abs(V.z)+d.z*Math.abs(V.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(g),s=m.dot(g),i=x.dot(g),l=d.x*Math.abs(b.z)+d.z*Math.abs(b.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(z),s=m.dot(z),i=x.dot(z),l=d.x*Math.abs(f.z)+d.z*Math.abs(f.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(v),s=m.dot(v),i=x.dot(v),l=d.x*Math.abs(V.y)+d.y*Math.abs(V.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(S),s=m.dot(S),i=x.dot(S),l=d.x*Math.abs(b.y)+d.y*Math.abs(b.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(B),s=m.dot(B),i=x.dot(B),l=d.x*Math.abs(f.y)+d.y*Math.abs(f.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(Math.max(u.x,m.x,x.x)<-d.x||Math.min(u.x,m.x,x.x)>d.x)return!1;if(Math.max(u.y,m.y,x.y)<-d.y||Math.min(u.y,m.y,x.y)>d.y)return!1;if(Math.max(u.z,m.z,x.z)<-d.z||Math.min(u.z,m.z,x.z)>d.z)return!1;var P=new t.Plane;return P.normal=(new t.Vector3).copy(b).cross(V).normalize(),P.constant=P.normal.dot(r),e.collision.isIntersectionAABBPlane(a,P)},e.collision.isIntersectionSphereSphere=function(t,e){var r=t.radius+e.radius;return t.center.distanceToSquared(e.center)<=r*r},e.collision.isIntersectionSphereAABB=function(t,e){var r=0;return t.center.xe.max.x&&(r+=(t.center.x-e.max.x)*(t.center.x-e.max.x)),t.center.ye.max.y&&(r+=(t.center.y-e.max.y)*(t.center.y-e.max.y)),t.center.ze.max.z&&(r+=(t.center.z-e.max.z)*(t.center.z-e.max.z)),r<=t.radius*t.radius},e.collision.isIntersectionSphereTriangle=function(e,r,o,n,a){var c,s,i,l=new t.Vector3,h=new t.Vector3,d=new t.Vector3,u=new t.Vector3;if(l.subVectors(r,e.center),h.subVectors(o,e.center),d.subVectors(n,e.center),c=e.radius*e.radius,u.crossVectors(h.clone().sub(l),d.clone().sub(l)),s=l.dot(u),i=u.dot(u),s*s>c*i)return!1;var m,x,V,b,f,y;if(m=l.dot(l),x=l.dot(h),V=l.dot(d),b=h.dot(h),f=h.dot(d),y=d.dot(d),m>c&x>m&V>m||b>c&x>b&f>b||y>c&V>y&f>y)return!1;var p,M,w,g,z,v,S=new t.Vector3,B=new t.Vector3,P=new t.Vector3,E=new t.Vector3,N=new t.Vector3,T=new t.Vector3,A=new t.Vector3,O=new t.Vector3,I=new t.Vector3;if(S.subVectors(h,l),B.subVectors(d,h),P.subVectors(l,d),p=x-m,M=f-b,w=V-y,g=S.dot(S),z=B.dot(B),v=P.dot(P),E.subVectors(l.multiplyScalar(g),S.multiplyScalar(p)),N.subVectors(h.multiplyScalar(z),B.multiplyScalar(M)),T.subVectors(d.multiplyScalar(v),P.multiplyScalar(w)),A.subVectors(d.multiplyScalar(g),E),O.subVectors(l.multiplyScalar(z),N),I.subVectors(h.multiplyScalar(v),T),E.dot(E)>c*g*g&&E.dot(A)>=0||N.dot(N)>c*z*z&&N.dot(O)>=0||T.dot(T)>c*v*v&&T.dot(I)>=0)return!1;var R=Math.sqrt(s*s/i)-e.radius-1,F=new t.Vector3,H=new t.Vector3(-a.x,-a.y,-a.z);return F.copy(e.center).add(H.multiplyScalar(R)),{distance:R,contactPoint:F}},e.collision.testSegmentTriangle=function(t,e,r,o,n){var a=o.clone().sub(r),c=n.clone().sub(r),s=t.clone().sub(e),i=a.clone().cross(c),l=s.dot(i);if(0>=l)return!1;var h=t.clone().sub(r),d=h.dot(i);if(0>d)return 0;if(d>l)return 0;var u=s.clone().cross(h),m=c.dot(u);if(0>m||m>l)return 0;var x=-1*a.clone().dot(u);if(0>x||m+x>l)return 0;var V=1/l;d*=V,m*=V,x*=V;var b=1-m-x,f=r.clone().multiplyScalar(b),y=o.clone().multiplyScalar(m),p=n.clone().multiplyScalar(x),M=f.clone().add(y).add(p);return{contactPoint:M}}}(THREE,MW),function(t,e){"use strict";e.World=function(){this.colliderPool=[],this.characterPool=[]},e.World.prototype.add=function(t){t instanceof e.Octree?this.colliderPool.push(t):t instanceof e.CharacterController&&this.characterPool.push(t)},e.World.prototype.step=function(r){var o,n,a,c,s,i,l,h,d;for(i=0,h=this.characterPool.length;h>i;i++){for(o=this.characterPool[i],l=0,d=this.colliderPool.length;d>l;l++)n=this.colliderPool[l],a=new t.Sphere(o.center,o.radius+o.groundPadding),c=n.getIntersectedNodes(a,n.maxDepth),s=e.Octree.uniqTriangkesfromNodes(c);o.collisionCandidate=s,o.update(r)}}}(THREE,MW),function(t,e){"use strict";e.Octree=function(r,o,n){this.min=r,this.max=o,this.maxDepth=n,this.nodes=[];var a,c,s,i,l,h,d,u,m,x=new t.Vector3,V=new t.Vector3,b=new t.Vector3;for(s=0;sa;a++)d=a%l,u=a/h|0,m=(a/l|0)%l,V.set(this.min.x+d*x.x,this.min.y+u*x.y,this.min.z+m*x.z),b.copy(V).add(x),i=e.Octree.getMortonNumber(d,u,m),this.nodes[s][i]=new e.OctreeNode(this,s,i,V,b)},e.Octree.prototype={constructor:e.Octree,importThreeMesh:function(r){var o,n,a,c,s,i,l,h,d,u,m,x,V,b,f=new t.Vector3,y=new t.Vector3,p=new t.Vector3,M=new t.Vector3,w=(new t.Vector3,new t.Vector3,new t.Vector3,new t.Vector3),g=new t.Vector3;if(r.updateMatrix(),i=r.geometry.uuid,s=r.geometry.clone(),s.applyMatrix(r.matrix),s.computeVertexNormals(),s instanceof t.BufferGeometry){if(void 0!==s.attributes.index){var z=s.attributes.index.array,v=s.attributes.position.array,S=(s.attributes.normal.array,s.offsets);for(0===S.length&&(S=[{start:0,count:z.length,index:0}]),o=0,a=S.length;a>o;++o)for(u=S[o].start,d=S[o].count,h=S[o].index,n=u,c=u+d;c>n;n+=3)m=h+z[n],x=h+z[n+1],V=h+z[n+2],y=f.fromArray(v,3*m).clone(),p=f.fromArray(v,3*x).clone(),M=f.fromArray(v,3*V).clone(),g.subVectors(M,p),w.subVectors(y,p),b=g.cross(w).normalize().clone(),l=new e.Face(y,p,M,b,i),this.addFace(l)}}else for(s.computeFaceNormals(),o=0,a=s.faces.length;a>o;o++)l=new e.Face(s.vertices[s.faces[o].a],s.vertices[s.faces[o].b],s.vertices[s.faces[o].c],s.faces[o].normal,i),this.addFace(l)},addFace:function(t){var r,o,n,a,c,s,i=[],l=[];for(i=this.nodes[0].slice(0),r=0,n=this.maxDepth;n>r;r++){for(o=0,a=i.length;a>o;o++)c=i[o],s=e.collision.isIntersectionTriangleAABB(t.a,t.b,t.c,c),s&&(c.trianglePool.push(t),r+1!==this.maxDepth&&(l=l.concat(c.getChildNodes())));if(0===l.length)break;i=l.slice(0),l.length=0}},removeFace:function(){},getIntersectedNodes:function(t,r){var o,n,a,c,s,i,l,h=[],d=[],u=[];if(i=e.collision.isIntersectionSphereAABB(t,this),!i)return[];for(h=this.nodes[0].slice(0),o=0,a=r;a>o;o++){for(n=0,c=h.length;c>n;n++)s=h[n],i=e.collision.isIntersectionSphereAABB(t,s),i&&(l=o+1===r,l?0!==s.trianglePool.length&&u.push(s):d=d.concat(s.getChildNodes()));h=d.slice(0),d.length=0}return u}},e.Octree.separate3Bit=function(t){return t=61455&(t|t<<8),t=798915&(t|t<<4),t=2396745&(t|t<<2)},e.Octree.getMortonNumber=function(t,r,o){return e.Octree.separate3Bit(t)|e.Octree.separate3Bit(r)<<1|e.Octree.separate3Bit(o)<<2},e.Octree.uniqTriangkesfromNodes=function(t){var e,r,o,n,a,c,s=[],i=!1;if(0===t.length)return[];if(1===t.length)return t[0].trianglePool.slice(0);for(e=0,n=t.length;n>e;e++)for(r=0,a=t[e].trianglePool.length;a>r;r++){for(o=0,c=s.length;c>o;o++)t[e].trianglePool[r]===s[o]&&(i=!0);i||s.push(t[e].trianglePool[r]),i=!1}return s},e.OctreeNode=function(e,r,o,n,a){this.tree=e,this.depth=r,this.mortonNumber=o,this.min=new t.Vector3(n.x,n.y,n.z),this.max=new t.Vector3(a.x,a.y,a.z),this.trianglePool=[]},e.OctreeNode.prototype={constructor:e.OctreeNode,getParentNode:function(){return 0===this.depth?null:(this.tree.nodes[this.depth][this.mortonNumber>>3],void 0)},getChildNodes:function(){if(this.tree.maxDepth===this.depth)return null;var t=this.mortonNumber<<3;return[this.tree.nodes[this.depth+1][t],this.tree.nodes[this.depth+1][t+1],this.tree.nodes[this.depth+1][t+2],this.tree.nodes[this.depth+1][t+3],this.tree.nodes[this.depth+1][t+4],this.tree.nodes[this.depth+1][t+5],this.tree.nodes[this.depth+1][t+6],this.tree.nodes[this.depth+1][t+7]]}},e.Face=function(t,e,r,o,n){this.a=t.clone(),this.b=e.clone(),this.c=r.clone(),this.normal=o.clone(),this.meshID=n},e.Face.prototype={constructor:e.Face},e.Ray=function(t,e,r){this.origin=t,this.direction=e,this.distance=r}}(THREE,MW); \ No newline at end of file +var MW={};MW.triangle={},MW.triangle.makeBoundingBox=function(t){var e=new THREE.Box3;return e.min=e.min.min(t.a),e.min=e.min.min(t.b),e.min=e.min.min(t.c),e.max=e.max.max(t.a),e.max=e.max.max(t.b),e.max=e.max.max(t.c),e},MW.triangle.makeBoundingSphere=function(t,e){var r,o,n,a,c,s,i,l=new THREE.Sphere,h=new THREE.Vector3,d=new THREE.Vector3,u=new THREE.Vector3,m=new THREE.Vector3,x=new THREE.Vector3;return d.subVectors(t.b,t.a),u.subVectors(t.c,t.a),d.dot(u)<=0?(l.center.addVectors(t.b,t.c).divideScalar(2),l.radius=h.subVectors(t.b,t.c).length()/2,l):(d.subVectors(t.a,t.b),u.subVectors(t.c,t.b),d.dot(u)<=0?(l.center.addVectors(t.a,t.c).divideScalar(2),l.radius=h.subVectors(t.a,t.c).length()/2,l):(d.subVectors(t.a,t.c),u.subVectors(t.b,t.c),d.dot(u)<=0?(l.center.addVectors(t.a,t.b).divideScalar(2),l.radius=h.subVectors(t.a,t.b).length()/2,l):(e||(e=t.normal()),d.crossVectors(h.subVectors(t.c,t.b),e),u.crossVectors(h.subVectors(t.c,t.a),e),m.addVectors(t.c,t.b).multiplyScalar(.5),x.addVectors(t.c,t.a).multiplyScalar(.5),r=d.dot(u),o=d.dot(d),a=u.dot(u),n=-h.subVectors(x,m).dot(d),c=-h.subVectors(x,m).dot(u),s=-r*r+o*a,i=(-n*a+r*c)/s,l.center=m.clone().add(d.clone().multiplyScalar(i)),l.radius=h.subVectors(l.center,t.a).length(),l)))},function(t,e){"use strict";e.collision={},e.collision.isIntersectionAABBPlane=function(e,r){var o=(new t.Vector3).addVectors(e.max,e.min).multiplyScalar(.5),n=(new t.Vector3).subVectors(e.max,o),a=n.x*Math.abs(r.normal.x)+n.y*Math.abs(r.normal.y)+n.z*Math.abs(r.normal.z),c=r.normal.dot(o)-r.constant;return Math.abs(c)<=a},e.collision.isIntersectionTriangleAABB=function(r,o,n,a){var c,s,i,l,h=(new t.Vector3).addVectors(a.max,a.min).multiplyScalar(.5),d=(new t.Vector3).subVectors(a.max,h),u=(new t.Vector3).subVectors(r,h),m=(new t.Vector3).subVectors(o,h),x=(new t.Vector3).subVectors(n,h),V=(new t.Vector3).subVectors(m,u),b=(new t.Vector3).subVectors(x,m),f=(new t.Vector3).subVectors(u,x),y=new t.Vector3(0,-V.z,V.y),p=new t.Vector3(0,-b.z,b.y),M=new t.Vector3(0,-f.z,f.y),w=new t.Vector3(V.z,0,-V.x),g=new t.Vector3(b.z,0,-b.x),z=new t.Vector3(f.z,0,-f.x),v=new t.Vector3(-V.y,V.x,0),S=new t.Vector3(-b.y,b.x,0),B=new t.Vector3(-f.y,f.x,0);if(c=u.dot(y),s=m.dot(y),i=x.dot(y),l=d.y*Math.abs(V.z)+d.z*Math.abs(V.y),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(p),s=m.dot(p),i=x.dot(p),l=d.y*Math.abs(b.z)+d.z*Math.abs(b.y),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(M),s=m.dot(M),i=x.dot(M),l=d.y*Math.abs(f.z)+d.z*Math.abs(f.y),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(w),s=m.dot(w),i=x.dot(w),l=d.x*Math.abs(V.z)+d.z*Math.abs(V.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(g),s=m.dot(g),i=x.dot(g),l=d.x*Math.abs(b.z)+d.z*Math.abs(b.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(z),s=m.dot(z),i=x.dot(z),l=d.x*Math.abs(f.z)+d.z*Math.abs(f.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(v),s=m.dot(v),i=x.dot(v),l=d.x*Math.abs(V.y)+d.y*Math.abs(V.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(S),s=m.dot(S),i=x.dot(S),l=d.x*Math.abs(b.y)+d.y*Math.abs(b.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(c=u.dot(B),s=m.dot(B),i=x.dot(B),l=d.x*Math.abs(f.y)+d.y*Math.abs(f.x),Math.max(-Math.max(c,s,i),Math.min(c,s,i))>l)return!1;if(Math.max(u.x,m.x,x.x)<-d.x||Math.min(u.x,m.x,x.x)>d.x)return!1;if(Math.max(u.y,m.y,x.y)<-d.y||Math.min(u.y,m.y,x.y)>d.y)return!1;if(Math.max(u.z,m.z,x.z)<-d.z||Math.min(u.z,m.z,x.z)>d.z)return!1;var P=new t.Plane;return P.normal=(new t.Vector3).copy(b).cross(V).normalize(),P.constant=P.normal.dot(r),e.collision.isIntersectionAABBPlane(a,P)},e.collision.isIntersectionSphereSphere=function(t,e){var r=t.radius+e.radius;return t.center.distanceToSquared(e.center)<=r*r},e.collision.isIntersectionSphereAABB=function(t,e){var r=0;return t.center.xe.max.x&&(r+=(t.center.x-e.max.x)*(t.center.x-e.max.x)),t.center.ye.max.y&&(r+=(t.center.y-e.max.y)*(t.center.y-e.max.y)),t.center.ze.max.z&&(r+=(t.center.z-e.max.z)*(t.center.z-e.max.z)),r<=t.radius*t.radius},e.collision.isIntersectionSphereTriangle=function(e,r,o,n,a){var c,s,i,l=new t.Vector3,h=new t.Vector3,d=new t.Vector3,u=new t.Vector3;if(l.subVectors(r,e.center),h.subVectors(o,e.center),d.subVectors(n,e.center),c=e.radius*e.radius,u.crossVectors(h.clone().sub(l),d.clone().sub(l)),s=l.dot(u),i=u.dot(u),s*s>c*i)return!1;var m,x,V,b,f,y;if(m=l.dot(l),x=l.dot(h),V=l.dot(d),b=h.dot(h),f=h.dot(d),y=d.dot(d),m>c&x>m&V>m||b>c&x>b&f>b||y>c&V>y&f>y)return!1;var p,M,w,g,z,v,S=new t.Vector3,B=new t.Vector3,P=new t.Vector3,E=new t.Vector3,N=new t.Vector3,T=new t.Vector3,A=new t.Vector3,O=new t.Vector3,I=new t.Vector3;if(S.subVectors(h,l),B.subVectors(d,h),P.subVectors(l,d),p=x-m,M=f-b,w=V-y,g=S.dot(S),z=B.dot(B),v=P.dot(P),E.subVectors(l.multiplyScalar(g),S.multiplyScalar(p)),N.subVectors(h.multiplyScalar(z),B.multiplyScalar(M)),T.subVectors(d.multiplyScalar(v),P.multiplyScalar(w)),A.subVectors(d.multiplyScalar(g),E),O.subVectors(l.multiplyScalar(z),N),I.subVectors(h.multiplyScalar(v),T),E.dot(E)>c*g*g&&E.dot(A)>=0||N.dot(N)>c*z*z&&N.dot(O)>=0||T.dot(T)>c*v*v&&T.dot(I)>=0)return!1;var R=Math.sqrt(s*s/i)-e.radius-1,F=new t.Vector3,H=new t.Vector3(-a.x,-a.y,-a.z);return F.copy(e.center).add(H.multiplyScalar(R)),{distance:R,contactPoint:F}},e.collision.testSegmentTriangle=function(t,e,r,o,n){var a=o.clone().sub(r),c=n.clone().sub(r),s=t.clone().sub(e),i=a.clone().cross(c),l=s.dot(i);if(0>=l)return!1;var h=t.clone().sub(r),d=h.dot(i);if(0>d)return 0;if(d>l)return 0;var u=s.clone().cross(h),m=c.dot(u);if(0>m||m>l)return 0;var x=-1*a.clone().dot(u);if(0>x||m+x>l)return 0;var V=1/l;d*=V,m*=V,x*=V;var b=1-m-x,f=r.clone().multiplyScalar(b),y=o.clone().multiplyScalar(m),p=n.clone().multiplyScalar(x),M=f.clone().add(y).add(p);return{contactPoint:M}}}(THREE,MW),function(t,e){"use strict";e.World=function(){this.colliderPool=[],this.characterPool=[]},e.World.prototype.add=function(t){t instanceof e.Octree?this.colliderPool.push(t):t instanceof e.CharacterController&&(this.characterPool.push(t),t.world=this)},e.World.prototype.step=function(r){var o,n,a,c,s,i,l,h,d;for(i=0,h=this.characterPool.length;h>i;i++){for(o=this.characterPool[i],l=0,d=this.colliderPool.length;d>l;l++)n=this.colliderPool[l],a=new t.Sphere(o.center,o.radius+o.groundPadding),c=n.getIntersectedNodes(a,n.maxDepth),s=e.Octree.uniqTriangkesfromNodes(c);o.collisionCandidate=s,o.update(r)}}}(THREE,MW),function(t,e){"use strict";e.Octree=function(r,o,n){this.min=r,this.max=o,this.maxDepth=n,this.nodes=[];var a,c,s,i,l,h,d,u,m,x=new t.Vector3,V=new t.Vector3,b=new t.Vector3;for(s=0;sa;a++)d=a%l,u=a/h|0,m=(a/l|0)%l,V.set(this.min.x+d*x.x,this.min.y+u*x.y,this.min.z+m*x.z),b.copy(V).add(x),i=e.Octree.getMortonNumber(d,u,m),this.nodes[s][i]=new e.OctreeNode(this,s,i,V,b)},e.Octree.prototype={constructor:e.Octree,importThreeMesh:function(r){var o,n,a,c,s,i,l,h,d,u,m,x,V,b,f=new t.Vector3,y=new t.Vector3,p=new t.Vector3,M=new t.Vector3,w=(new t.Vector3,new t.Vector3,new t.Vector3,new t.Vector3),g=new t.Vector3;if(r.updateMatrix(),i=r.geometry.uuid,s=r.geometry.clone(),s.applyMatrix(r.matrix),s.computeVertexNormals(),s instanceof t.BufferGeometry){if(void 0!==s.index){var z=s.index.array,v=s.attributes.position.array,S=(s.attributes.normal.array,s.groups);for(0===S.length&&(S=[{start:0,count:z.length,index:0}]),o=0,a=S.length;a>o;++o)for(u=S[o].start,d=S[o].count,h=S[o].materialIndex,n=u,c=u+d;c>n;n+=3)m=h+z[n],x=h+z[n+1],V=h+z[n+2],y=f.fromArray(v,3*m).clone(),p=f.fromArray(v,3*x).clone(),M=f.fromArray(v,3*V).clone(),g.subVectors(M,p),w.subVectors(y,p),b=g.cross(w).normalize().clone(),l=new e.Face(y,p,M,b,i),this.addFace(l)}}else for(s.computeFaceNormals(),o=0,a=s.faces.length;a>o;o++)l=new e.Face(s.vertices[s.faces[o].a],s.vertices[s.faces[o].b],s.vertices[s.faces[o].c],s.faces[o].normal,i),this.addFace(l)},addFace:function(t){var r,o,n,a,c,s,i=[],l=[];for(i=this.nodes[0].slice(0),r=0,n=this.maxDepth;n>r;r++){for(o=0,a=i.length;a>o;o++)c=i[o],s=e.collision.isIntersectionTriangleAABB(t.a,t.b,t.c,c),s&&(c.trianglePool.push(t),r+1!==this.maxDepth&&(l=l.concat(c.getChildNodes())));if(0===l.length)break;i=l.slice(0),l.length=0}},removeFace:function(){},getIntersectedNodes:function(t,r){var o,n,a,c,s,i,l,h=[],d=[],u=[];if(i=e.collision.isIntersectionSphereAABB(t,this),!i)return[];for(h=this.nodes[0].slice(0),o=0,a=r;a>o;o++){for(n=0,c=h.length;c>n;n++)s=h[n],i=e.collision.isIntersectionSphereAABB(t,s),i&&(l=o+1===r,l?0!==s.trianglePool.length&&u.push(s):d=d.concat(s.getChildNodes()));h=d.slice(0),d.length=0}return u}},e.Octree.separate3Bit=function(t){return t=61455&(t|t<<8),t=798915&(t|t<<4),t=2396745&(t|t<<2)},e.Octree.getMortonNumber=function(t,r,o){return e.Octree.separate3Bit(t)|e.Octree.separate3Bit(r)<<1|e.Octree.separate3Bit(o)<<2},e.Octree.uniqTriangkesfromNodes=function(t){var e,r,o,n,a,c,s=[],i=!1;if(0===t.length)return[];if(1===t.length)return t[0].trianglePool.slice(0);for(e=0,n=t.length;n>e;e++)for(r=0,a=t[e].trianglePool.length;a>r;r++){for(o=0,c=s.length;c>o;o++)t[e].trianglePool[r]===s[o]&&(i=!0);i||s.push(t[e].trianglePool[r]),i=!1}return s},e.OctreeNode=function(e,r,o,n,a){this.tree=e,this.depth=r,this.mortonNumber=o,this.min=new t.Vector3(n.x,n.y,n.z),this.max=new t.Vector3(a.x,a.y,a.z),this.trianglePool=[]},e.OctreeNode.prototype={constructor:e.OctreeNode,getParentNode:function(){return 0===this.depth?null:(this.tree.nodes[this.depth][this.mortonNumber>>3],void 0)},getChildNodes:function(){if(this.tree.maxDepth===this.depth)return null;var t=this.mortonNumber<<3;return[this.tree.nodes[this.depth+1][t],this.tree.nodes[this.depth+1][t+1],this.tree.nodes[this.depth+1][t+2],this.tree.nodes[this.depth+1][t+3],this.tree.nodes[this.depth+1][t+4],this.tree.nodes[this.depth+1][t+5],this.tree.nodes[this.depth+1][t+6],this.tree.nodes[this.depth+1][t+7]]}},e.Face=function(t,e,r,o,n){this.a=t.clone(),this.b=e.clone(),this.c=r.clone(),this.normal=o.clone(),this.meshID=n},e.Face.prototype={constructor:e.Face},e.Ray=function(t,e,r){this.origin=t,this.direction=e,this.distance=r}}(THREE,MW); \ No newline at end of file diff --git a/example/1_getstarted.html b/example/1_getstarted.html index dd92948..26751b8 100755 --- a/example/1_getstarted.html +++ b/example/1_getstarted.html @@ -101,12 +101,17 @@ ;( function update () { requestAnimationFrame( update ); - var delta = clock.getDelta(); - world.step( delta ); renderer.render( scene, camera ); } )(); +;( function step () { + + setTimeout( step, 16.6 ); + world.step( 0.0166 ); + +} )(); + diff --git a/example/2_keyboardInput.html b/example/2_keyboardInput.html index 1714f61..d7c1afc 100755 --- a/example/2_keyboardInput.html +++ b/example/2_keyboardInput.html @@ -64,7 +64,7 @@ wall = new THREE.Mesh( new THREE.BoxGeometry( 5, 6, 10 ), - new THREE.MeshNormalMaterial( { color: 0xffffff, wireframe: true } ) + new THREE.MeshNormalMaterial( { wireframe: true } ) ); wall.position.set( 0, 3, 0 ); // wall.rotation.set( 0, 0, THREE.Math.degToRad( 20 ) ); @@ -89,21 +89,26 @@ keyInputControl = new MW.KeyInputControl(); // bind events -keyInputControl.addEventListener( 'movekeyhold', function () { playerController.isRunning = true; } ); -keyInputControl.addEventListener( 'movekeyrelease', function () { playerController.isRunning = false; } ); -keyInputControl.addEventListener( 'movekeychange', function () { playerController.direction = keyInputControl.getFrontAngle(); } ); -keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); +keyInputControl.addEventListener( 'movekeyon', function () { playerController.isRunning = true; } ); +keyInputControl.addEventListener( 'movekeyoff', function () { playerController.isRunning = false; } ); +keyInputControl.addEventListener( 'movekeychange', function () { playerController.direction = keyInputControl.frontAngle; } ); +keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); ;( function update () { requestAnimationFrame( update ); - var delta = clock.getDelta(); - world.step( delta ); renderer.render( scene, camera ); } )(); +;( function step () { + + setTimeout( step, 16.6 ); + world.step( 0.0166 ); + +} )(); + diff --git a/example/3_cameraControl.html b/example/3_cameraControl.html index 76adb15..4be1015 100755 --- a/example/3_cameraControl.html +++ b/example/3_cameraControl.html @@ -103,15 +103,15 @@ // bind events -keyInputControl.addEventListener( 'movekeyhold', function () { playerController.isRunning = true; } ); -keyInputControl.addEventListener( 'movekeyrelease', function () { playerController.isRunning = false; } ); -keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); +keyInputControl.addEventListener( 'movekeyon', function () { playerController.isRunning = true; } ); +keyInputControl.addEventListener( 'movekeyoff', function () { playerController.isRunning = false; } ); +keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); // synk with keybord input and camera control input keyInputControl.addEventListener( 'movekeychange', function () { - var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var cameraFrontAngle = tpsCameraControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); @@ -119,8 +119,8 @@ // the 'updated' event is fired by `tpsCameraControl.update()` tpsCameraControl.addEventListener( 'updated', function () { - var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var cameraFrontAngle = tpsCameraControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); @@ -129,13 +129,18 @@ ;( function update () { requestAnimationFrame( update ); - var delta = clock.getDelta(); - world.step( delta ); tpsCameraControl.update(); renderer.render( scene, camera ); } )(); +;( function step () { + + setTimeout( step, 16.6 ); + world.step( 0.0166 ); + +} )(); + diff --git a/example/4_objects.html b/example/4_objects.html index 4b99275..4b6c6d7 100755 --- a/example/4_objects.html +++ b/example/4_objects.html @@ -159,15 +159,15 @@ // bind events -keyInputControl.addEventListener( 'movekeyhold', function () { playerController.isRunning = true; } ); -keyInputControl.addEventListener( 'movekeyrelease', function () { playerController.isRunning = false; } ); -keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); +keyInputControl.addEventListener( 'movekeyon', function () { playerController.isRunning = true; } ); +keyInputControl.addEventListener( 'movekeyoff', function () { playerController.isRunning = false; } ); +keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); // synk with keybord input and camera control input keyInputControl.addEventListener( 'movekeychange', function () { var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); @@ -176,7 +176,7 @@ tpsCameraControl.addEventListener( 'updated', function () { var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); @@ -185,13 +185,18 @@ ;( function update () { requestAnimationFrame( update ); - var delta = clock.getDelta(); - world.step( delta ); tpsCameraControl.update(); renderer.render( scene, camera ); } )(); +;( function step () { + + setTimeout( step, 16.6 ); + world.step( 0.0166 ); + +} )(); + diff --git a/example/5_terrain.html b/example/5_terrain.html index 4432865..cd7344c 100755 --- a/example/5_terrain.html +++ b/example/5_terrain.html @@ -85,24 +85,24 @@ // bind events -keyInputControl.addEventListener( 'movekeyhold', function () { playerController.isRunning = true; } ); -keyInputControl.addEventListener( 'movekeyrelease', function () { playerController.isRunning = false; } ); +keyInputControl.addEventListener( 'movekeyon', function () { playerController.isRunning = true; } ); +keyInputControl.addEventListener( 'movekeyoff', function () { playerController.isRunning = false; } ); keyInputControl.addEventListener( 'jumpkeypress', function () { playerController.jump(); } ); // synk with keybord input and camera control input keyInputControl.addEventListener( 'movekeychange', function () { var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); -// the 'updated' event is fired by `tpsCameraControl.update()` +// 'updated' event is fired by `tpsCameraControl.update()` tpsCameraControl.addEventListener( 'updated', function () { var cameraFrontAngle = tpsCameraControl.getFrontAngle(); - var characterFrontAngle = keyInputControl.getFrontAngle(); + var characterFrontAngle = keyInputControl.frontAngle; playerController.direction = THREE.Math.degToRad( 360 ) - cameraFrontAngle + characterFrontAngle; } ); @@ -136,13 +136,18 @@ ;( function update () { requestAnimationFrame( update ); - var delta = clock.getDelta(); - world.step( delta ); tpsCameraControl.update(); renderer.render( scene, camera ); } )(); + ;( function step () { + + setTimeout( step, 16.6 ); + world.step( 0.0166 ); + + } )(); + } ); diff --git a/example/6_animationController.html b/example/6_animationController.html index 5d03760..9c71352 100644 --- a/example/6_animationController.html +++ b/example/6_animationController.html @@ -16,17 +16,24 @@
- - +
+ + + + +
+ + +
- - + +