├── .gitignore ├── LICENSE ├── README.md ├── dist ├── aframe-physics-components.js └── aframe-physics-components.min.js ├── examples ├── basic │ └── index.html ├── bounce │ └── index.html ├── index.html └── main.js ├── package.json ├── src ├── CannonDebugRenderer.js ├── index.js └── wasd-physics-controls.js └── tests ├── __init.test.js ├── helpers.js ├── index.test.js └── karma.conf.js /.gitignore: -------------------------------------------------------------------------------- 1 | .sw[ponm] 2 | examples/build.js 3 | examples/node_modules/ 4 | gh-pages 5 | node_modules/ 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Kevin Ngo 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## aframe-physics-components 2 | 3 | > Also check out Don McCurdy's physics implementation in [aframe-extras](https://github.com/donmccurdy/aframe-extras). 4 | 5 | Experimental physics components for [A-Frame](https://aframe.io) VR using [cannon.js](http://schteppe.github.io/cannon.js/). 6 | 7 | ![physics2](https://cloud.githubusercontent.com/assets/674727/12221506/a6345502-b752-11e5-8d9c-3a7245d24994.gif) 8 | 9 | ### Usage 10 | 11 | #### Browser Installation 12 | 13 | Install and use by directly including the [browser files](dist): 14 | 15 | ```html 16 | 17 | My A-Frame Scene 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 | 28 | ``` 29 | 30 | #### NPM Installation 31 | 32 | Install via NPM: 33 | 34 | ```bash 35 | npm install aframe-physics-components 36 | ``` 37 | 38 | Then register and use. 39 | 40 | ```js 41 | require('aframe'); 42 | require('aframe-physics-components'); 43 | ``` 44 | 45 | ### API 46 | 47 | #### physics-body Component 48 | 49 | | Property | Description | Type | Default Value | 50 | | -------- | ----------- | ---- | ------------- | 51 | | angularVelocity | (in deg/s) | vec3 | 0 0 0 | 52 | | boundingBox | Collision box (in m). | vec3 | 0 0 0 | 53 | | mass | (in kg) | number | 1 | 54 | | velocity | (in m/s) | vec3 | 0 0 0 | 55 | 56 | | Event Name | Description 57 | | ---------- | ----------- 58 | | collide | Emitted when entity collides with another entity. Event contains `contact`. 59 | 60 | ##### applyImpulse (impulseVec3, positionVec3) 61 | 62 | Applies an impulse (indicated by `impulseVec3`) at the body's local point 63 | (indicated by `positionVec3`). `forceVec3` is in Force / Time (Newtons / 64 | Seconds). 65 | 66 | ```js 67 | // Applies a small force from left-to-right to the top-left of the body. 68 | var hitMeBody = document.querySelector('#hit-me-entity').components['physics-body']; 69 | hitMeBody.applyImpulse({ x: 10, y: 0, z: 0 }, { x: -1, y: 1, z: 0 }); 70 | ``` 71 | 72 | #### physics-world Component 73 | 74 | | Property | Description | Default Value | 75 | | -------- | ----------- | ------------- | 76 | | gravity | vec3 | 0 -9.8 0 | 77 | 78 | | Event Name | Description 79 | | ---------- | ----------- 80 | | beginContact | Emitted when an entity in the world begins contact with another entity. Event contains `bodyA` and `bodyB`. 81 | | endContact | Emitted when an entity in the world ends contact with another entity. Event contains `bodyA` and `bodyB`. 82 | -------------------------------------------------------------------------------- /dist/aframe-physics-components.min.js: -------------------------------------------------------------------------------- 1 | !function(t){function e(o){if(i[o])return i[o].exports;var n=i[o]={exports:{},id:o,loaded:!1};return t[o].call(n.exports,n,n.exports,e),n.loaded=!0,n.exports}var i={};return e.m=t,e.c=i,e.p="",e(0)}([function(t,e,i){!function(){if("undefined"==typeof AFRAME)return void console.error("Component attempted to register before AFRAME was available.");var t=i(58).components;Object.keys(t).forEach(function(e){AFRAME.aframeCore?AFRAME.aframeCore.registerComponent(e,t[e]):AFRAME.registerComponent(e,t[e])})}()},function(t,e,i){function o(t,e,i){this.x=t||0,this.y=e||0,this.z=i||0}t.exports=o;var n=i(6);o.ZERO=new o(0,0,0),o.UNIT_X=new o(1,0,0),o.UNIT_Y=new o(0,1,0),o.UNIT_Z=new o(0,0,1),o.prototype.cross=function(t,e){var i=t.x,n=t.y,s=t.z,r=this.x,a=this.y,h=this.z;return e=e||new o,e.x=a*s-h*n,e.y=h*i-r*s,e.z=r*n-a*i,e},o.prototype.set=function(t,e,i){return this.x=t,this.y=e,this.z=i,this},o.prototype.setZero=function(){this.x=this.y=this.z=0},o.prototype.vadd=function(t,e){return e?(e.x=t.x+this.x,e.y=t.y+this.y,e.z=t.z+this.z,void 0):new o(this.x+t.x,this.y+t.y,this.z+t.z)},o.prototype.vsub=function(t,e){return e?(e.x=this.x-t.x,e.y=this.y-t.y,e.z=this.z-t.z,void 0):new o(this.x-t.x,this.y-t.y,this.z-t.z)},o.prototype.crossmat=function(){return new n([0,-this.z,this.y,this.z,0,-this.x,-this.y,this.x,0])},o.prototype.normalize=function(){var t=this.x,e=this.y,i=this.z,o=Math.sqrt(t*t+e*e+i*i);if(o>0){var n=1/o;this.x*=n,this.y*=n,this.z*=n}else this.x=0,this.y=0,this.z=0;return o},o.prototype.unit=function(t){t=t||new o;var e=this.x,i=this.y,n=this.z,s=Math.sqrt(e*e+i*i+n*n);return s>0?(s=1/s,t.x=e*s,t.y=i*s,t.z=n*s):(t.x=1,t.y=0,t.z=0),t},o.prototype.norm=function(){var t=this.x,e=this.y,i=this.z;return Math.sqrt(t*t+e*e+i*i)},o.prototype.length=o.prototype.norm,o.prototype.norm2=function(){return this.dot(this)},o.prototype.lengthSquared=o.prototype.norm2,o.prototype.distanceTo=function(t){var e=this.x,i=this.y,o=this.z,n=t.x,s=t.y,r=t.z;return Math.sqrt((n-e)*(n-e)+(s-i)*(s-i)+(r-o)*(r-o))},o.prototype.distanceSquared=function(t){var e=this.x,i=this.y,o=this.z,n=t.x,s=t.y,r=t.z;return(n-e)*(n-e)+(s-i)*(s-i)+(r-o)*(r-o)},o.prototype.mult=function(t,e){e=e||new o;var i=this.x,n=this.y,s=this.z;return e.x=t*i,e.y=t*n,e.z=t*s,e},o.prototype.vmul=function(t,e){return e=e||new o,e.x=t.x*this.x,e.y=t.y*this.y,e.z=t.z*this.z,e},o.prototype.scale=o.prototype.mult,o.prototype.addScaledVector=function(t,e,i){return i=i||new o,i.x=this.x+t*e.x,i.y=this.y+t*e.y,i.z=this.z+t*e.z,i},o.prototype.dot=function(t){return this.x*t.x+this.y*t.y+this.z*t.z},o.prototype.isZero=function(){return 0===this.x&&0===this.y&&0===this.z},o.prototype.negate=function(t){return t=t||new o,t.x=-this.x,t.y=-this.y,t.z=-this.z,t};var s=new o,r=new o;o.prototype.tangents=function(t,e){var i=this.norm();if(i>0){var o=s,n=1/i;o.set(this.x*n,this.y*n,this.z*n);var a=r;Math.abs(o.x)<.9?(a.set(1,0,0),o.cross(a,t)):(a.set(0,1,0),o.cross(a,t)),o.cross(t,e)}else t.set(1,0,0),e.set(0,1,0)},o.prototype.toString=function(){return this.x+","+this.y+","+this.z},o.prototype.toArray=function(){return[this.x,this.y,this.z]},o.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this},o.prototype.lerp=function(t,e,i){var o=this.x,n=this.y,s=this.z;i.x=o+(t.x-o)*e,i.y=n+(t.y-n)*e,i.z=s+(t.z-s)*e},o.prototype.almostEquals=function(t,e){return void 0===e&&(e=1e-6),Math.abs(this.x-t.x)>e||Math.abs(this.y-t.y)>e||Math.abs(this.z-t.z)>e?!1:!0},o.prototype.almostZero=function(t){return void 0===t&&(t=1e-6),Math.abs(this.x)>t||Math.abs(this.y)>t||Math.abs(this.z)>t?!1:!0};var a=new o;o.prototype.isAntiparallelTo=function(t,e){return this.negate(a),a.almostEquals(t,e)},o.prototype.clone=function(){return new o(this.x,this.y,this.z)}},function(t,e,i){function o(){this.id=o.idCounter++,this.type=0,this.boundingSphereRadius=0,this.collisionResponse=!0,this.material=null,this.body=null}t.exports=o;var o=i(2);i(1),i(3),i(13);o.prototype.constructor=o,o.prototype.updateBoundingSphereRadius=function(){throw"computeBoundingSphereRadius() not implemented for shape type "+this.type},o.prototype.volume=function(){throw"volume() not implemented for shape type "+this.type},o.prototype.calculateLocalInertia=function(t,e){throw"calculateLocalInertia() not implemented for shape type "+this.type},o.idCounter=0,o.types={SPHERE:1,PLANE:2,BOX:4,COMPOUND:8,CONVEXPOLYHEDRON:16,HEIGHTFIELD:32,PARTICLE:64,CYLINDER:128,TRIMESH:256}},function(t,e,i){function o(t,e,i,o){this.x=void 0!==t?t:0,this.y=void 0!==e?e:0,this.z=void 0!==i?i:0,this.w=void 0!==o?o:1}t.exports=o;var n=i(1);o.prototype.set=function(t,e,i,o){return this.x=t,this.y=e,this.z=i,this.w=o,this},o.prototype.toString=function(){return this.x+","+this.y+","+this.z+","+this.w},o.prototype.toArray=function(){return[this.x,this.y,this.z,this.w]},o.prototype.setFromAxisAngle=function(t,e){var i=Math.sin(.5*e);return this.x=t.x*i,this.y=t.y*i,this.z=t.z*i,this.w=Math.cos(.5*e),this},o.prototype.toAxisAngle=function(t){t=t||new n,this.normalize();var e=2*Math.acos(this.w),i=Math.sqrt(1-this.w*this.w);return.001>i?(t.x=this.x,t.y=this.y,t.z=this.z):(t.x=this.x/i,t.y=this.y/i,t.z=this.z/i),[t,e]};var s=new n,r=new n;o.prototype.setFromVectors=function(t,e){if(t.isAntiparallelTo(e)){var i=s,o=r;t.tangents(i,o),this.setFromAxisAngle(i,Math.PI)}else{var n=t.cross(e);this.x=n.x,this.y=n.y,this.z=n.z,this.w=Math.sqrt(Math.pow(t.norm(),2)*Math.pow(e.norm(),2))+t.dot(e),this.normalize()}return this};new n,new n,new n;o.prototype.mult=function(t,e){e=e||new o;var i=this.x,n=this.y,s=this.z,r=this.w,a=t.x,h=t.y,l=t.z,p=t.w;return e.x=i*p+r*a+n*l-s*h,e.y=n*p+r*h+s*a-i*l,e.z=s*p+r*l+i*h-n*a,e.w=r*p-i*a-n*h-s*l,e},o.prototype.inverse=function(t){var e=this.x,i=this.y,n=this.z,s=this.w;t=t||new o,this.conjugate(t);var r=1/(e*e+i*i+n*n+s*s);return t.x*=r,t.y*=r,t.z*=r,t.w*=r,t},o.prototype.conjugate=function(t){return t=t||new o,t.x=-this.x,t.y=-this.y,t.z=-this.z,t.w=this.w,t},o.prototype.normalize=function(){var t=Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w);return 0===t?(this.x=0,this.y=0,this.z=0,this.w=0):(t=1/t,this.x*=t,this.y*=t,this.z*=t,this.w*=t),this},o.prototype.normalizeFast=function(){var t=(3-(this.x*this.x+this.y*this.y+this.z*this.z+this.w*this.w))/2;return 0===t?(this.x=0,this.y=0,this.z=0,this.w=0):(this.x*=t,this.y*=t,this.z*=t,this.w*=t),this},o.prototype.vmult=function(t,e){e=e||new n;var i=t.x,o=t.y,s=t.z,r=this.x,a=this.y,h=this.z,l=this.w,p=l*i+a*s-h*o,c=l*o+h*i-r*s,u=l*s+r*o-a*i,d=-r*i-a*o-h*s;return e.x=p*l+d*-r+c*-h-u*-a,e.y=c*l+d*-a+u*-r-p*-h,e.z=u*l+d*-h+p*-a-c*-r,e},o.prototype.copy=function(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=t.w,this},o.prototype.toEuler=function(t,e){e=e||"YZX";var i,o,n,s=this.x,r=this.y,a=this.z,h=this.w;switch(e){case"YZX":var l=s*r+a*h;if(l>.499&&(i=2*Math.atan2(s,h),o=Math.PI/2,n=0),-.499>l&&(i=-2*Math.atan2(s,h),o=-Math.PI/2,n=0),isNaN(i)){var p=s*s,c=r*r,u=a*a;i=Math.atan2(2*r*h-2*s*a,1-2*c-2*u),o=Math.asin(2*l),n=Math.atan2(2*s*h-2*r*a,1-2*p-2*u)}break;default:throw new Error("Euler order "+e+" not supported yet.")}t.y=i,t.z=o,t.x=n},o.prototype.setFromEuler=function(t,e,i,o){o=o||"XYZ";var n=Math.cos(t/2),s=Math.cos(e/2),r=Math.cos(i/2),a=Math.sin(t/2),h=Math.sin(e/2),l=Math.sin(i/2);return"XYZ"===o?(this.x=a*s*r+n*h*l,this.y=n*h*r-a*s*l,this.z=n*s*l+a*h*r,this.w=n*s*r-a*h*l):"YXZ"===o?(this.x=a*s*r+n*h*l,this.y=n*h*r-a*s*l,this.z=n*s*l-a*h*r,this.w=n*s*r+a*h*l):"ZXY"===o?(this.x=a*s*r-n*h*l,this.y=n*h*r+a*s*l,this.z=n*s*l+a*h*r,this.w=n*s*r-a*h*l):"ZYX"===o?(this.x=a*s*r-n*h*l,this.y=n*h*r+a*s*l,this.z=n*s*l-a*h*r,this.w=n*s*r+a*h*l):"YZX"===o?(this.x=a*s*r+n*h*l,this.y=n*h*r+a*s*l,this.z=n*s*l-a*h*r,this.w=n*s*r-a*h*l):"XZY"===o&&(this.x=a*s*r-n*h*l,this.y=n*h*r-a*s*l,this.z=n*s*l+a*h*r,this.w=n*s*r+a*h*l),this},o.prototype.clone=function(){return new o(this.x,this.y,this.z,this.w)},o.prototype.slerp=function(t,e,i){i=i||new o;var n,s,r,a,h,l=this.x,p=this.y,c=this.z,u=this.w,d=t.x,v=t.y,y=t.z,f=t.w;return s=l*d+p*v+c*y+u*f,0>s&&(s=-s,d=-d,v=-v,y=-y,f=-f),1-s>1e-6?(n=Math.acos(s),r=Math.sin(n),a=Math.sin((1-e)*n)/r,h=Math.sin(e*n)/r):(a=1-e,h=e),i.x=a*l+h*d,i.y=a*p+h*v,i.z=a*c+h*y,i.w=a*u+h*f,i},o.prototype.integrate=function(t,e,i,n){n=n||new o;var s=t.x*i.x,r=t.y*i.y,a=t.z*i.z,h=this.x,l=this.y,p=this.z,c=this.w,u=.5*e;return n.x+=u*(s*c+r*p-a*l),n.y+=u*(r*c+a*h-s*p),n.z+=u*(a*c+s*l-r*h),n.w+=u*(-s*h-r*l-a*p),n}},function(t,e,i){function o(t){t=t||{},this.lowerBound=new n,t.lowerBound&&this.lowerBound.copy(t.lowerBound),this.upperBound=new n,t.upperBound&&this.upperBound.copy(t.upperBound)}var n=i(1);i(14);t.exports=o;var s=new n;o.prototype.setFromPoints=function(t,e,i,o){var n=this.lowerBound,r=this.upperBound,a=i;n.copy(t[0]),a&&a.vmult(n,n),r.copy(n);for(var h=1;hr.x&&(r.x=l.x),l.xr.y&&(r.y=l.y),l.yr.z&&(r.z=l.z),l.z=n.x&&e.y<=o.y&&i.y>=n.y&&e.z<=o.z&&i.z>=n.z},o.prototype.getCorners=function(t,e,i,o,n,s,r,a){var h=this.lowerBound,l=this.upperBound;t.copy(h),e.set(l.x,h.y,h.z),i.set(l.x,l.y,h.z),o.set(h.x,l.y,l.z),n.set(l.x,h.y,h.z),s.set(h.x,l.y,h.z),r.set(h.x,h.y,l.z),a.copy(l)};var r=[new n,new n,new n,new n,new n,new n,new n,new n];o.prototype.toLocalFrame=function(t,e){var i=r,o=i[0],n=i[1],s=i[2],a=i[3],h=i[4],l=i[5],p=i[6],c=i[7];this.getCorners(o,n,s,a,h,l,p,c);for(var u=0;8!==u;u++){var d=i[u];t.pointToLocal(d,d)}return e.setFromPoints(i)},o.prototype.toWorldFrame=function(t,e){var i=r,o=i[0],n=i[1],s=i[2],a=i[3],h=i[4],l=i[5],p=i[6],c=i[7];this.getCorners(o,n,s,a,h,l,p,c);for(var u=0;8!==u;u++){var d=i[u];t.pointToWorld(d,d)}return e.setFromPoints(i)},o.prototype.overlapsRay=function(t){var e=1/t._direction.x,i=1/t._direction.y,o=1/t._direction.z,n=(this.lowerBound.x-t.from.x)*e,s=(this.upperBound.x-t.from.x)*e,r=(this.lowerBound.y-t.from.y)*i,a=(this.upperBound.y-t.from.y)*i,h=(this.lowerBound.z-t.from.z)*o,l=(this.upperBound.z-t.from.z)*o,p=Math.max(Math.max(Math.min(n,s),Math.min(r,a)),Math.min(h,l)),c=Math.min(Math.min(Math.max(n,s),Math.max(r,a)),Math.max(h,l));return 0>c?!1:p>c?!1:!0}},function(t,e,i){function o(t,e,i){i="undefined"!=typeof i?i:1e6,n.call(this,t,e,0,i),this.restitution=0,this.ri=new s,this.rj=new s,this.ni=new s}t.exports=o;var n=i(9),s=i(1);i(6);o.prototype=new n,o.prototype.constructor=o;var r=new s,a=new s,h=new s;o.prototype.computeB=function(t){var e=this.a,i=this.b,o=this.bi,n=this.bj,s=this.ri,l=this.rj,p=r,c=a,u=o.velocity,d=o.angularVelocity,v=(o.force,o.torque,n.velocity),y=n.angularVelocity,f=(n.force,n.torque,h),m=this.jacobianElementA,w=this.jacobianElementB,g=this.ni;s.cross(g,p),l.cross(g,c),g.negate(m.spatial),p.negate(m.rotational),w.spatial.copy(g),w.rotational.copy(c),f.copy(n.position),f.vadd(l,f),f.vsub(o.position,f),f.vsub(s,f);var x=g.dot(f),b=this.restitution+1,B=b*v.dot(g)-b*u.dot(g)+y.dot(c)-d.dot(p),A=this.computeGiMf(),E=-x*e-B*i-t*A;return E};var l=new s,p=new s,c=new s,u=new s,d=new s;o.prototype.getImpactVelocityAlongNormal=function(){var t=l,e=p,i=c,o=u,n=d;return this.bi.position.vadd(this.ri,i),this.bj.position.vadd(this.rj,o),this.bi.getVelocityAtWorldPoint(i,t),this.bj.getVelocityAtWorldPoint(o,e),t.vsub(e,n),this.ni.dot(n)}},function(t,e,i){function o(t){t?this.elements=t:this.elements=[0,0,0,0,0,0,0,0,0]}t.exports=o;var n=i(1);o.prototype.identity=function(){var t=this.elements;t[0]=1,t[1]=0,t[2]=0,t[3]=0,t[4]=1,t[5]=0,t[6]=0,t[7]=0,t[8]=1},o.prototype.setZero=function(){var t=this.elements;t[0]=0,t[1]=0,t[2]=0,t[3]=0,t[4]=0,t[5]=0,t[6]=0,t[7]=0,t[8]=0},o.prototype.setTrace=function(t){var e=this.elements;e[0]=t.x,e[4]=t.y,e[8]=t.z},o.prototype.getTrace=function(t){var t=t||new n,e=this.elements;t.x=e[0],t.y=e[4],t.z=e[8]},o.prototype.vmult=function(t,e){e=e||new n;var i=this.elements,o=t.x,s=t.y,r=t.z;return e.x=i[0]*o+i[1]*s+i[2]*r,e.y=i[3]*o+i[4]*s+i[5]*r,e.z=i[6]*o+i[7]*s+i[8]*r,e},o.prototype.smult=function(t){for(var e=0;en;n++)for(var s=0;3>s;s++){for(var r=0,a=0;3>a;a++)r+=t.elements[n+3*a]*this.elements[a+3*s];i.elements[n+3*s]=r}return i},o.prototype.scale=function(t,e){e=e||new o;for(var i=this.elements,n=e.elements,s=0;3!==s;s++)n[3*s+0]=t.x*i[3*s+0],n[3*s+1]=t.y*i[3*s+1],n[3*s+2]=t.z*i[3*s+2];return e},o.prototype.solve=function(t,e){e=e||new n;for(var i=3,o=4,s=[],r=0;i*o>r;r++)s.push(0);var r,a;for(r=0;3>r;r++)for(a=0;3>a;a++)s[r+o*a]=this.elements[r+3*a];s[3]=t.x,s[7]=t.y,s[11]=t.z;var h,l,p=3,c=p,u=4;do{if(r=c-p,0===s[r+o*r])for(a=r+1;c>a;a++)if(0!==s[r+o*a]){h=u;do l=u-h,s[l+o*r]+=s[l+o*a];while(--h);break}if(0!==s[r+o*r])for(a=r+1;c>a;a++){var d=s[r+o*a]/s[r+o*r];h=u;do l=u-h,s[l+o*a]=r>=l?0:s[l+o*a]-s[l+o*r]*d;while(--h)}}while(--p);if(e.z=s[2*o+3]/s[2*o+2],e.y=(s[1*o+3]-s[1*o+2]*e.z)/s[1*o+1],e.x=(s[0*o+3]-s[0*o+2]*e.z-s[0*o+1]*e.y)/s[0*o+0],isNaN(e.x)||isNaN(e.y)||isNaN(e.z)||e.x===1/0||e.y===1/0||e.z===1/0)throw"Could not solve equation! Got x=["+e.toString()+"], b=["+t.toString()+"], A=["+this.toString()+"]";return e},o.prototype.e=function(t,e,i){return void 0===i?this.elements[e+3*t]:void(this.elements[e+3*t]=i)},o.prototype.copy=function(t){for(var e=0;ei;i++)t+=this.elements[i]+e;return t},o.prototype.reverse=function(t){t=t||new o;for(var e=3,i=6,n=[],s=0;e*i>s;s++)n.push(0);var s,r;for(s=0;3>s;s++)for(r=0;3>r;r++)n[s+i*r]=this.elements[s+3*r];n[3]=1,n[9]=0,n[15]=0,n[4]=0,n[10]=1,n[16]=0,n[5]=0,n[11]=0,n[17]=1;var a,h,l=3,p=l,c=i;do{if(s=p-l,0===n[s+i*s])for(r=s+1;p>r;r++)if(0!==n[s+i*r]){a=c;do h=c-a,n[h+i*s]+=n[h+i*r];while(--a);break}if(0!==n[s+i*s])for(r=s+1;p>r;r++){var u=n[s+i*r]/n[s+i*s];a=c;do h=c-a,n[h+i*r]=s>=h?0:n[h+i*r]-n[h+i*s]*u;while(--a)}}while(--l);s=2;do{r=s-1;do{var u=n[s+i*r]/n[s+i*s];a=i;do h=i-a,n[h+i*r]=n[h+i*r]-n[h+i*s]*u;while(--a)}while(r--)}while(--s);s=2;do{var u=1/n[s+i*s];a=i;do h=i-a,n[h+i*s]=n[h+i*s]*u;while(--a)}while(s--);s=2;do{r=2;do{if(h=n[e+r+i*s],isNaN(h)||h===1/0)throw"Could not reverse! A=["+this.toString()+"]";t.e(s,r,h)}while(r--)}while(s--);return t},o.prototype.setRotationFromQuaternion=function(t){var e=t.x,i=t.y,o=t.z,n=t.w,s=e+e,r=i+i,a=o+o,h=e*s,l=e*r,p=e*a,c=i*r,u=i*a,d=o*a,v=n*s,y=n*r,f=n*a,m=this.elements;return m[0]=1-(c+d),m[1]=l-f,m[2]=p+y,m[3]=l+f,m[4]=1-(h+d),m[5]=u-v,m[6]=p-y,m[7]=u+v,m[8]=1-(h+c),this},o.prototype.transpose=function(t){t=t||new o;for(var e=t.elements,i=this.elements,n=0;3!==n;n++)for(var s=0;3!==s;s++)e[3*n+s]=i[3*s+n];return t}},function(t,e,i){function o(t){t=t||{},n.apply(this),this.id=o.idCounter++,this.world=null,this.preStep=null,this.postStep=null,this.vlambda=new s,this.collisionFilterGroup="number"==typeof t.collisionFilterGroup?t.collisionFilterGroup:1,this.collisionFilterMask="number"==typeof t.collisionFilterMask?t.collisionFilterMask:1,this.collisionResponse=!0,this.position=new s,this.previousPosition=new s,this.interpolatedPosition=new s,this.initPosition=new s,t.position&&(this.position.copy(t.position),this.previousPosition.copy(t.position),this.interpolatedPosition.copy(t.position),this.initPosition.copy(t.position)),this.velocity=new s,t.velocity&&this.velocity.copy(t.velocity),this.initVelocity=new s,this.force=new s;var e="number"==typeof t.mass?t.mass:0;this.mass=e,this.invMass=e>0?1/e:0,this.material=t.material||null,this.linearDamping="number"==typeof t.linearDamping?t.linearDamping:.01,this.type=0>=e?o.STATIC:o.DYNAMIC,typeof t.type==typeof o.STATIC&&(this.type=t.type),this.allowSleep="undefined"!=typeof t.allowSleep?t.allowSleep:!0,this.sleepState=0,this.sleepSpeedLimit="undefined"!=typeof t.sleepSpeedLimit?t.sleepSpeedLimit:.1,this.sleepTimeLimit="undefined"!=typeof t.sleepTimeLimit?t.sleepTimeLimit:1,this.timeLastSleepy=0,this._wakeUpAfterNarrowphase=!1,this.torque=new s,this.quaternion=new a,this.initQuaternion=new a,this.previousQuaternion=new a,this.interpolatedQuaternion=new a,t.quaternion&&(this.quaternion.copy(t.quaternion),this.initQuaternion.copy(t.quaternion),this.previousQuaternion.copy(t.quaternion),this.interpolatedQuaternion.copy(t.quaternion)),this.angularVelocity=new s,t.angularVelocity&&this.angularVelocity.copy(t.angularVelocity),this.initAngularVelocity=new s,this.shapes=[],this.shapeOffsets=[],this.shapeOrientations=[],this.inertia=new s,this.invInertia=new s,this.invInertiaWorld=new r,this.invMassSolve=0,this.invInertiaSolve=new s,this.invInertiaWorldSolve=new r,this.fixedRotation="undefined"!=typeof t.fixedRotation?t.fixedRotation:!1,this.angularDamping="undefined"!=typeof t.angularDamping?t.angularDamping:.01,this.linearFactor=new s(1,1,1),t.linearFactor&&this.linearFactor.copy(t.linearFactor),this.angularFactor=new s(1,1,1),t.angularFactor&&this.angularFactor.copy(t.angularFactor),this.aabb=new h,this.aabbNeedsUpdate=!0,this.wlambda=new s,t.shape&&this.addShape(t.shape),this.updateMassProperties()}t.exports=o;var n=i(23),s=(i(2),i(1)),r=i(6),a=i(3),h=(i(13),i(4)),l=i(19);o.prototype=new n,o.prototype.constructor=o,o.COLLIDE_EVENT_NAME="collide",o.DYNAMIC=1,o.STATIC=2,o.KINEMATIC=4,o.AWAKE=0,o.SLEEPY=1,o.SLEEPING=2,o.idCounter=0,o.wakeupEvent={type:"wakeup"},o.prototype.wakeUp=function(){var t=this.sleepState;this.sleepState=0,this._wakeUpAfterNarrowphase=!1,t===o.SLEEPING&&this.dispatchEvent(o.wakeupEvent)},o.prototype.sleep=function(){this.sleepState=o.SLEEPING,this.velocity.set(0,0,0),this.angularVelocity.set(0,0,0),this._wakeUpAfterNarrowphase=!1},o.sleepyEvent={type:"sleepy"},o.sleepEvent={type:"sleep"},o.prototype.sleepTick=function(t){if(this.allowSleep){var e=this.sleepState,i=this.velocity.norm2()+this.angularVelocity.norm2(),n=Math.pow(this.sleepSpeedLimit,2);e===o.AWAKE&&n>i?(this.sleepState=o.SLEEPY,this.timeLastSleepy=t,this.dispatchEvent(o.sleepyEvent)):e===o.SLEEPY&&i>n?this.wakeUp():e===o.SLEEPY&&t-this.timeLastSleepy>this.sleepTimeLimit&&(this.sleep(),this.dispatchEvent(o.sleepEvent))}},o.prototype.updateSolveMassProperties=function(){this.sleepState===o.SLEEPING||this.type===o.KINEMATIC?(this.invMassSolve=0,this.invInertiaSolve.setZero(),this.invInertiaWorldSolve.setZero()):(this.invMassSolve=this.invMass,this.invInertiaSolve.copy(this.invInertia),this.invInertiaWorldSolve.copy(this.invInertiaWorld))},o.prototype.pointToLocalFrame=function(t,e){var e=e||new s;return t.vsub(this.position,e),this.quaternion.conjugate().vmult(e,e),e},o.prototype.vectorToLocalFrame=function(t,e){var e=e||new s;return this.quaternion.conjugate().vmult(t,e),e},o.prototype.pointToWorldFrame=function(t,e){var e=e||new s;return this.quaternion.vmult(t,e),e.vadd(this.position,e),e},o.prototype.vectorToWorldFrame=function(t,e){var e=e||new s;return this.quaternion.vmult(t,e),e};var p=new s,c=new a;o.prototype.addShape=function(t,e,i){var o=new s,n=new a;return e&&o.copy(e),i&&n.copy(i),this.shapes.push(t),this.shapeOffsets.push(o),this.shapeOrientations.push(n),this.updateMassProperties(),this.updateBoundingRadius(),this.aabbNeedsUpdate=!0,t.body=this,this},o.prototype.updateBoundingRadius=function(){for(var t=this.shapes,e=this.shapeOffsets,i=t.length,o=0,n=0;n!==i;n++){var s=t[n];s.updateBoundingSphereRadius();var r=e[n].norm(),a=s.boundingSphereRadius;r+a>o&&(o=r+a)}this.boundingRadius=o};var u=new h;o.prototype.computeAABB=function(){for(var t=this.shapes,e=this.shapeOffsets,i=this.shapeOrientations,o=t.length,n=p,s=c,r=this.quaternion,a=this.aabb,h=u,l=0;l!==o;l++){var d=t[l];r.vmult(e[l],n),n.vadd(this.position,n),i[l].mult(r,s),d.calculateWorldAABB(n,s,h.lowerBound,h.upperBound),0===l?a.copy(h):a.extend(h)}this.aabbNeedsUpdate=!1};var d=new r,v=new r;new r;o.prototype.updateInertiaWorld=function(t){var e=this.invInertia;if(e.x!==e.y||e.y!==e.z||t){var i=d,o=v;i.setRotationFromQuaternion(this.quaternion),i.transpose(o),i.scale(e,i),i.mmult(o,this.invInertiaWorld)}else;};var y=(new s,new s);o.prototype.applyForce=function(t,e){if(this.type===o.DYNAMIC){var i=y;e.cross(t,i),this.force.vadd(t,this.force),this.torque.vadd(i,this.torque)}};var f=new s,m=new s;o.prototype.applyLocalForce=function(t,e){if(this.type===o.DYNAMIC){var i=f,n=m;this.vectorToWorldFrame(t,i),this.vectorToWorldFrame(e,n),this.applyForce(i,n)}};var w=(new s,new s),g=new s;o.prototype.applyImpulse=function(t,e){if(this.type===o.DYNAMIC){var i=e,n=w;n.copy(t),n.mult(this.invMass,n),this.velocity.vadd(n,this.velocity);var s=g;i.cross(t,s),this.invInertiaWorld.vmult(s,s),this.angularVelocity.vadd(s,this.angularVelocity)}};var x=new s,b=new s;o.prototype.applyLocalImpulse=function(t,e){if(this.type===o.DYNAMIC){var i=x,n=b;this.vectorToWorldFrame(t,i),this.vectorToWorldFrame(e,n),this.applyImpulse(i,n)}};var B=new s;o.prototype.updateMassProperties=function(){var t=B;this.invMass=this.mass>0?1/this.mass:0;var e=this.inertia,i=this.fixedRotation;this.computeAABB(),t.set((this.aabb.upperBound.x-this.aabb.lowerBound.x)/2,(this.aabb.upperBound.y-this.aabb.lowerBound.y)/2,(this.aabb.upperBound.z-this.aabb.lowerBound.z)/2),l.calculateInertia(t,this.mass,e),this.invInertia.set(e.x>0&&!i?1/e.x:0,e.y>0&&!i?1/e.y:0,e.z>0&&!i?1/e.z:0),this.updateInertiaWorld(!0)},o.prototype.getVelocityAtWorldPoint=function(t,e){var i=new s;return t.vsub(this.position,i),this.angularVelocity.cross(i,e),this.velocity.vadd(e,e),e};new s,new s,new a,new a;o.prototype.integrate=function(t,e,i){if(this.previousPosition.copy(this.position),this.previousQuaternion.copy(this.quaternion),(this.type===o.DYNAMIC||this.type===o.KINEMATIC)&&this.sleepState!==o.SLEEPING){var n=this.velocity,s=this.angularVelocity,r=this.position,a=this.force,h=this.torque,l=this.quaternion,p=this.invMass,c=this.invInertiaWorld,u=this.linearFactor,d=p*t;n.x+=a.x*d*u.x,n.y+=a.y*d*u.y,n.z+=a.z*d*u.z;var v=c.elements,y=this.angularFactor,f=h.x*y.x,m=h.y*y.y,w=h.z*y.z;s.x+=t*(v[0]*f+v[1]*m+v[2]*w),s.y+=t*(v[3]*f+v[4]*m+v[5]*w),s.z+=t*(v[6]*f+v[7]*m+v[8]*w),r.x+=n.x*t,r.y+=n.y*t,r.z+=n.z*t,l.integrate(this.angularVelocity,t,this.angularFactor,l),e&&(i?l.normalizeFast():l.normalize()),this.aabbNeedsUpdate=!0,this.updateInertiaWorld()}}},function(t,e,i){function o(t,e,i){i=n.defaults(i,{collideConnected:!0,wakeUpBodies:!0}),this.equations=[],this.bodyA=t,this.bodyB=e,this.id=o.idCounter++,this.collideConnected=i.collideConnected,i.wakeUpBodies&&(t&&t.wakeUp(),e&&e.wakeUp())}t.exports=o;var n=i(14);o.prototype.update=function(){throw new Error("method update() not implmemented in this Constraint subclass!")},o.prototype.enable=function(){for(var t=this.equations,e=0;ed&&(d=y,u=v)}for(var f=[],m=i.faces[u],w=m.length,g=0;w>g;g++){var x=i.vertices[m[g]],b=new s;b.copy(x),n.vmult(b,b),o.vadd(b,b),f.push(b)}u>=0&&this.clipFaceAgainstHull(r,t,e,f,a,h,l)};var c=new s,u=new s,d=new s,v=new s,y=new s,f=new s;o.prototype.findSeparatingAxis=function(t,e,i,o,n,s,r,a){var h=c,l=u,p=d,m=v,w=y,g=f,x=Number.MAX_VALUE,b=this,B=0;if(b.uniqueAxes)for(var A=0;A!==b.uniqueAxes.length;A++){i.vmult(b.uniqueAxes[A],h);var E=b.testSepAxis(h,t,e,i,o,n);if(E===!1)return!1;x>E&&(x=E,s.copy(h))}else for(var z=r?r.length:b.faces.length,A=0;z>A;A++){var S=r?r[A]:A;h.copy(b.faceNormals[S]),i.vmult(h,h);var E=b.testSepAxis(h,t,e,i,o,n);if(E===!1)return!1;x>E&&(x=E,s.copy(h))}if(t.uniqueAxes)for(var A=0;A!==t.uniqueAxes.length;A++){n.vmult(t.uniqueAxes[A],l),B++;var E=b.testSepAxis(l,t,e,i,o,n);if(E===!1)return!1;x>E&&(x=E,s.copy(l))}else for(var M=a?a.length:t.faces.length,A=0;M>A;A++){var S=a?a[A]:A;l.copy(t.faceNormals[S]),n.vmult(l,l),B++;var E=b.testSepAxis(l,t,e,i,o,n);if(E===!1)return!1;x>E&&(x=E,s.copy(l))}for(var C=0;C!==b.uniqueEdges.length;C++){i.vmult(b.uniqueEdges[C],m);for(var F=0;F!==t.uniqueEdges.length;F++)if(n.vmult(t.uniqueEdges[F],w),m.cross(w,g),!g.almostZero()){g.normalize();var R=b.testSepAxis(g,t,e,i,o,n);if(R===!1)return!1;x>R&&(x=R,s.copy(g))}}return o.vsub(e,p),p.dot(s)>0&&s.negate(s),!0};var m=[],w=[];o.prototype.testSepAxis=function(t,e,i,n,s,r){var a=this;o.project(a,t,i,n,m),o.project(e,t,s,r,w);var h=m[0],l=m[1],p=w[0],c=w[1];if(c>h||l>p)return!1;var u=h-c,d=p-l,v=d>u?u:d;return v};var g=new s,x=new s;o.prototype.calculateLocalInertia=function(t,e){this.computeLocalAABB(g,x);var i=x.x-g.x,o=x.y-g.y,n=x.z-g.z;e.x=1/12*t*(2*o*2*o+2*n*2*n),e.y=1/12*t*(2*i*2*i+2*n*2*n),e.z=1/12*t*(2*o*2*o+2*i*2*i)},o.prototype.getPlaneConstantOfFace=function(t){var e=this.faces[t],i=this.faceNormals[t],o=this.vertices[e[0]],n=-i.dot(o);return n};var b=new s,B=new s,A=new s,E=new s,z=new s,S=new s,M=new s,C=new s;o.prototype.clipFaceAgainstHull=function(t,e,i,o,n,s,r){for(var a=b,h=B,l=A,p=E,c=z,u=S,d=M,v=C,y=this,f=[],m=o,w=f,g=-1,x=Number.MAX_VALUE,F=0;FR&&(x=R,g=F)}if(!(0>g)){var T=y.faces[g];T.connectedFaces=[];for(var I=0;Iq;q++){var L=y.vertices[T[q]],W=y.vertices[T[(q+1)%P]];L.vsub(W,h),l.copy(h),i.vmult(l,l),e.vadd(l,l),p.copy(this.faceNormals[g]),i.vmult(p,p),e.vadd(p,p),l.cross(p,c),c.negate(c),u.copy(L),i.vmult(u,u),e.vadd(u,u);var j,V=(-u.dot(c),T.connectedFaces[q]);d.copy(this.faceNormals[V]);var k=this.getPlaneConstantOfFace(V);v.copy(d),i.vmult(v,v); 2 | var j=k-v.dot(e);for(this.clipFaceAgainstPlane(m,w,v,j);m.length;)m.shift();for(;w.length;)m.push(w.shift())}d.copy(this.faceNormals[g]);var k=this.getPlaneConstantOfFace(g);v.copy(d),i.vmult(v,v);for(var j=k-v.dot(e),I=0;I=O&&(console.log("clamped: depth="+O+" to minDist="+(n+"")),O=n),s>=O){var _=m[I];if(0>=O){var D={point:_,normal:v,depth:O};r.push(D)}}}}},o.prototype.clipFaceAgainstPlane=function(t,e,i,o){var n,r,a=t.length;if(2>a)return e;var h=t[t.length-1],l=t[0];n=i.dot(h)+o;for(var p=0;a>p;p++){if(l=t[p],r=i.dot(l)+o,0>n)if(0>r){var c=new s;c.copy(l),e.push(c)}else{var c=new s;h.lerp(l,n/(n-r),c),e.push(c)}else if(0>r){var c=new s;h.lerp(l,n/(n-r),c),e.push(c),e.push(l)}h=l,n=r}return e},o.prototype.computeWorldVertices=function(t,e){for(var i=this.vertices.length;this.worldVertices.lengthn;n++){var s=o[n];s.xe.x&&(e.x=s.x),s.ye.y&&(e.y=s.y),s.ze.z&&(e.z=s.z)}},o.prototype.computeWorldFaceNormals=function(t){for(var e=this.faceNormals.length;this.worldFaceNormals.lengtht&&(t=n)}this.boundingSphereRadius=Math.sqrt(t)};var F=new s;o.prototype.calculateWorldAABB=function(t,e,i,o){for(var n,s,r,a,h,l,p=this.vertices.length,c=this.vertices,u=0;p>u;u++){F.copy(c[u]),e.vmult(F,F),t.vadd(F,F);var d=F;d.xa||void 0===a)&&(a=d.x),d.yh||void 0===h)&&(h=d.y),d.zl||void 0===l)&&(l=d.z)}i.set(n,s,r),o.set(a,h,l)},o.prototype.volume=function(){return 4*Math.PI*this.boundingSphereRadius/3},o.prototype.getAveragePointLocal=function(t){t=t||new s;for(var e=this.vertices.length,i=this.vertices,o=0;e>o;o++)t.vadd(i[o],t);return t.mult(1/e,t),t},o.prototype.transformAllPoints=function(t,e){var i=this.vertices.length,o=this.vertices;if(e){for(var n=0;i>n;n++){var s=o[n];e.vmult(s,s)}for(var n=0;nn;n++){var s=o[n];s.vadd(t,s)}};var R=new s,T=new s,I=new s;o.prototype.pointIsInside=function(t){var e=this.vertices.length,i=this.vertices,o=this.faces,n=this.faceNormals,s=null,r=this.faces.length,a=R;this.getAveragePointLocal(a);for(var h=0;r>h;h++){var e=(this.faces[h].length,n[h]),l=i[o[h][0]],p=T;t.vsub(l,p);var c=e.dot(p),u=I;a.vsub(l,u);var d=e.dot(u);if(0>c&&d>0||c>0&&0>d)return!1}return s?1:-1};var N=(new s,new s),P=new s;o.project=function(t,e,i,o,n){var s=t.vertices.length,a=N,h=0,l=0,p=P,c=t.vertices;p.setZero(),r.vectorToLocalFrame(i,o,e,a),r.pointToLocalFrame(i,o,p,p);var u=p.dot(a);l=h=c[0].dot(a);for(var d=1;s>d;d++){var v=c[d].dot(a);v>h&&(h=v),l>v&&(l=v)}if(l-=u,h-=u,l>h){var y=l;l=h,h=y}n[0]=h,n[1]=l}},function(t,e,i){function o(){this.rayFromWorld=new n,this.rayToWorld=new n,this.hitNormalWorld=new n,this.hitPointWorld=new n,this.hasHit=!1,this.shape=null,this.body=null,this.hitFaceIndex=-1,this.distance=-1,this._shouldStop=!1}var n=i(1);t.exports=o,o.prototype.reset=function(){this.rayFromWorld.setZero(),this.rayToWorld.setZero(),this.hitNormalWorld.setZero(),this.hitPointWorld.setZero(),this.hasHit=!1,this.shape=null,this.body=null,this.hitFaceIndex=-1,this.distance=-1,this._shouldStop=!1},o.prototype.abort=function(){this._shouldStop=!0},o.prototype.set=function(t,e,i,o,n,s,r){this.rayFromWorld.copy(t),this.rayToWorld.copy(e),this.hitNormalWorld.copy(i),this.hitPointWorld.copy(o),this.shape=n,this.body=s,this.distance=r}},function(t,e){function i(t){var e="";t=t||{},"string"==typeof t?(e=t,t={}):"object"==typeof t&&(e=""),this.name=e,this.id=i.idCounter++,this.friction="undefined"!=typeof t.friction?t.friction:-1,this.restitution="undefined"!=typeof t.restitution?t.restitution:-1}t.exports=i,i.idCounter=0},function(t,e){function i(){}t.exports=i,i.defaults=function(t,e){t=t||{};for(var i in e)i in t||(t[i]=e[i]);return t}},function(t,e,i){function o(){this.world=null,this.useBoundingBoxes=!1,this.dirty=!0}var n=i(7),s=i(1),r=i(3);i(2),i(29);t.exports=o,o.prototype.collisionPairs=function(t,e,i){throw new Error("collisionPairs not implemented for this BroadPhase class!")},o.prototype.needBroadphaseCollision=function(t,e){return 0===(t.collisionFilterGroup&e.collisionFilterMask)||0===(e.collisionFilterGroup&t.collisionFilterMask)?!1:0===(t.type&n.STATIC)&&t.sleepState!==n.SLEEPING||0===(e.type&n.STATIC)&&e.sleepState!==n.SLEEPING?!0:!1},o.prototype.intersectionTest=function(t,e,i,o){this.useBoundingBoxes?this.doBoundingBoxBroadphase(t,e,i,o):this.doBoundingSphereBroadphase(t,e,i,o)};var a=new s;new s,new r,new s;o.prototype.doBoundingSphereBroadphase=function(t,e,i,o){var n=a;e.position.vsub(t.position,n);var s=Math.pow(t.boundingRadius+e.boundingRadius,2),r=n.norm2();s>r&&(i.push(t),o.push(e))},o.prototype.doBoundingBoxBroadphase=function(t,e,i,o){t.aabbNeedsUpdate&&t.computeAABB(),e.aabbNeedsUpdate&&e.computeAABB(),t.aabb.overlaps(e.aabb)&&(i.push(t),o.push(e))};var h={keys:[]},l=[],p=[];o.prototype.makePairsUnique=function(t,e){for(var i=h,o=l,n=p,s=t.length,r=0;r!==s;r++)o[r]=t[r],n[r]=e[r];t.length=0,e.length=0;for(var r=0;r!==s;r++){var a=o[r].id,c=n[r].id,u=c>a?a+","+c:c+","+a;i[u]=r,i.keys.push(u)}for(var r=0;r!==i.keys.length;r++){var u=i.keys.pop(),d=i[u];t.push(o[d]),e.push(n[d]),delete i[u]}},o.prototype.setWorld=function(t){};var c=new s;o.boundingSphereCheck=function(t,e){var i=c;return t.position.vsub(e.position,i),Math.pow(t.shape.boundingSphereRadius+e.shape.boundingSphereRadius,2)>i.norm2()},o.prototype.aabbQuery=function(t,e,i){return console.warn(".aabbQuery is not implemented in this Broadphase subclass."),[]}},function(t,e,i){function o(t,e){this.from=t?t.clone():new r,this.to=e?e.clone():new r,this._direction=new r,this.precision=1e-4,this.checkCollisionResponse=!0,this.skipBackfaces=!1,this.collisionFilterMask=-1,this.collisionFilterGroup=-1,this.mode=o.ANY,this.result=new l,this.hasHit=!1,this.callback=function(t){}}function n(t,e,i,o){o.vsub(e,j),i.vsub(e,v),t.vsub(e,y);var n,s,r=j.dot(j),a=j.dot(v),h=j.dot(y),l=v.dot(v),p=v.dot(y);return(n=l*h-a*p)>=0&&(s=r*p-a*h)>=0&&r*l-a*a>n+s}function s(t,e,i){i.vsub(t,j);var o=j.dot(e);e.mult(o,V),V.vadd(t,V);var n=i.distanceTo(V);return n}t.exports=o;var r=i(1),a=i(3),h=i(10),l=(i(11),i(19),i(12)),p=i(2),c=i(4);o.prototype.constructor=o,o.CLOSEST=1,o.ANY=2,o.ALL=4;var u=new c,d=[];o.prototype.intersectWorld=function(t,e){return this.mode=e.mode||o.ANY,this.result=e.result||new l,this.skipBackfaces=!!e.skipBackfaces,this.collisionFilterMask="undefined"!=typeof e.collisionFilterMask?e.collisionFilterMask:-1,this.collisionFilterGroup="undefined"!=typeof e.collisionFilterGroup?e.collisionFilterGroup:-1,e.from&&this.from.copy(e.from),e.to&&this.to.copy(e.to),this.callback=e.callback||function(){},this.hasHit=!1,this.result.reset(),this._updateDirection(),this.getAABB(u),d.length=0,t.broadphase.aabbQuery(t,u,d),this.intersectBodies(d),this.hasHit};var v=new r,y=new r;o.pointInTriangle=n;var f=new r,m=new a;o.prototype.intersectBody=function(t,e){e&&(this.result=e,this._updateDirection());var i=this.checkCollisionResponse;if((!i||t.collisionResponse)&&0!==(this.collisionFilterGroup&t.collisionFilterMask)&&0!==(t.collisionFilterGroup&this.collisionFilterMask))for(var o=f,n=m,s=0,r=t.shapes.length;r>s;s++){var a=t.shapes[s];if((!i||a.collisionResponse)&&(t.quaternion.mult(t.shapeOrientations[s],n),t.quaternion.vmult(t.shapeOffsets[s],o),o.vadd(t.position,o),this.intersectShape(a,n,o,t),this.result._shouldStop))break}},o.prototype.intersectBodies=function(t,e){e&&(this.result=e,this._updateDirection());for(var i=0,o=t.length;!this.result._shouldStop&&o>i;i++)this.intersectBody(t[i])},o.prototype._updateDirection=function(){this.to.vsub(this.from,this._direction),this._direction.normalize()},o.prototype.intersectShape=function(t,e,i,o){var n=this.from,r=s(n,this._direction,i);if(!(r>t.boundingSphereRadius)){var a=this[t.type];a&&a.call(this,t,e,i,o,t)}};var w=(new r,new r,new r),g=new r,x=new r,b=new r;new r,new l;o.prototype.intersectBox=function(t,e,i,o,n){return this.intersectConvex(t.convexPolyhedronRepresentation,e,i,o,n)},o.prototype[p.types.BOX]=o.prototype.intersectBox,o.prototype.intersectPlane=function(t,e,i,o,n){var s=this.from,a=this.to,h=this._direction,l=new r(0,0,1);e.vmult(l,l);var p=new r;s.vsub(i,p);var c=p.dot(l);a.vsub(i,p);var u=p.dot(l);if(!(c*u>0||s.distanceTo(a)v;v++)for(var y=a;p>y;y++){if(this.result._shouldStop)return;if(t.getAabbAtIndex(v,y,d),d.overlapsRay(s)){if(t.getConvexTrianglePillar(v,y,!1),h.pointToWorldFrame(i,e,t.pillarOffset,A),this.intersectConvex(t.pillarConvex,e,A,o,n,B),this.result._shouldStop)return;t.getConvexTrianglePillar(v,y,!0),h.pointToWorldFrame(i,e,t.pillarOffset,A),this.intersectConvex(t.pillarConvex,e,A,o,n,B)}}},o.prototype[p.types.HEIGHTFIELD]=o.prototype.intersectHeightfield;var S=new r,M=new r;o.prototype.intersectSphere=function(t,e,i,o,n){var s=this.from,r=this.to,a=t.radius,h=Math.pow(r.x-s.x,2)+Math.pow(r.y-s.y,2)+Math.pow(r.z-s.z,2),l=2*((r.x-s.x)*(s.x-i.x)+(r.y-s.y)*(s.y-i.y)+(r.z-s.z)*(s.z-i.z)),p=Math.pow(s.x-i.x,2)+Math.pow(s.y-i.y,2)+Math.pow(s.z-i.z,2)-Math.pow(a,2),c=Math.pow(l,2)-4*h*p,u=S,d=M;if(!(0>c))if(0===c)s.lerp(r,c,u),u.vsub(i,d),d.normalize(),this.reportIntersection(d,u,n,o,-1);else{var v=(-l-Math.sqrt(c))/(2*h),y=(-l+Math.sqrt(c))/(2*h);if(v>=0&&1>=v&&(s.lerp(r,v,u),u.vsub(i,d),d.normalize(),this.reportIntersection(d,u,n,o,-1)),this.result._shouldStop)return;y>=0&&1>=y&&(s.lerp(r,y,u),u.vsub(i,d),d.normalize(),this.reportIntersection(d,u,n,o,-1))}},o.prototype[p.types.SPHERE]=o.prototype.intersectSphere;var C=new r,F=(new r,new r,new r);o.prototype.intersectConvex=function(t,e,i,o,s,r){for(var a=C,h=F,l=r&&r.faceList||null,p=t.faces,c=t.vertices,u=t.faceNormals,d=this._direction,v=this.from,y=this.to,f=v.distanceTo(y),m=l?l.length:p.length,B=this.result,A=0;!B._shouldStop&&m>A;A++){var E=l?l[A]:A,z=p[E],S=u[E],M=e,R=i;h.copy(c[z[0]]),M.vmult(h,h),h.vadd(R,h),h.vsub(v,h),M.vmult(S,a);var T=d.dot(a);if(!(Math.abs(T)I)){d.mult(I,w),w.vadd(v,w),g.copy(c[z[0]]),M.vmult(g,g),R.vadd(g,g);for(var N=1;!B._shouldStop&&Nf||this.reportIntersection(a,w,s,o,E)}}}}},o.prototype[p.types.CONVEXPOLYHEDRON]=o.prototype.intersectConvex;var R=new r,T=new r,I=new r,N=new r,P=new r,q=new r,L=(new c,[]),W=new h;o.prototype.intersectTrimesh=function(t,e,i,o,s,r){var a=R,l=L,p=W,c=F,u=T,d=I,v=N,y=q,f=P,m=(r&&r.faceList||null,t.indices),B=(t.vertices,t.faceNormals,this.from),A=this.to,E=this._direction;p.position.copy(i),p.quaternion.copy(e),h.vectorToLocalFrame(i,e,E,u),h.pointToLocalFrame(i,e,B,d),h.pointToLocalFrame(i,e,A,v),v.x*=t.scale.x,v.y*=t.scale.y,v.z*=t.scale.z,d.x*=t.scale.x,d.y*=t.scale.y,d.z*=t.scale.z,v.vsub(d,u),u.normalize();var z=d.distanceSquared(v);t.tree.rayQuery(this,p,l);for(var S=0,M=l.length;!this.result._shouldStop&&S!==M;S++){var C=l[S];t.getNormal(C,a),t.getVertex(m[3*C],g),g.vsub(d,c);var j=u.dot(a),V=a.dot(c)/j;if(!(0>V)){u.scale(V,w),w.vadd(d,w),t.getVertex(m[3*C+1],x),t.getVertex(m[3*C+2],b);var k=w.distanceSquared(d);!n(w,x,g,b)&&!n(w,g,x,b)||k>z||(h.vectorToWorldFrame(e,a,f),h.pointToWorldFrame(i,e,w,y),this.reportIntersection(f,y,s,o,C))}}l.length=0},o.prototype[p.types.TRIMESH]=o.prototype.intersectTrimesh,o.prototype.reportIntersection=function(t,e,i,n,s){var r=this.from,a=this.to,h=r.distanceTo(e),l=this.result;if(!(this.skipBackfaces&&t.dot(this._direction)>0))switch(l.hitFaceIndex="undefined"!=typeof s?s:-1,this.mode){case o.ALL:this.hasHit=!0,l.set(r,a,t,e,i,n,h),l.hasHit=!0,this.callback(l);break;case o.CLOSEST:(hr;r++){var s=h[r];e.vmult(s,s),t.vadd(s,s);var a=s.x,l=s.y,p=s.z;a>o.x&&(o.x=a),l>o.y&&(o.y=l),p>o.z&&(o.z=p),ao;o++)i[o].call(this,t)}return this}}},function(t,e){function i(){this.matrix=[]}t.exports=i,i.prototype.get=function(t,e){if(t=t.index,e=e.index,e>t){var i=e;e=t,t=i}return this.matrix[(t*(t+1)>>1)+e-1]},i.prototype.set=function(t,e,i){if(t=t.index,e=e.index,e>t){var o=e;e=t,t=o}this.matrix[(t*(t+1)>>1)+e-1]=i?1:0},i.prototype.reset=function(){for(var t=0,e=this.matrix.length;t!==e;t++)this.matrix[t]=0},i.prototype.setNumObjects=function(t){this.matrix.length=t*(t-1)>>1}},function(t,e,i){function o(){n.apply(this)}t.exports=o;var n=i(15),s=i(4);o.prototype=new n,o.prototype.constructor=o,o.prototype.collisionPairs=function(t,e,i){var o,n,s,r,a=t.bodies,h=a.length;for(o=0;o!==h;o++)for(n=0;n!==o;n++)s=a[o],r=a[n],this.needBroadphaseCollision(s,r)&&this.intersectionTest(s,r,e,i)};new s;o.prototype.aabbQuery=function(t,e,i){i=i||[];for(var o=0;oA.maxForce&&(n=A.maxForce-p),B[M]+=n,h+=n>0?n:-n,A.addToWlambda(n)}if(d>h*h)break}for(var g=0;g!==m;g++){var E=f[g],C=E.velocity,F=E.angularVelocity;E.vlambda.vmul(E.linearFactor,E.vlambda),C.vadd(E.vlambda,C),E.wlambda.vmul(E.angularFactor,E.wlambda),F.vadd(E.wlambda,F)}for(var R=v.length,T=1/w;R--;)v[R].multiplier=B[R]*T}return c}},function(t,e){function i(){this.objects=[],this.type=Object}t.exports=i,i.prototype.release=function(){for(var t=arguments.length,e=0;e!==t;e++)this.objects.push(arguments[e]);return this},i.prototype.get=function(){return 0===this.objects.length?this.constructObject():this.objects.pop()},i.prototype.constructObject=function(){throw new Error("constructObject() not implemented in this Pool subclass yet!")},i.prototype.resize=function(t){for(var e=this.objects;e.length>t;)e.pop();for(;e.length0&&o===!0||0>=p&&o===!1))return!1;null===o&&(o=p>0)}return!0}t.exports=o;var s=i(4),r=i(7),a=i(2),h=i(16),l=i(1),p=i(10),c=(i(11),i(3)),u=(i(20),i(33)),d=i(5),v=i(21);o.prototype.createContactEquation=function(t,e,i,o,n,s){var r;this.contactPointPool.length?(r=this.contactPointPool.pop(),r.bi=t,r.bj=e):r=new d(t,e),r.enabled=t.collisionResponse&&e.collisionResponse&&i.collisionResponse&&o.collisionResponse;var a=this.currentContactMaterial;r.restitution=a.restitution,r.setSpookParams(a.contactEquationStiffness,a.contactEquationRelaxation,this.world.dt);var h=i.material||t.material,l=o.material||e.material;return h&&l&&h.restitution>=0&&l.restitution>=0&&(r.restitution=h.restitution*l.restitution),r.si=n||i,r.sj=s||o,r},o.prototype.createFrictionEquationsFromContact=function(t,e){var i=t.bi,o=t.bj,n=t.si,s=t.sj,r=this.world,a=this.currentContactMaterial,h=a.friction,l=n.material||i.material,p=s.material||o.material;if(l&&p&&l.friction>=0&&p.friction>=0&&(h=l.friction*p.friction),h>0){var c=h*r.gravity.length(),u=i.invMass+o.invMass;u>0&&(u=1/u);var d=this.frictionEquationPool,y=d.length?d.pop():new v(i,o,c*u),f=d.length?d.pop():new v(i,o,c*u);return y.bi=f.bi=i,y.bj=f.bj=o,y.minForce=f.minForce=-c*u,y.maxForce=f.maxForce=c*u,y.ri.copy(t.ri),y.rj.copy(t.rj),f.ri.copy(t.ri),f.rj.copy(t.rj),t.ni.tangents(y.t,f.t),y.setSpookParams(a.frictionEquationStiffness,a.frictionEquationRelaxation,r.dt),f.setSpookParams(a.frictionEquationStiffness,a.frictionEquationRelaxation,r.dt),y.enabled=f.enabled=t.enabled,e.push(y,f),!0}return!1};var y=new l,f=new l,m=new l;o.prototype.createFrictionFromAverage=function(t){var e=this.result[this.result.length-1];if(this.createFrictionEquationsFromContact(e,this.frictionResult)&&1!==t){var i=this.frictionResult[this.frictionResult.length-2],o=this.frictionResult[this.frictionResult.length-1];y.setZero(),f.setZero(),m.setZero();for(var n=e.bi,s=(e.bj,0);s!==t;s++)e=this.result[this.result.length-1-s],e.bodyA!==n?(y.vadd(e.ni,y),f.vadd(e.ri,f),m.vadd(e.rj,m)):(y.vsub(e.ni,y),f.vadd(e.rj,f),m.vadd(e.ri,m));var r=1/t;f.scale(r,i.ri),m.scale(r,i.rj),o.ri.copy(i.ri),o.rj.copy(i.rj),y.normalize(),y.tangents(i.t,o.t)}};var w=new l,g=new l,x=new c,b=new c;o.prototype.getContacts=function(t,e,i,o,n,s,a){this.contactPointPool=n,this.frictionEquationPool=a,this.result=o,this.frictionResult=s;for(var h=x,l=b,p=w,c=g,u=0,d=t.length;u!==d;u++){var v=t[u],y=e[u],f=null;v.material&&y.material&&(f=i.getContactMaterial(v.material,y.material)||null);for(var m=v.type&r.KINEMATIC&&y.type&r.STATIC||v.type&r.STATIC&&y.type&r.KINEMATIC||v.type&r.KINEMATIC&&y.type&r.KINEMATIC,B=0;BA.boundingSphereRadius+z.boundingSphereRadius)){var S=null;A.material&&z.material&&(S=i.getContactMaterial(A.material,z.material)||null),this.currentContactMaterial=S||f||i.defaultContactMaterial;var M=this[A.type|z.type];if(M){var C=!1;C=A.type=w){if(u)return!0;var g=this.createContactEquation(r,a,t,e,h,c);g.ni.copy(v);var x=E;v.scale(m.dot(v),x),d.vsub(x,x),g.ri.copy(x),g.ri.vsub(r.position,g.ri),g.rj.copy(d),g.rj.vsub(a.position,g.rj),this.result.push(g),this.createFrictionEquationsFromContact(g,this.frictionResult)}}};var z=new l,S=new l,M=(new l,new l),C=new l,F=new l,R=new l,T=new l,I=new l,N=new l,P=new l,q=new l,L=new l,W=new l,j=new s,V=[]; 3 | o.prototype[a.types.SPHERE|a.types.TRIMESH]=o.prototype.sphereTrimesh=function(t,e,i,o,n,s,r,a,l,c,u){var d=F,v=R,y=T,f=I,m=N,w=P,g=j,x=C,b=S,B=V;p.pointToLocalFrame(o,s,i,m);var A=t.radius;g.lowerBound.set(m.x-A,m.y-A,m.z-A),g.upperBound.set(m.x+A,m.y+A,m.z+A),e.getTrianglesInAABB(g,B);for(var E=M,k=t.radius*t.radius,O=0;O_;_++)if(e.getVertex(e.indices[3*B[O]+_],E),E.vsub(m,b),b.norm2()<=k){if(x.copy(E),p.pointToWorldFrame(o,s,x,E),E.vsub(i,b),u)return!0;var D=this.createContactEquation(r,a,t,e,l,c);D.ni.copy(b),D.ni.normalize(),D.ri.copy(D.ni),D.ri.scale(t.radius,D.ri),D.ri.vadd(i,D.ri),D.ri.vsub(r.position,D.ri),D.rj.copy(E),D.rj.vsub(a.position,D.rj),this.result.push(D),this.createFrictionEquationsFromContact(D,this.frictionResult)}for(var O=0;O_;_++){e.getVertex(e.indices[3*B[O]+_],d),e.getVertex(e.indices[3*B[O]+(_+1)%3],v),v.vsub(d,y),m.vsub(v,w);var H=w.dot(y);m.vsub(d,w);var U=w.dot(y);if(U>0&&0>H){m.vsub(d,w),f.copy(y),f.normalize(),U=w.dot(f),f.scale(U,w),w.vadd(d,w);var Y=w.distanceTo(m);if(YM&&M>0){var C=X,F=G;C.copy(u[(A+1)%3]),F.copy(u[(A+2)%3]);var R=C.norm(),T=F.norm();C.normalize(),F.normalize();var I=U.dot(C),N=U.dot(F);if(R>I&&I>-R&&T>N&&N>-T){var P=Math.abs(M-S-d);if((null===B||B>P)&&(B=P,x=I,b=N,w=S,y.copy(z),f.copy(C),m.copy(F),g++,p))return!0}}}if(g){v=!0;var q=this.createContactEquation(r,a,t,e,h,l);y.mult(-d,q.ri),q.ni.copy(y),q.ni.negate(q.ni),y.mult(w,y),f.mult(x,f),y.vadd(f,y),m.mult(b,m),y.vadd(m,q.rj),q.ri.vadd(i,q.ri),q.ri.vsub(r.position,q.ri),q.rj.vadd(o,q.rj),q.rj.vsub(a.position,q.rj),this.result.push(q),this.createFrictionEquationsFromContact(q,this.frictionResult)}for(var L=c.get(),W=Z,j=0;2!==j&&!v;j++)for(var V=0;2!==V&&!v;V++)for(var k=0;2!==k&&!v;k++)if(L.set(0,0,0),j?L.vadd(u[0],L):L.vsub(u[0],L),V?L.vadd(u[1],L):L.vsub(u[1],L),k?L.vadd(u[2],L):L.vsub(u[2],L),o.vadd(L,W),W.vsub(i,W),W.norm2()it){if(p)return!0;v=!0;var ot=this.createContactEquation(r,a,t,e,h,l);_.vadd(D,ot.rj),ot.rj.copy(ot.rj),P.negate(ot.ni),ot.ni.normalize(),ot.ri.copy(ot.rj),ot.ri.vadd(o,ot.ri),ot.ri.vsub(i,ot.ri),ot.ri.normalize(),ot.ri.mult(d,ot.ri),ot.ri.vadd(i,ot.ri),ot.ri.vsub(r.position,ot.ri),ot.rj.vadd(o,ot.rj),ot.rj.vsub(a.position,ot.rj),this.result.push(ot),this.createFrictionEquationsFromContact(ot,this.frictionResult)}}c.release(O,_,q,D,P)};var tt=new l,et=new l,it=new l,ot=new l,nt=new l,st=new l,rt=new l,at=new l,ht=new l,lt=new l;o.prototype[a.types.SPHERE|a.types.CONVEXPOLYHEDRON]=o.prototype.sphereConvex=function(t,e,i,o,s,r,a,h,l,p,c){var u=this.v3pool;i.vsub(o,tt);for(var d=e.faceNormals,v=e.faces,y=e.vertices,f=t.radius,m=0;m!==y.length;m++){var w=y[m],g=nt;r.vmult(w,g),o.vadd(g,g);var x=ot;if(g.vsub(i,x),x.norm2()R&&T.dot(S)>0){for(var I=[],N=0,P=z.length;N!==P;N++){var q=u.get();r.vmult(y[z[N]],q),o.vadd(q,q),I.push(q)}if(n(I,S,i)){if(c)return!0;B=!0;var b=this.createContactEquation(a,h,t,e,l,p);S.mult(-f,b.ri),S.negate(b.ni);var L=u.get();S.mult(-R,L);var W=u.get();S.mult(-f,W),i.vsub(o,b.rj),b.rj.vadd(W,b.rj),b.rj.vadd(L,b.rj),b.rj.vadd(o,b.rj),b.rj.vsub(h.position,b.rj),b.ri.vadd(i,b.ri),b.ri.vsub(a.position,b.ri),u.release(L),u.release(W),this.result.push(b),this.createFrictionEquationsFromContact(b,this.frictionResult);for(var N=0,j=I.length;N!==j;N++)u.release(I[N]);return}for(var N=0;N!==z.length;N++){var V=u.get(),k=u.get();r.vmult(y[z[(N+1)%z.length]],V),r.vmult(y[z[(N+2)%z.length]],k),o.vadd(V,V),o.vadd(k,k);var O=et;k.vsub(V,O);var _=it;O.unit(_);var D=u.get(),H=u.get();i.vsub(V,H);var U=H.dot(_);_.mult(U,D),D.vadd(V,D);var Y=u.get();if(D.vsub(i,Y),U>0&&U*U=f){if(p)return!0;var m=this.createContactEquation(r,a,t,e,h,l),w=dt;u.mult(u.dot(v),w),c.vsub(w,w),w.vsub(i,m.ri),m.ni.copy(u),c.vsub(o,m.rj),m.ri.vadd(i,m.ri),m.ri.vsub(r.position,m.ri),m.rj.vadd(o,m.rj),m.rj.vsub(a.position,m.rj),this.result.push(m),d++,this.enableFrictionReduction||this.createFrictionEquationsFromContact(m,this.frictionResult)}}this.enableFrictionReduction&&d&&this.createFrictionFromAverage(d)};var vt=new l,yt=new l;o.prototype[a.types.CONVEXPOLYHEDRON]=o.prototype.convexConvex=function(t,e,i,o,n,s,r,a,h,l,p,c,u){var d=vt;if(!(i.distanceTo(o)>t.boundingSphereRadius+e.boundingSphereRadius)&&t.findSeparatingAxis(e,i,n,o,s,d,c,u)){var v=[],y=yt;t.clipAgainstHull(i,n,e,o,s,d,-100,100,v);for(var f=0,m=0;m!==v.length;m++){if(p)return!0;var w=this.createContactEquation(r,a,t,e,h,l),g=w.ri,x=w.rj;d.negate(w.ni),v[m].normal.negate(y),y.mult(v[m].depth,y),v[m].point.vadd(y,g),x.copy(v[m].point),g.vsub(i,g),x.vsub(o,x),g.vadd(i,g),g.vsub(r.position,g),x.vadd(o,x),x.vsub(a.position,x),this.result.push(w),f++,this.enableFrictionReduction||this.createFrictionEquationsFromContact(w,this.frictionResult)}this.enableFrictionReduction&&f&&this.createFrictionFromAverage(f)}};var ft=new l,mt=new l,wt=new l;o.prototype[a.types.PLANE|a.types.PARTICLE]=o.prototype.planeParticle=function(t,e,i,o,n,s,r,a,h,l,p){var c=ft;c.set(0,0,1),r.quaternion.vmult(c,c);var u=mt;o.vsub(r.position,u);var d=c.dot(u);if(0>=d){if(p)return!0;var v=this.createContactEquation(a,r,e,t,h,l);v.ni.copy(c),v.ni.negate(v.ni),v.ri.set(0,0,0);var y=wt;c.mult(c.dot(o),y),o.vsub(y,y),v.rj.copy(y),this.result.push(v),this.createFrictionEquationsFromContact(v,this.frictionResult)}};var gt=new l;o.prototype[a.types.PARTICLE|a.types.SPHERE]=o.prototype.sphereParticle=function(t,e,i,o,n,s,r,a,h,l,p){var c=gt;c.set(0,0,1),o.vsub(i,c);var u=c.norm2();if(u<=t.radius*t.radius){if(p)return!0;var d=this.createContactEquation(a,r,e,t,h,l);c.normalize(),d.rj.copy(c),d.rj.mult(t.radius,d.rj),d.ni.copy(c),d.ni.negate(d.ni),d.ri.set(0,0,0),this.result.push(d),this.createFrictionEquationsFromContact(d,this.frictionResult)}};var xt=new c,bt=new l,Bt=(new l,new l),At=new l,Et=new l;o.prototype[a.types.PARTICLE|a.types.CONVEXPOLYHEDRON]=o.prototype.convexParticle=function(t,e,i,o,n,s,r,a,h,l,p){var c=-1,u=Bt,d=Et,v=null,y=0,f=bt;if(f.copy(o),f.vsub(i,f),n.conjugate(xt),xt.vmult(f,f),t.pointIsInside(f)){t.worldVerticesNeedsUpdate&&t.computeWorldVertices(i,n),t.worldFaceNormalsNeedsUpdate&&t.computeWorldFaceNormals(n);for(var m=0,w=t.faces.length;m!==w;m++){var g=[t.worldVertices[t.faces[m][0]]],x=t.worldFaceNormals[m];o.vsub(g[0],At);var b=-x.dot(At);if(null===v||Math.abs(b)g||0>b||w>u.length||x>u[0].length)){0>w&&(w=0),0>g&&(g=0),0>x&&(x=0),0>b&&(b=0),w>=u.length&&(w=u.length-1),g>=u.length&&(g=u.length-1),b>=u[0].length&&(b=u[0].length-1),x>=u[0].length&&(x=u[0].length-1);var B=[];e.getRectMinMax(w,x,g,b,B);var A=B[0],E=B[1];if(!(m.z-v>E||m.z+vz;z++)for(var S=x;b>S;S++){var M=!1;if(e.getConvexTrianglePillar(z,S,!1),p.pointToWorldFrame(o,s,e.pillarOffset,y),i.distanceTo(y)w||0>x||m>u.length||x>u[0].length)){0>m&&(m=0),0>w&&(w=0),0>g&&(g=0),0>x&&(x=0),m>=u.length&&(m=u.length-1),w>=u.length&&(w=u.length-1),x>=u[0].length&&(x=u[0].length-1),g>=u[0].length&&(g=u[0].length-1);var b=[];e.getRectMinMax(m,g,w,x,b);var B=b[0],A=b[1];if(!(f.z-d>A||f.z+dz;z++)for(var S=g;x>S;S++){var M=E.length,C=!1;if(e.getConvexTrianglePillar(z,S,!1),p.pointToWorldFrame(o,s,e.pillarOffset,y),i.distanceTo(y)2)return}}}},function(t,e,i){t.exports={version:i(57).version,AABB:i(4),ArrayCollisionMatrix:i(24),Body:i(7),Box:i(19),Broadphase:i(15),Constraint:i(8),ContactEquation:i(5),Narrowphase:i(34),ConeTwistConstraint:i(40),ContactMaterial:i(27),ConvexPolyhedron:i(11),Cylinder:i(50),DistanceConstraint:i(41),Equation:i(9),EventTarget:i(23),FrictionEquation:i(21),GSSolver:i(31),GridBroadphase:i(36),Heightfield:i(51),HingeConstraint:i(26),LockConstraint:i(42),Mat3:i(6),Material:i(13),NaiveBroadphase:i(25),ObjectCollisionMatrix:i(37),Pool:i(32),Particle:i(28),Plane:i(29),PointToPointConstraint:i(17),Quaternion:i(3),Ray:i(16),RaycastVehicle:i(45),RaycastResult:i(12),RigidVehicle:i(46),RotationalEquation:i(18),RotationalMotorEquation:i(22),SAPBroadphase:i(39),SPHSystem:i(47),Shape:i(2),Solver:i(20),Sphere:i(30),SplitSolver:i(53),Spring:i(48),Transform:i(10),Trimesh:i(52),Vec3:i(1),Vec3Pool:i(33),World:i(56)}},function(t,e,i){function o(t,e,i,o,r){n.apply(this),this.nx=i||10,this.ny=o||10,this.nz=r||10,this.aabbMin=t||new s(100,100,100),this.aabbMax=e||new s(-100,-100,-100);var a=this.nx*this.ny*this.nz;if(0>=a)throw"GridBroadphase: Each dimension's n must be >0";this.bins=[],this.binLengths=[],this.bins.length=a,this.binLengths.length=a;for(var h=0;a>h;h++)this.bins[h]=[],this.binLengths[h]=0}t.exports=o;var n=i(15),s=i(1),r=i(2);o.prototype=new n,o.prototype.constructor=o;var a=new s;new s;o.prototype.collisionPairs=function(t,e,i){function o(t,e,i,o,n,s,r){var a=(t-g)*B|0,h=(e-x)*A|0,l=(i-b)*E|0,f=L((o-g)*B),m=L((n-x)*A),w=L((s-b)*E);0>a?a=0:a>=p&&(a=p-1),0>h?h=0:h>=c&&(h=c-1),0>l?l=0:l>=u&&(l=u-1),0>f?f=0:f>=p&&(f=p-1),0>m?m=0:m>=c&&(m=c-1),0>w?w=0:w>=u&&(w=u-1),a*=d,h*=v,l*=y,f*=d,m*=v,w*=y;for(var z=a;f>=z;z+=d)for(var S=h;m>=S;S+=v)for(var M=l;w>=M;M+=y){var C=z+S+M;I[C][N[C]++]=r}}for(var n=t.numObjects(),s=t.bodies,h=this.aabbMax,l=this.aabbMin,p=this.nx,c=this.ny,u=this.nz,d=c*u,v=u,y=1,f=h.x,m=h.y,w=h.z,g=l.x,x=l.y,b=l.z,B=p/(f-g),A=c/(m-x),E=u/(w-b),z=(f-g)/p,S=(m-x)/c,M=(w-b)/u,C=.5*Math.sqrt(z*z+S*S+M*M),F=r.types,R=F.SPHERE,T=F.PLANE,I=(F.BOX,F.COMPOUND,F.CONVEXPOLYHEDRON,this.bins),N=this.binLengths,P=this.bins.length,q=0;q!==P;q++)N[q]=0;for(var L=Math.ceil,l=Math.min,h=Math.max,q=0;q!==n;q++){var W=s[q],j=W.shape;switch(j.type){case R:var V=W.position.x,k=W.position.y,O=W.position.z,_=j.radius;o(V-_,k-_,O-_,V+_,k+_,O+_,W);break;case T:j.worldNormalNeedsUpdate&&j.computeWorldNormal(W.quaternion);var D=j.worldNormal,H=g+.5*z-W.position.x,U=x+.5*S-W.position.y,Y=b+.5*M-W.position.z,X=a;X.set(H,U,Y);for(var G=0,K=0;G!==p;G++,K+=d,X.y=U,X.x+=z)for(var Z=0,Q=0;Z!==c;Z++,Q+=v,X.z=Y,X.y+=S)for(var J=0,$=0;J!==u;J++,$+=y,X.z+=M)if(X.dot(D)1)for(var it=I[q],G=0;G!==et;G++)for(var W=it[G],Z=0;Z!==G;Z++){var ot=it[Z];this.needBroadphaseCollision(W,ot)&&this.intersectionTest(W,ot,e,i)}}this.makePairsUnique(e,i)}},function(t,e){function i(){this.matrix={}}t.exports=i,i.prototype.get=function(t,e){if(t=t.id,e=e.id,e>t){var i=e;e=t,t=i}return t+"-"+e in this.matrix},i.prototype.set=function(t,e,i){if(t=t.id,e=e.id,e>t){var o=e;e=t,t=o}i?this.matrix[t+"-"+e]=!0:delete this.matrix[t+"-"+e]},i.prototype.reset=function(){this.matrix={}},i.prototype.setNumObjects=function(t){}},function(t,e){function i(){this.current=[],this.previous=[]}function o(t,e){t.push((4294901760&e)>>16,65535&e)}t.exports=i,i.prototype.getKey=function(t,e){if(t>e){var i=e;e=t,t=i}return t<<16|e},i.prototype.set=function(t,e){for(var i=this.getKey(t,e),o=this.current,n=0;i>o[n];)n++;if(i!==o[n]){for(var e=o.length-1;e>=n;e--)o[e+1]=o[e];o[n]=i}},i.prototype.tick=function(){var t=this.current;this.current=this.previous,this.previous=t,this.current.length=0},i.prototype.getDiff=function(t,e){for(var i=this.current,n=this.previous,s=i.length,r=n.length,a=0,h=0;s>h;h++){for(var l=!1,p=i[h];p>n[a];)a++;l=p===n[a],l||o(t,p)}a=0;for(var h=0;r>h;h++){for(var l=!1,c=n[h];c>i[a];)a++;l=i[a]===c,l||o(e,c)}}},function(t,e,i){function o(t){n.apply(this),this.axisList=[],this.world=null,this.axisIndex=0;var e=this.axisList;this._addBodyHandler=function(t){e.push(t.body)},this._removeBodyHandler=function(t){var i=e.indexOf(t.body);-1!==i&&e.splice(i,1)},t&&this.setWorld(t)}var n=(i(2),i(15));t.exports=o,o.prototype=new n,o.prototype.setWorld=function(t){this.axisList.length=0;for(var e=0;ee;e++){for(var o=t[e],n=e-1;n>=0&&!(t[n].aabb.lowerBound.x<=o.aabb.lowerBound.x);n--)t[n+1]=t[n];t[n+1]=o}return t},o.insertionSortY=function(t){for(var e=1,i=t.length;i>e;e++){for(var o=t[e],n=e-1;n>=0&&!(t[n].aabb.lowerBound.y<=o.aabb.lowerBound.y);n--)t[n+1]=t[n];t[n+1]=o}return t},o.insertionSortZ=function(t){for(var e=1,i=t.length;i>e;e++){for(var o=t[e],n=e-1;n>=0&&!(t[n].aabb.lowerBound.z<=o.aabb.lowerBound.z);n--)t[n+1]=t[n];t[n+1]=o}return t},o.prototype.collisionPairs=function(t,e,i){var n,s,r=this.axisList,a=r.length,h=this.axisIndex;for(this.dirty&&(this.sortList(),this.dirty=!1),n=0;n!==a;n++){var l=r[n];for(s=n+1;a>s;s++){var p=r[s];if(this.needBroadphaseCollision(l,p)){if(!o.checkBounds(l,p,h))break;this.intersectionTest(l,p,e,i)}}}},o.prototype.sortList=function(){for(var t=this.axisList,e=this.axisIndex,i=t.length,n=0;n!==i;n++){var s=t[n];s.aabbNeedsUpdate&&s.computeAABB()}0===e?o.insertionSortX(t):1===e?o.insertionSortY(t):2===e&&o.insertionSortZ(t)},o.checkBounds=function(t,e,i){var o,n;0===i?(o=t.position.x,n=e.position.x):1===i?(o=t.position.y,n=e.position.y):2===i&&(o=t.position.z,n=e.position.z);var s=t.boundingRadius,r=e.boundingRadius,a=o+s,h=n-r;return a>h},o.prototype.autoDetectAxis=function(){for(var t=0,e=0,i=0,o=0,n=0,s=0,r=this.axisList,a=r.length,h=1/a,l=0;l!==a;l++){var p=r[l],c=p.position.x;t+=c,e+=c*c;var u=p.position.y;i+=u,o+=u*u;var d=p.position.z;n+=d,s+=d*d}var v=e-t*t*h,y=o-i*i*h,f=s-n*n*h;v>y?v>f?this.axisIndex=0:this.axisIndex=2:y>f?this.axisIndex=1:this.axisIndex=2},o.prototype.aabbQuery=function(t,e,i){i=i||[],this.dirty&&(this.sortList(),this.dirty=!1);var o=this.axisIndex,n="x";1===o&&(n="y"),2===o&&(n="z");for(var s=this.axisList,r=(e.lowerBound[n],e.upperBound[n],0);rn&&(r=n),-n>r&&(r=-n),r}function s(t,e,i){var o=E,n=z,s=S,r=M;return e.vsub(t.position,o),o.cross(i,n),t.invInertiaWorld.vmult(n,r),r.cross(o,s),t.invMass+i.dot(s)}function r(t,e,i,o,n,s){var r=n.norm2();if(r>1.1)return 0;var a=C,h=F,l=R;t.getVelocityAtWorldPoint(e,a),i.getVelocityAtWorldPoint(o,h),a.vsub(h,l);var p=n.dot(l),c=.2,u=1/(t.invMass+i.invMass),s=-c*p*u;return s}var a=(i(7),i(1)),h=i(3),l=(i(12),i(16)),p=i(49);t.exports=o;var c=(new a,new a,new a,new a),u=new a,d=new a;new l;o.prototype.addWheel=function(t){t=t||{};var e=new p(t),i=this.wheelInfos.length;return this.wheelInfos.push(e),i},o.prototype.setSteeringValue=function(t,e){var i=this.wheelInfos[e];i.steering=t};new a;o.prototype.applyEngineForce=function(t,e){this.wheelInfos[e].engineForce=t},o.prototype.setBrake=function(t,e){this.wheelInfos[e].brake=t},o.prototype.addToWorld=function(t){this.constraints;t.addBody(this.chassisBody);var e=this;this.preStepCallback=function(){e.updateVehicle(t.dt)},t.addEventListener("preStep",this.preStepCallback),this.world=t},o.prototype.getVehicleAxisWorld=function(t,e){e.set(0===t?1:0,1===t?1:0,2===t?1:0),this.chassisBody.vectorToWorldFrame(e,e)},o.prototype.updateVehicle=function(t){for(var e=this.wheelInfos,i=e.length,o=this.chassisBody,n=0;i>n;n++)this.updateWheelTransform(n);this.currentVehicleSpeedKmHour=3.6*o.velocity.norm();var s=new a;this.getVehicleAxisWorld(this.indexForwardAxis,s),s.dot(o.velocity)<0&&(this.currentVehicleSpeedKmHour*=-1);for(var n=0;i>n;n++)this.castRay(e[n]);this.updateSuspension(t);for(var r=new a,h=new a,n=0;i>n;n++){var l=e[n],p=l.suspensionForce;p>l.maxSuspensionForce&&(p=l.maxSuspensionForce),l.raycastResult.hitNormalWorld.scale(p*t,r),l.raycastResult.hitPointWorld.vsub(o.position,h),o.applyImpulse(r,h)}this.updateFriction(t);var c=new a,u=new a,d=new a;for(n=0;i>n;n++){var l=e[n];o.getVelocityAtWorldPoint(l.chassisConnectionPointWorld,d);var v=1;switch(this.indexUpAxis){case 1:v=-1}if(l.isInContact){this.getVehicleAxisWorld(this.indexForwardAxis,u);var y=u.dot(l.raycastResult.hitNormalWorld);l.raycastResult.hitNormalWorld.scale(y,c),u.vsub(c,u);var f=u.dot(d);l.deltaRotation=v*f*t/l.radius}!l.sliding&&l.isInContact||0===l.engineForce||!l.useCustomSlidingRotationalSpeed||(l.deltaRotation=(l.engineForce>0?1:-1)*l.customSlidingRotationalSpeed*t),Math.abs(l.brake)>Math.abs(l.engineForce)&&(l.deltaRotation=0),l.rotation+=l.deltaRotation,l.deltaRotation*=.99}},o.prototype.updateSuspension=function(t){for(var e=this.chassisBody,i=e.mass,o=this.wheelInfos,n=o.length,s=0;n>s;s++){var r=o[s];if(r.isInContact){var a,h=r.suspensionRestLength,l=r.suspensionLength,p=h-l;a=r.suspensionStiffness*p*r.clippedInvContactDotSuspension;var c,u=r.suspensionRelativeVelocity;c=0>u?r.dampingCompression:r.dampingRelaxation,a-=c*u,r.suspensionForce=a*i,r.suspensionForce<0&&(r.suspensionForce=0)}else r.suspensionForce=0}},o.prototype.removeFromWorld=function(t){this.constraints;t.remove(this.chassisBody),t.removeEventListener("preStep",this.preStepCallback),this.world=null};var v=new a,y=new a;o.prototype.castRay=function(t){var e=v,i=y;this.updateWheelTransformWorld(t);var o=this.chassisBody,n=-1,s=t.suspensionRestLength+t.radius;t.directionWorld.scale(s,e);var r=t.chassisConnectionPointWorld;r.vadd(e,i);var h=t.raycastResult;h.reset();var l=o.collisionResponse;o.collisionResponse=!1,this.world.rayTest(r,i,h),o.collisionResponse=l;var p=h.body;if(t.raycastResult.groundObject=0,p){n=h.distance,t.raycastResult.hitNormalWorld=h.hitNormalWorld,t.isInContact=!0;var c=h.distance;t.suspensionLength=c-t.radius;var u=t.suspensionRestLength-t.maxSuspensionTravel,d=t.suspensionRestLength+t.maxSuspensionTravel;t.suspensionLengthd&&(t.suspensionLength=d,t.raycastResult.reset());var f=t.raycastResult.hitNormalWorld.dot(t.directionWorld),m=new a;o.getVelocityAtWorldPoint(t.raycastResult.hitPointWorld,m);var w=t.raycastResult.hitNormalWorld.dot(m);if(f>=-.1)t.suspensionRelativeVelocity=0,t.clippedInvContactDotSuspension=10;else{var g=-1/f;t.suspensionRelativeVelocity=w*g,t.clippedInvContactDotSuspension=g}}else t.suspensionLength=t.suspensionRestLength+0*t.maxSuspensionTravel,t.suspensionRelativeVelocity=0,t.directionWorld.scale(-1,t.raycastResult.hitNormalWorld),t.clippedInvContactDotSuspension=1;return n},o.prototype.updateWheelTransformWorld=function(t){t.isInContact=!1;var e=this.chassisBody;e.pointToWorldFrame(t.chassisConnectionPointLocal,t.chassisConnectionPointWorld),e.vectorToWorldFrame(t.directionLocal,t.directionWorld),e.vectorToWorldFrame(t.axleLocal,t.axleWorld)},o.prototype.updateWheelTransform=function(t){var e=c,i=u,o=d,n=this.wheelInfos[t];this.updateWheelTransformWorld(n),n.directionLocal.scale(-1,e),i.copy(n.axleLocal),e.cross(i,o),o.normalize(),i.normalize();var s=n.steering,r=new h;r.setFromAxisAngle(e,s);var a=new h;a.setFromAxisAngle(i,n.rotation);var l=n.worldTransform.quaternion;this.chassisBody.quaternion.mult(r,l),l.mult(a,l),l.normalize();var p=n.worldTransform.position;p.copy(n.directionWorld),p.scale(n.suspensionLength,p),p.vadd(n.chassisConnectionPointWorld,p)};var f=[new a(1,0,0),new a(0,1,0),new a(0,0,1)];o.prototype.getWheelTransformWorld=function(t){return this.wheelInfos[t].worldTransform};var m=new a,w=[],g=[],x=1;o.prototype.updateFriction=function(t){for(var e=m,i=this.wheelInfos,o=i.length,s=this.chassisBody,h=g,l=w,p=0,c=0;o>c;c++){var u=i[c],d=u.raycastResult.body;d&&p++,u.sideImpulse=0,u.forwardImpulse=0,h[c]||(h[c]=new a),l[c]||(l[c]=new a)}for(var c=0;o>c;c++){var u=i[c],d=u.raycastResult.body;if(d){var v=l[c],y=this.getWheelTransformWorld(c);y.vectorToWorldFrame(f[this.indexRightAxis],v);var b=u.raycastResult.hitNormalWorld,B=v.dot(b);b.scale(B,e),v.vsub(e,v),v.normalize(),b.cross(v,h[c]),h[c].normalize(),u.sideImpulse=r(s,u.raycastResult.hitPointWorld,d,u.raycastResult.hitPointWorld,v),u.sideImpulse*=x}}var A=1,E=.5;this.sliding=!1;for(var c=0;o>c;c++){var u=i[c],d=u.raycastResult.body,z=0;if(u.slipInfo=1,d){var S=0,M=u.brake?u.brake:S;z=n(s,d,u.raycastResult.hitPointWorld,h[c],M),z+=u.engineForce*t;var C=M/z;u.slipInfo*=C}if(u.forwardImpulse=0,u.skidInfo=1,d){u.skidInfo=1;var F=u.suspensionForce*t*u.frictionSlip,R=F,T=F*R;u.forwardImpulse=z;var I=u.forwardImpulse*E,N=u.sideImpulse*A,P=I*I+N*N;if(u.sliding=!1,P>T){this.sliding=!0,u.sliding=!0;var C=F/Math.sqrt(P);u.skidInfo*=C}}}if(this.sliding)for(var c=0;o>c;c++){var u=i[c];0!==u.sideImpulse&&u.skidInfo<1&&(u.forwardImpulse*=u.skidInfo,u.sideImpulse*=u.skidInfo)}for(var c=0;o>c;c++){var u=i[c],q=new a;if(u.raycastResult.hitPointWorld.vsub(s.position,q),0!==u.forwardImpulse){var L=new a;h[c].scale(u.forwardImpulse,L),s.applyImpulse(L,q)}if(0!==u.sideImpulse){var d=u.raycastResult.body,W=new a;u.raycastResult.hitPointWorld.vsub(d.position,W);var j=new a;l[c].scale(u.sideImpulse,j),s.vectorToLocalFrame(q,q),q["xyz"[this.indexUpAxis]]*=u.rollInfluence,s.vectorToWorldFrame(q,q),s.applyImpulse(j,q),j.scale(-1,j),d.applyImpulse(j,W)}}};var b=new a,B=new a,A=new a,E=new a,z=new a,S=new a,M=new a,C=new a,F=new a,R=new a},function(t,e,i){function o(t){if(this.wheelBodies=[],this.coordinateSystem="undefined"==typeof t.coordinateSystem?new a(1,2,3):t.coordinateSystem.clone(),this.chassisBody=t.chassisBody,!this.chassisBody){var e=new r(new a(5,2,.5)); 4 | this.chassisBody=new n(1,e)}this.constraints=[],this.wheelAxes=[],this.wheelForces=[]}var n=i(7),s=i(30),r=i(19),a=i(1),h=i(26);t.exports=o,o.prototype.addWheel=function(t){t=t||{};var e=t.body;e||(e=new n(1,new s(1.2))),this.wheelBodies.push(e),this.wheelForces.push(0);var i=(new a,"undefined"!=typeof t.position?t.position.clone():new a),o=new a;this.chassisBody.pointToWorldFrame(i,o),e.position.set(o.x,o.y,o.z);var r="undefined"!=typeof t.axis?t.axis.clone():new a(0,1,0);this.wheelAxes.push(r);var l=new h(this.chassisBody,e,{pivotA:i,axisA:r,pivotB:a.ZERO,axisB:r,collideConnected:!1});return this.constraints.push(l),this.wheelBodies.length-1},o.prototype.setSteeringValue=function(t,e){var i=this.wheelAxes[e],o=Math.cos(t),n=Math.sin(t),s=i.x,r=i.y;this.constraints[e].axisA.set(o*s-n*r,n*s+o*r,0)},o.prototype.setMotorSpeed=function(t,e){var i=this.constraints[e];i.enableMotor(),i.motorTargetVelocity=t},o.prototype.disableMotor=function(t){var e=this.constraints[t];e.disableMotor()};var l=new a;o.prototype.setWheelForce=function(t,e){this.wheelForces[e]=t},o.prototype.applyWheelForce=function(t,e){var i=this.wheelAxes[e],o=this.wheelBodies[e],n=o.torque;i.scale(t,l),o.vectorToWorldFrame(l,l),n.vadd(l,n)},o.prototype.addToWorld=function(t){for(var e=this.constraints,i=this.wheelBodies.concat([this.chassisBody]),o=0;othis.particles.length&&this.neighbors.pop())};var s=new n;o.prototype.getNeighbors=function(t,e){for(var i=this.particles.length,o=t.id,n=this.smoothingRadius*this.smoothingRadius,r=s,a=0;a!==i;a++){var h=this.particles[a];h.position.vsub(t.position,r),o!==h.id&&r.norm2()=-.1)this.suspensionRelativeVelocity=0,this.clippedInvContactDotSuspension=10;else{var n=-1/i;this.suspensionRelativeVelocity=o*n,this.clippedInvContactDotSuspension=n}}else e.suspensionLength=this.suspensionRestLength,this.suspensionRelativeVelocity=0,e.directionWorld.scale(-1,e.hitNormalWorld),this.clippedInvContactDotSuspension=1}},function(t,e,i){function o(t,e,i,o){var a=o,h=[],l=[],p=[],c=[],u=[],d=Math.cos,v=Math.sin;h.push(new s(e*d(0),e*v(0),.5*-i)),c.push(0),h.push(new s(t*d(0),t*v(0),.5*i)),u.push(1);for(var y=0;a>y;y++){var f=2*Math.PI/a*(y+1),m=2*Math.PI/a*(y+.5);a-1>y?(h.push(new s(e*d(f),e*v(f),.5*-i)),c.push(2*y+2),h.push(new s(t*d(f),t*v(f),.5*i)),u.push(2*y+3),p.push([2*y+2,2*y+3,2*y+1,2*y])):p.push([0,1,2*y+1,2*y]),(a%2===1||a/2>y)&&l.push(new s(d(m),v(m),0))}p.push(u),l.push(new s(0,0,1));for(var w=[],y=0;yn&&(e=n)}this.minValue=e},o.prototype.updateMaxValue=function(){for(var t=this.data,e=t[0][0],i=0;i!==t.length;i++)for(var o=0;o!==t[i].length;o++){var n=t[i][o];n>e&&(e=n)}this.maxValue=e},o.prototype.setHeightValueAtIndex=function(t,e,i){var o=this.data;o[t][e]=i,this.clearCachedConvexTrianglePillar(t,e,!1),t>0&&(this.clearCachedConvexTrianglePillar(t-1,e,!0),this.clearCachedConvexTrianglePillar(t-1,e,!1)),e>0&&(this.clearCachedConvexTrianglePillar(t,e-1,!0),this.clearCachedConvexTrianglePillar(t,e-1,!1)),e>0&&t>0&&this.clearCachedConvexTrianglePillar(t-1,e-1,!0)},o.prototype.getRectMinMax=function(t,e,i,o,n){n=n||[];for(var s=this.data,r=this.minValue,a=t;i>=a;a++)for(var h=e;o>=h;h++){var l=s[a][h];l>r&&(r=l)}n[0]=this.minValue,n[1]=r},o.prototype.getIndexOfPosition=function(t,e,i,o){var n=this.elementSize,s=this.data,r=Math.floor(t/n),a=Math.floor(e/n);return i[0]=r,i[1]=a,o&&(0>r&&(r=0),0>a&&(a=0),r>=s.length-1&&(r=s.length-1),a>=s[0].length-1&&(a=s[0].length-1)),0>r||0>a||r>=s.length-1||a>=s[0].length-1?!1:!0};var l=[],p=new a,c=new a,u=new a,d=new a;o.prototype.getTriangleAt=function(t,e,i,o,n,s){var r=l;this.getIndexOfPosition(t,e,r,i);var a=r[0],h=r[1],p=this.data;i&&(a=Math.min(p.length-2,Math.max(0,a)),h=Math.min(p[0].length-2,Math.max(0,h)));var c=this.elementSize,u=Math.pow(t/c-a,2)+Math.pow(e/c-h,2),d=Math.pow(t/c-(a+1),2)+Math.pow(e/c-(h+1),2),v=u>d;return this.getTriangle(a,h,v,o,n,s),v};var v=new a,y=new a,f=new a,m=new a,w=new a;o.prototype.getNormalAt=function(t,e,i,o){var n=v,s=y,r=f,a=m,h=w;this.getTriangleAt(t,e,i,n,s,r),s.vsub(n,a),r.vsub(n,h),a.cross(h,o),o.normalize()},o.prototype.getAabbAtIndex=function(t,e,i){var o=this.data,n=this.elementSize;i.lowerBound.set(t*n,e*n,o[t][e]),i.upperBound.set((t+1)*n,(e+1)*n,o[t+1][e+1])},o.prototype.getHeightAt=function(t,e,i){var o=this.data,s=c,r=u,a=d,h=l;this.getIndexOfPosition(t,e,h,i);var v=h[0],y=h[1];i&&(v=Math.min(o.length-2,Math.max(0,v)),y=Math.min(o[0].length-2,Math.max(0,y)));var f=this.getTriangleAt(t,e,i,s,r,a);n(t,e,s.x,s.y,r.x,r.y,a.x,a.y,p);var m=p;return f?o[v+1][y+1]*m.x+o[v][y+1]*m.y+o[v+1][y]*m.z:o[v][y]*m.x+o[v+1][y]*m.y+o[v][y+1]*m.z},o.prototype.getCacheConvexTrianglePillarKey=function(t,e,i){return t+"_"+e+"_"+(i?1:0)},o.prototype.getCachedConvexTrianglePillar=function(t,e,i){return this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,e,i)]},o.prototype.setCachedConvexTrianglePillar=function(t,e,i,o,n){this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,e,i)]={convex:o,offset:n}},o.prototype.clearCachedConvexTrianglePillar=function(t,e,i){delete this._cachedPillars[this.getCacheConvexTrianglePillarKey(t,e,i)]},o.prototype.getTriangle=function(t,e,i,o,n,s){var r=this.data,a=this.elementSize;i?(o.set((t+1)*a,(e+1)*a,r[t+1][e+1]),n.set(t*a,(e+1)*a,r[t][e+1]),s.set((t+1)*a,e*a,r[t+1][e])):(o.set(t*a,e*a,r[t][e]),n.set((t+1)*a,e*a,r[t+1][e]),s.set(t*a,(e+1)*a,r[t][e+1]))},o.prototype.getConvexTrianglePillar=function(t,e,i){var o=this.pillarConvex,n=this.pillarOffset;if(this.cacheEnabled){var s=this.getCachedConvexTrianglePillar(t,e,i);if(s)return this.pillarConvex=s.convex,void(this.pillarOffset=s.offset);o=new r,n=new a,this.pillarConvex=o,this.pillarOffset=n}var s=this.data,h=this.elementSize,l=o.faces;o.vertices.length=6;for(var p=0;6>p;p++)o.vertices[p]||(o.vertices[p]=new a);l.length=5;for(var p=0;5>p;p++)l[p]||(l[p]=[]);var c=o.vertices,u=(Math.min(s[t][e],s[t+1][e],s[t][e+1],s[t+1][e+1])-this.minValue)/2+this.minValue;i?(n.set((t+.75)*h,(e+.75)*h,u),c[0].set(.25*h,.25*h,s[t+1][e+1]-u),c[1].set(-.75*h,.25*h,s[t][e+1]-u),c[2].set(.25*h,-.75*h,s[t+1][e]-u),c[3].set(.25*h,.25*h,-u-1),c[4].set(-.75*h,.25*h,-u-1),c[5].set(.25*h,-.75*h,-u-1),l[0][0]=0,l[0][1]=1,l[0][2]=2,l[1][0]=5,l[1][1]=4,l[1][2]=3,l[2][0]=2,l[2][1]=5,l[2][2]=3,l[2][3]=0,l[3][0]=3,l[3][1]=4,l[3][2]=1,l[3][3]=0,l[4][0]=1,l[4][1]=4,l[4][2]=5,l[4][3]=2):(n.set((t+.25)*h,(e+.25)*h,u),c[0].set(-.25*h,-.25*h,s[t][e]-u),c[1].set(.75*h,-.25*h,s[t+1][e]-u),c[2].set(-.25*h,.75*h,s[t][e+1]-u),c[3].set(-.25*h,-.25*h,-u-1),c[4].set(.75*h,-.25*h,-u-1),c[5].set(-.25*h,.75*h,-u-1),l[0][0]=0,l[0][1]=1,l[0][2]=2,l[1][0]=5,l[1][1]=4,l[1][2]=3,l[2][0]=0,l[2][1]=2,l[2][2]=5,l[2][3]=3,l[3][0]=1,l[3][1]=0,l[3][2]=3,l[3][3]=4,l[4][0]=4,l[4][1]=5,l[4][2]=2,l[4][3]=1),o.computeNormals(),o.computeEdges(),o.updateBoundingSphereRadius(),this.setCachedConvexTrianglePillar(t,e,i,o,n)},o.prototype.calculateLocalInertia=function(t,e){return e=e||new a,e.set(0,0,0),e},o.prototype.volume=function(){return Number.MAX_VALUE},o.prototype.calculateWorldAABB=function(t,e,i,o){i.set(-Number.MAX_VALUE,-Number.MAX_VALUE,-Number.MAX_VALUE),o.set(Number.MAX_VALUE,Number.MAX_VALUE,Number.MAX_VALUE)},o.prototype.updateBoundingSphereRadius=function(){var t=this.data,e=this.elementSize;this.boundingSphereRadius=new a(t.length*e,t[0].length*e,Math.max(Math.abs(this.maxValue),Math.abs(this.minValue))).norm()},o.prototype.setHeightsFromImage=function(t,e){var i=document.createElement("canvas");i.width=t.width,i.height=t.height;var o=i.getContext("2d");o.drawImage(t,0,0);var n=o.getImageData(0,0,t.width,t.height),s=this.data;s.length=0,this.elementSize=Math.abs(e.x)/n.width;for(var r=0;rn?n+"_"+s:s+"_"+n;t[o]=!0},i=0;ii.x&&(i.x=n.x),n.yi.y&&(i.y=n.y),n.zi.z&&(i.z=n.z)},o.prototype.updateAABB=function(){this.computeLocalAABB(this.aabb)},o.prototype.updateBoundingSphereRadius=function(){for(var t=0,e=this.vertices,i=new s,o=0,n=e.length/3;o!==n;o++){this.getVertex(o,i);var r=i.norm2();r>t&&(t=r)}this.boundingSphereRadius=Math.sqrt(t)};var x=(new s,new r),b=new a;o.prototype.calculateWorldAABB=function(t,e,i,o){var n=x,s=b;n.position=t,n.quaternion=e,this.aabb.toWorldFrame(n,s),i.copy(s.lowerBound),o.copy(s.upperBound)},o.prototype.volume=function(){return 4*Math.PI*this.boundingSphereRadius/3},o.createTorus=function(t,e,i,n,s){t=t||1,e=e||.5,i=i||8,n=n||6,s=s||2*Math.PI;for(var r=[],a=[],h=0;i>=h;h++)for(var l=0;n>=l;l++){var p=l/n*s,c=h/i*Math.PI*2,u=(t+e*Math.cos(c))*Math.cos(p),d=(t+e*Math.cos(c))*Math.sin(p),v=e*Math.sin(c);r.push(u,d,v)}for(var h=1;i>=h;h++)for(var l=1;n>=l;l++){var y=(n+1)*h+l-1,f=(n+1)*(h-1)+l-1,m=(n+1)*(h-1)+l,w=(n+1)*h+l;a.push(y,f,w),a.push(f,m,w)}return new o(r,a)}},function(t,e,i){function o(t){for(h.call(this),this.iterations=10,this.tolerance=1e-7,this.subsolver=t,this.nodes=[],this.nodePool=[];this.nodePool.length<128;)this.nodePool.push(this.createNode())}function n(t){for(var e=t.length,i=0;i!==e;i++){var o=t[i];if(!(o.visited||o.body.type&d))return o}return!1}function s(t,e,i,o){for(v.push(t),t.visited=!0,e(t,i,o);v.length;)for(var s,r=v.pop();s=n(r.children);)s.visited=!0,e(s,i,o),v.push(s)}function r(t,e,i){e.push(t.body);for(var o=t.eqs.length,n=0;n!==o;n++){var s=t.eqs[n];-1===i.indexOf(s)&&i.push(s)}}function a(t,e){return e.id-t.id}t.exports=o;var h=(i(1),i(3),i(20)),l=i(7);o.prototype=new h;var p=[],c=[],u={bodies:[]},d=l.STATIC,v=[];o.prototype.createNode=function(){return{body:null,children:[],eqs:[],visited:!1}},o.prototype.solve=function(t,e){for(var i=p,o=this.nodePool,h=e.bodies,l=this.equations,d=l.length,v=h.length,y=this.subsolver;o.lengthf;f++)i[f]=o[f];for(var f=0;f!==v;f++){var m=i[f];m.body=h[f],m.children.length=0,m.eqs.length=0,m.visited=!1}for(var w=0;w!==d;w++){var g=l[w],f=h.indexOf(g.bi),x=h.indexOf(g.bj),b=i[f],B=i[x];b.children.push(B),b.eqs.push(g),B.children.push(b),B.eqs.push(g)}var A,E=0,z=c;y.tolerance=this.tolerance,y.iterations=this.iterations;for(var S=u;A=n(i);){z.length=0,S.bodies.length=0,s(A,r,S.bodies,z);var M=z.length;z=z.sort(a);for(var f=0;f!==M;f++)y.addEquation(z[f]);y.solve(t,S);y.removeAllEquations(),E++}return E}},function(t,e,i){function o(t){t=t||{},this.root=t.root||null,this.aabb=t.aabb?t.aabb.clone():new s,this.data=[],this.children=[]}function n(t,e){e=e||{},e.root=null,e.aabb=t,o.call(this,e),this.maxDepth="undefined"!=typeof e.maxDepth?e.maxDepth:8}var s=i(4),r=i(1);t.exports=n,n.prototype=new o,o.prototype.reset=function(t,e){this.children.length=this.data.length=0},o.prototype.insert=function(t,e,i){var o=this.data;if(i=i||0,!this.aabb.contains(t))return!1;var n=this.children;if(i<(this.maxDepth||this.root.maxDepth)){var s=!1;n.length||(this.subdivide(),s=!0);for(var r=0;8!==r;r++)if(n[r].insert(t,e,i+1))return!0;s&&(n.length=0)}return o.push(e),!0};var a=new r;o.prototype.subdivide=function(){var t=this.aabb,e=t.lowerBound,i=t.upperBound,n=this.children;n.push(new o({aabb:new s({lowerBound:new r(0,0,0)})}),new o({aabb:new s({lowerBound:new r(1,0,0)})}),new o({aabb:new s({lowerBound:new r(1,1,0)})}),new o({aabb:new s({lowerBound:new r(1,1,1)})}),new o({aabb:new s({lowerBound:new r(0,1,1)})}),new o({aabb:new s({lowerBound:new r(0,0,1)})}),new o({aabb:new s({lowerBound:new r(1,0,1)})}),new o({aabb:new s({lowerBound:new r(0,1,0)})})),i.vsub(e,a),a.scale(.5,a);for(var h=this.root||this,l=0;8!==l;l++){var p=n[l];p.root=h;var c=p.aabb.lowerBound;c.x*=a.x,c.y*=a.y,c.z*=a.z,c.vadd(e,c),c.vadd(a,p.aabb.upperBound)}},o.prototype.aabbQuery=function(t,e){for(var i=(this.data,this.children,[this]);i.length;){var o=i.pop();o.aabb.overlaps(t)&&Array.prototype.push.apply(e,o.data),Array.prototype.push.apply(i,o.children)}return e};var h=new s;o.prototype.rayQuery=function(t,e,i){return t.getAABB(h),h.toLocalFrame(e,h),this.aabbQuery(h,i),i},o.prototype.removeEmptyNodes=function(){for(var t=[this];t.length;){for(var e=t.pop(),i=e.children.length-1;i>=0;i--)e.children[i].data.length||e.children.splice(i,1);Array.prototype.push.apply(t,e.children)}}},function(t,e){function i(){this.data={keys:[]}}t.exports=i,i.prototype.get=function(t,e){if(t>e){var i=e;e=t,t=i}return this.data[t+"-"+e]},i.prototype.set=function(t,e,i){if(t>e){var o=e;e=t,t=o}var n=t+"-"+e;this.get(t,e)||this.data.keys.push(n),this.data[n]=i},i.prototype.reset=function(){for(var t=this.data,e=t.keys;e.length>0;){var i=e.pop();delete t[i]}}},function(t,e,i){function o(t){t=t||{},h.apply(this),this.dt=-1,this.allowSleep=!!t.allowSleep,this.contacts=[],this.frictionEquations=[],this.quatNormalizeSkip=void 0!==t.quatNormalizeSkip?t.quatNormalizeSkip:0,this.quatNormalizeFast=void 0!==t.quatNormalizeFast?t.quatNormalizeFast:!1,this.time=0,this.stepnumber=0,this.default_dt=1/60,this.nextId=0,this.gravity=new n,t.gravity&&this.gravity.copy(t.gravity),this.broadphase=void 0!==t.broadphase?t.broadphase:new w,this.bodies=[],this.solver=void 0!==t.solver?t.solver:new r,this.constraints=[],this.narrowphase=new a(this),this.collisionMatrix=new l,this.collisionMatrixPrevious=new l,this.bodyOverlapKeeper=new p,this.shapeOverlapKeeper=new p,this.materials=[],this.contactmaterials=[],this.contactMaterialTable=new v,this.defaultMaterial=new c("default"),this.defaultContactMaterial=new u(this.defaultMaterial,this.defaultMaterial,{friction:.3,restitution:0}),this.doProfiling=!1,this.profile={solve:0,makeContactConstraints:0,broadphase:0,integrate:0,narrowphase:0},this.accumulator=0,this.subsystems=[],this.addBodyEvent={type:"addBody",body:null},this.removeBodyEvent={type:"removeBody",body:null},this.idToBodyMap={},this.broadphase.setWorld(this)}t.exports=o;var n=(i(2),i(1)),s=i(3),r=i(31),a=(i(5),i(21),i(34)),h=i(23),l=i(24),p=i(38),c=i(13),u=i(27),d=i(7),v=i(55),y=i(12),f=i(4),m=i(16),w=i(25);o.prototype=new h;var g=(new f,new m);if(o.prototype.getContactMaterial=function(t,e){return this.contactMaterialTable.get(t.id,e.id)},o.prototype.numObjects=function(){return this.bodies.length},o.prototype.collisionMatrixTick=function(){var t=this.collisionMatrixPrevious;this.collisionMatrixPrevious=this.collisionMatrix,this.collisionMatrix=t,this.collisionMatrix.reset(),this.bodyOverlapKeeper.tick(),this.shapeOverlapKeeper.tick()},o.prototype.add=o.prototype.addBody=function(t){-1===this.bodies.indexOf(t)&&(t.index=this.bodies.length,this.bodies.push(t),t.world=this,t.initPosition.copy(t.position),t.initVelocity.copy(t.velocity),t.timeLastSleepy=this.time,t instanceof d&&(t.initAngularVelocity.copy(t.angularVelocity),t.initQuaternion.copy(t.quaternion)),this.collisionMatrix.setNumObjects(this.bodies.length),this.addBodyEvent.body=t,this.idToBodyMap[t.id]=t,this.dispatchEvent(this.addBodyEvent))},o.prototype.addConstraint=function(t){this.constraints.push(t)},o.prototype.removeConstraint=function(t){var e=this.constraints.indexOf(t);-1!==e&&this.constraints.splice(e,1)},o.prototype.rayTest=function(t,e,i){i instanceof y?this.raycastClosest(t,e,{skipBackfaces:!0},i):this.raycastAll(t,e,{skipBackfaces:!0},i)},o.prototype.raycastAll=function(t,e,i,o){return i.mode=m.ALL,i.from=t,i.to=e,i.callback=o,g.intersectWorld(this,i)},o.prototype.raycastAny=function(t,e,i,o){return i.mode=m.ANY,i.from=t,i.to=e,i.result=o,g.intersectWorld(this,i)},o.prototype.raycastClosest=function(t,e,i,o){return i.mode=m.CLOSEST,i.from=t,i.to=e,i.result=o,g.intersectWorld(this,i)},o.prototype.remove=function(t){t.world=null;var e=this.bodies.length-1,i=this.bodies,o=i.indexOf(t);if(-1!==o){i.splice(o,1);for(var n=0;n!==i.length;n++)i[n].index=n;this.collisionMatrix.setNumObjects(e),this.removeBodyEvent.body=t,delete this.idToBodyMap[t.id],this.dispatchEvent(this.removeBodyEvent)}},o.prototype.removeBody=o.prototype.remove,o.prototype.getBodyById=function(t){return this.idToBodyMap[t]},o.prototype.getShapeById=function(t){for(var e=this.bodies,i=0,o=e.length;o>i;i++)for(var n=e[i].shapes,s=0,r=n.length;r>s;s++){var a=n[s];if(a.id===t)return a}},o.prototype.addMaterial=function(t){this.materials.push(t)},o.prototype.addContactMaterial=function(t){this.contactmaterials.push(t),this.contactMaterialTable.set(t.materials[0].id,t.materials[1].id,t)},"undefined"==typeof performance&&(performance={}),!performance.now){var x=Date.now();performance.timing&&performance.timing.navigationStart&&(x=performance.timing.navigationStart),performance.now=function(){return Date.now()-x}}new n;o.prototype.step=function(t,e,i){if(i=i||10,e=e||0,0===e)this.internalStep(t),this.time+=t;else{this.accumulator+=e;for(var o=0;this.accumulator>=t&&i>o;)this.internalStep(t),this.accumulator-=t,o++;for(var n=this.accumulator%t/t,s=0;s!==this.bodies.length;s++){var r=this.bodies[s];r.previousPosition.lerp(r.position,n,r.interpolatedPosition),r.previousQuaternion.slerp(r.quaternion,n,r.interpolatedQuaternion),r.previousQuaternion.normalize()}this.time+=e}};var b={type:"postStep"},B={type:"preStep"},A={type:d.COLLIDE_EVENT_NAME,body:null,contact:null},E=[],z=[],S=[],M=[];new n,new n,new n,new n,new n,new n,new n,new n,new n,new s,new s,new s,new n;o.prototype.internalStep=function(t){this.dt=t;var e,i=this.contacts,o=S,n=M,s=this.numObjects(),r=this.bodies,a=this.solver,h=this.gravity,l=this.doProfiling,p=this.profile,c=d.DYNAMIC,u=this.constraints,v=z,y=(h.norm(),h.x),f=h.y,m=h.z,w=0;for(l&&(e=performance.now()),w=0;w!==s;w++){var g=r[w];if(g.type===c){var x=g.force,C=g.mass;x.x+=C*y,x.y+=C*f,x.z+=C*m}}for(var w=0,F=this.subsystems.length;w!==F;w++)this.subsystems[w].update();l&&(e=performance.now()),o.length=0,n.length=0,this.broadphase.collisionPairs(this,o,n),l&&(p.broadphase=performance.now()-e);var R=u.length;for(w=0;w!==R;w++){var T=u[w];if(!T.collideConnected)for(var I=o.length-1;I>=0;I-=1)(T.bodyA===o[I]&&T.bodyB===n[I]||T.bodyB===o[I]&&T.bodyA===n[I])&&(o.splice(I,1),n.splice(I,1))}this.collisionMatrixTick(),l&&(e=performance.now());var N=E,P=i.length;for(w=0;w!==P;w++)N.push(i[w]);i.length=0;var q=this.frictionEquations.length;for(w=0;w!==q;w++)v.push(this.frictionEquations[w]);this.frictionEquations.length=0,this.narrowphase.getContacts(o,n,this,i,N,this.frictionEquations,v),l&&(p.narrowphase=performance.now()-e),l&&(e=performance.now());for(var w=0;w=0&&V.material.friction>=0&&(_=g.material.friction*V.material.friction),g.material.restitution>=0&&V.material.restitution>=0&&(T.restitution=g.material.restitution*V.material.restitution)),a.addEquation(T),g.allowSleep&&g.type===d.DYNAMIC&&g.sleepState===d.SLEEPING&&V.sleepState===d.AWAKE&&V.type!==d.STATIC){var D=V.velocity.norm2()+V.angularVelocity.norm2(),H=Math.pow(V.sleepSpeedLimit,2);D>=2*H&&(g._wakeUpAfterNarrowphase=!0)}if(V.allowSleep&&V.type===d.DYNAMIC&&V.sleepState===d.SLEEPING&&g.sleepState===d.AWAKE&&g.type!==d.STATIC){var U=g.velocity.norm2()+g.angularVelocity.norm2(),Y=Math.pow(g.sleepSpeedLimit,2);U>=2*Y&&(V._wakeUpAfterNarrowphase=!0)}this.collisionMatrix.set(g,V,!0),this.collisionMatrixPrevious.get(g,V)||(A.body=V,A.contact=T,g.dispatchEvent(A),A.body=g,V.dispatchEvent(A)),this.bodyOverlapKeeper.set(g.id,V.id),this.shapeOverlapKeeper.set(k.id,O.id)}for(this.emitContactEvents(),l&&(p.makeContactConstraints=performance.now()-e,e=performance.now()),w=0;w!==s;w++){var g=r[w];g._wakeUpAfterNarrowphase&&(g.wakeUp(),g._wakeUpAfterNarrowphase=!1)}var R=u.length;for(w=0;w!==R;w++){var T=u[w];T.update();for(var I=0,X=T.equations.length;I!==X;I++){var G=T.equations[I];a.addEquation(G)}}a.solve(t,this),l&&(p.solve=performance.now()-e),a.removeAllEquations();var K=Math.pow;for(w=0;w!==s;w++){var g=r[w];if(g.type&c){var Z=K(1-g.linearDamping,t),Q=g.velocity;Q.mult(Z,Q);var J=g.angularVelocity;if(J){var $=K(1-g.angularDamping,t);J.mult($,J)}}}for(this.dispatchEvent(B),w=0;w!==s;w++){var g=r[w];g.preStep&&g.preStep.call(g)}l&&(e=performance.now());var tt=this.stepnumber,et=tt%(this.quatNormalizeSkip+1)===0,it=this.quatNormalizeFast;for(w=0;w!==s;w++)r[w].integrate(t,et,it);for(this.clearForces(),this.broadphase.dirty=!0,l&&(p.integrate=performance.now()-e),this.time+=t,this.stepnumber+=1,this.dispatchEvent(b),w=0;w!==s;w++){var g=r[w],ot=g.postStep;ot&&ot.call(g)}if(this.allowSleep)for(w=0;w!==s;w++)r[w].sleepTick(this.time)},o.prototype.emitContactEvents=function(){var t=[],e=[],i={type:"beginContact",bodyA:null,bodyB:null},o={type:"endContact",bodyA:null,bodyB:null},n={type:"beginShapeContact",bodyA:null,bodyB:null,shapeA:null,shapeB:null},s={type:"endShapeContact",bodyA:null,bodyB:null,shapeA:null,shapeB:null};return function(){var r=this.hasAnyEventListener("beginContact"),a=this.hasAnyEventListener("endContact");if((r||a)&&this.bodyOverlapKeeper.getDiff(t,e),r){for(var h=0,l=t.length;l>h;h+=2)i.bodyA=this.getBodyById(t[h]), 5 | i.bodyB=this.getBodyById(t[h+1]),this.dispatchEvent(i);i.bodyA=i.bodyB=null}if(a){for(var h=0,l=e.length;l>h;h+=2)o.bodyA=this.getBodyById(e[h]),o.bodyB=this.getBodyById(e[h+1]),this.dispatchEvent(o);o.bodyA=o.bodyB=null}t.length=e.length=0;var p=this.hasAnyEventListener("beginShapeContact"),c=this.hasAnyEventListener("endShapeContact");if((p||c)&&this.shapeOverlapKeeper.getDiff(t,e),p){for(var h=0,l=t.length;l>h;h+=2){var u=this.getShapeById(t[h]),d=this.getShapeById(t[h+1]);n.shapeA=u,n.shapeB=d,n.bodyA=u.body,n.bodyB=d.body,this.dispatchEvent(n)}n.bodyA=n.bodyB=n.shapeA=n.shapeB=null}if(c){for(var h=0,l=e.length;l>h;h+=2){var u=this.getShapeById(e[h]),d=this.getShapeById(e[h+1]);s.shapeA=u,s.shapeB=d,s.bodyA=u.body,s.bodyB=d.body,this.dispatchEvent(s)}s.bodyA=s.bodyB=s.shapeA=s.shapeB=null}}}(),o.prototype.clearForces=function(){for(var t=this.bodies,e=t.length,i=0;i!==e;i++){var o=t[i];o.force,o.torque;o.force.set(0,0,0),o.torque.set(0,0,0)}}},function(t,e){t.exports={name:"cannon",version:"0.6.2",description:"A lightweight 3D physics engine written in JavaScript.",homepage:"https://github.com/schteppe/cannon.js",author:{name:"Stefan Hedman",email:"schteppe@gmail.com",url:"http://steffe.se"},keywords:["cannon.js","cannon","physics","engine","3d"],main:"./src/Cannon.js",engines:{node:"*"},repository:{type:"git",url:"git+https://github.com/schteppe/cannon.js.git"},bugs:{url:"https://github.com/schteppe/cannon.js/issues"},licenses:[{type:"MIT"}],devDependencies:{jshint:"latest","uglify-js":"latest",nodeunit:"^0.9.0",grunt:"~0.4.0","grunt-contrib-jshint":"~0.1.1","grunt-contrib-nodeunit":"^0.4.1","grunt-contrib-concat":"~0.1.3","grunt-contrib-uglify":"^0.5.1","grunt-browserify":"^2.1.4","grunt-contrib-yuidoc":"^0.5.2",browserify:"*"},dependencies:{},gitHead:"022e8ba53fa83abf0ad8a0e4fd08623123838a17",readme:'# cannon.js\n\n### Lightweight 3D physics for the web\nInspired by [three.js](https://github.com/mrdoob/three.js) and [ammo.js](https://github.com/kripken/ammo.js), and driven by the fact that the web lacks a physics engine, here comes cannon.js.\nThe rigid body physics engine includes simple collision detection, various body shapes, contacts, friction and constraints.\n\n[Demos](http://schteppe.github.com/cannon.js) - [Documentation](http://schteppe.github.com/cannon.js/docs) - [Rendering hints](https://github.com/schteppe/cannon.js/tree/master/examples) - [NPM package](https://npmjs.org/package/cannon) - [CDN](https://cdnjs.com/libraries/cannon.js)\n\n### Browser install\n\nJust include [cannon.js](https://github.com/schteppe/cannon.js/releases/download/v0.6.2/cannon.js) or [cannon.min.js](https://github.com/schteppe/cannon.js/releases/download/v0.6.2/cannon.min.js) in your html and you\'re done:\n\n```html\n\n```\n\n### Node.js install\n\nInstall the cannon package via NPM:\n\n```bash\nnpm install --save cannon\n```\n\nAlternatively, point to the Github repo directly to get the very latest version:\n\n```bash\nnpm install --save schteppe/cannon.js\n```\n\n### Example\n\nThe sample code below creates a sphere on a plane, steps the simulation, and prints the sphere simulation to the console. Note that Cannon.js uses [SI units](http://en.wikipedia.org/wiki/International_System_of_Units) (metre, kilogram, second, etc.).\n\n```javascript\n// Setup our world\nvar world = new CANNON.World();\nworld.gravity.set(0, 0, -9.82); // m/s²\n\n// Create a sphere\nvar radius = 1; // m\nvar sphereBody = new CANNON.Body({\n mass: 5, // kg\n position: new CANNON.Vec3(0, 0, 10), // m\n shape: new CANNON.Sphere(radius)\n});\nworld.addBody(sphereBody);\n\n// Create a plane\nvar groundBody = new CANNON.Body({\n mass: 0 // mass == 0 makes the body static\n});\nvar groundShape = new CANNON.Plane();\ngroundBody.addShape(groundShape);\nworld.addBody(groundBody);\n\nvar fixedTimeStep = 1.0 / 60.0; // seconds\nvar maxSubSteps = 3;\n\n// Start the simulation loop\nvar lastTime;\n(function simloop(time){\n requestAnimationFrame(simloop);\n if(lastTime !== undefined){\n var dt = (time - lastTime) / 1000;\n world.step(fixedTimeStep, dt, maxSubSteps);\n }\n console.log("Sphere z position: " + sphereBody.position.z);\n lastTime = time;\n})();\n```\n\nIf you want to know how to use cannon.js with a rendering engine, for example Three.js, see the [Examples](examples).\n\n### Features\n* Rigid body dynamics\n* Discrete collision detection\n* Contacts, friction and restitution\n* Constraints\n * PointToPoint (a.k.a. ball/socket joint)\n * Distance\n * Hinge (with optional motor)\n * Lock\n * ConeTwist\n* Gauss-Seidel constraint solver and an island split algorithm\n* Collision filters\n* Body sleeping\n* Experimental SPH / fluid support\n* Various shapes and collision algorithms (see table below)\n\n| | [Sphere](http://schteppe.github.io/cannon.js/docs/classes/Sphere.html) | [Plane](http://schteppe.github.io/cannon.js/docs/classes/Plane.html) | [Box](http://schteppe.github.io/cannon.js/docs/classes/Box.html) | [Convex](http://schteppe.github.io/cannon.js/docs/classes/ConvexPolyhedron.html) | [Particle](http://schteppe.github.io/cannon.js/docs/classes/Particle.html) | [Heightfield](http://schteppe.github.io/cannon.js/docs/classes/Heightfield.html) | [Trimesh](http://schteppe.github.io/cannon.js/docs/classes/Trimesh.html) |\n| :-----------|:------:|:-----:|:---:|:------:|:--------:|:-----------:|:-------:|\n| Sphere | Yes | Yes | Yes | Yes | Yes | Yes | Yes |\n| Plane | - | - | Yes | Yes | Yes | - | Yes |\n| Box | - | - | Yes | Yes | Yes | Yes | (todo) |\n| Cylinder | - | - | Yes | Yes | Yes | Yes | (todo) |\n| Convex | - | - | - | Yes | Yes | Yes | (todo) |\n| Particle | - | - | - | - | - | (todo) | (todo) |\n| Heightfield | - | - | - | - | - | - | (todo) |\n| Trimesh | - | - | - | - | - | - | - |\n\n### Todo\nThe simpler todos are marked with ```@todo``` in the code. Github Issues can and should also be used for todos.\n\n### Help\nCreate an [issue](https://github.com/schteppe/cannon.js/issues) if you need help.\n',readmeFilename:"README.markdown",_id:"cannon@0.6.2",_shasum:"1dd279639eb713fa5b8d6c0d02a7ca79177f881f",_from:"schteppe/cannon.js#022e8ba53fa83abf0ad8a0e4fd08623123838a17",_resolved:"git://github.com/schteppe/cannon.js.git#022e8ba53fa83abf0ad8a0e4fd08623123838a17"}},function(t,e,i){var o=i(35),n=(AFRAME.utils.coordinates,AFRAME.utils.diff),s=THREE.Math.degToRad,r=THREE.Math.radToDeg,a={schema:{gravity:{type:"vec3","default":{x:0,y:-9.82,z:0}}},init:function(){var t=this.el,e=this.world=new o.World;this.fixedTimeStep=1/60,this.maxSubSteps=3,["beginContact","endContact"].forEach(function(i){e.addEventListener(i,function(e){t.emit("physics-"+i,{bodyA:e.bodyA.el,bodyB:e.bodyB.el,target:e.target,bubbles:!1})})})},update:function(t){var e=this.data.gravity,i=this.world;i.broadphase=new o.NaiveBroadphase,i.gravity.set(e.x,e.y,e.z)},tick:function(t){var e=this.fixedTimeStep,i=this.maxSubsteps,o=this.world;if(void 0!==this.lastTime){var n=(t-this.lastTime)/1e3;o.step(e,n,i),o.bodies.forEach(function(t){t.tickWorld&&t.tickWorld()})}this.lastTime=t}},h={dependencies:["position"],schema:{angularVelocity:{type:"vec3"},angularDamping:{"default":.01},boundingBox:{type:"vec3"},linearDamping:{"default":.01},mass:{"default":1},velocity:{type:"vec3"}},init:function(){var t=this,e=this.el.sceneEl;this.tickWorldBound=this.tickWorld.bind(this),e.addEventListener("loaded",function(){"physics-world"in e.components||console.warn("physics-world must be specified on scene for physics to work.");var i=t.world=e.components["physics-world"].world,o=t.body=t.getBody(t.el,t.data);i.add(o)})},update:function(t){if(this.world){var e=n(this.data,t);"velocity"in e&&(this.body.velocity.x=e.velocity.x,this.body.velocity.y=e.velocity.y,this.body.velocity.z=e.velocity.z)}},applyImpulse:function(t,e){e=e||{x:0,y:0,z:0},this.body.applyImpulse(new o.Vec3(t.x,t.y,t.z),new o.Vec3(e.x,e.y,e.z))},getBody:function(t,e){var i=e.boundingBox,n=t.getAttribute("position"),r=e.angularVelocity,a=e.velocity,h={angularDamping:e.angularDamping,angularVelocity:new o.Vec3(s(r.x),s(r.y),s(r.z)),linearDamping:e.linearDamping,mass:e.mass,position:new o.Vec3(n.x,n.y,n.z),shape:new o.Box(new o.Vec3(i.x/2,i.y/2,i.z/2)),velocity:new o.Vec3(a.x,a.y,a.z)};return body=new o.Body(h),body.el=t,body.tickWorld=this.tickWorldBound,body.addEventListener("collide",function(e){t.emit("physics-collide",{body:e.body,contact:e.contact,target:e.target,bubbles:!1})}),body},tickWorld:function(){var t=this.body,e=this.el;e.setAttribute("position",t.position),this.el.components.camera||e.setAttribute("rotation",{x:r(t.quaternion.x),y:r(t.quaternion.y),z:r(t.quaternion.z)})}};t.exports.components={"physics-body":h,"physics-world":a,"wasd-physics-controls":i(59)}},function(t,e){var i=.2;t.exports={dependendencies:["physics-body"],schema:{easing:{"default":20},acceleration:{"default":65},enabled:{"default":!0},fly:{"default":!1},wsAxis:{"default":"z",oneOf:["x","y","z"]},adAxis:{"default":"x",oneOf:["x","y","z"]},wsInverted:{"default":!1},wsEnabled:{"default":!0},adInverted:{"default":!1},adEnabled:{"default":!0}},init:function(){this.velocity=new THREE.Vector3,this.keys={},this.onKeyDown=this.onKeyDown.bind(this),this.onKeyUp=this.onKeyUp.bind(this)},update:function(t){var e=this.data,o=e.acceleration,n=e.easing,s=this.velocity,r=this.prevTime=this.prevTime||Date.now(),a=window.performance.now(),h=(a-r)/1e3,l=this.keys,p=e.adAxis,c=e.wsAxis,u=e.adInverted?-1:1,d=e.wsInverted?-1:1,v=this.el;return this.prevTime=a,t||h>i?(s[p]=0,void(s[c]=0)):(s[p]-=s[p]*n*h,s[c]-=s[c]*n*h,e.enabled&&(e.adEnabled&&(l[65]&&(s[p]-=u*o*h),l[68]&&(s[p]+=u*o*h)),e.wsEnabled&&(l[87]&&(s[c]-=d*o*h),l[83]&&(s[c]+=d*o*h))),s=this.getMovementVector(s),void v.setAttribute("physics-body","velocity",{x:s.x,y:s.y,z:s.z}))},play:function(){this.attachEventListeners()},pause:function(){this.removeEventListeners()},tick:function(t){this.update()},remove:function(){this.pause()},attachEventListeners:function(){window.addEventListener("keydown",this.onKeyDown,!1),window.addEventListener("keyup",this.onKeyUp,!1)},removeEventListeners:function(){window.removeEventListener("keydown",this.onKeyDown),window.removeEventListener("keyup",this.onKeyUp)},onKeyDown:function(t){this.keys[t.keyCode]=!0},onKeyUp:function(t){this.keys[t.keyCode]=!1},getMovementVector:function(t){var e=new THREE.Vector3(0,0,0),i=new THREE.Euler(0,0,0,"YXZ"),t=t,o=this.el.getAttribute("rotation");return e.copy(t),o?(this.data.fly||(o.x=0),i.set(THREE.Math.degToRad(o.x),THREE.Math.degToRad(o.y),0),e.applyEuler(i),e):e}}}]); -------------------------------------------------------------------------------- /examples/basic/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 16 | 20 | 21 | 22 | 23 | 25 | 27 | 28 | 32 | 33 | 34 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /examples/bounce/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | A-Frame Physics Components 4 | 5 | 22 | 23 | 24 |

A-Frame Physics Components

25 | Basic 26 | Bounce 27 | 28 |
29 |
30 | Fork me on GitHub 31 |
32 |
33 | 34 | 35 | -------------------------------------------------------------------------------- /examples/main.js: -------------------------------------------------------------------------------- 1 | require('aframe'); 2 | require('../src/index.js'); 3 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "aframe-physics-components", 3 | "version": "1.1.0", 4 | "description": "Physics components for A-Frame VR.", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "build": "browserify examples/main.js -o examples/build.js", 8 | "dev": "budo examples/main.js:build.js --dir examples --port 8001 --live --open", 9 | "dist": "webpack src/index.js dist/aframe-physics-component.js && webpack -p src/index.js dist/aframe-physics-component.min.js", 10 | "postpublish": "npm run dist", 11 | "preghpages": "npm run build && rm -rf gh-pages && cp -r examples gh-pages", 12 | "ghpages": "npm run preghpages && ghpages -p gh-pages", 13 | "test": "karma start ./tests/karma.conf.js", 14 | "unboil": "node scripts/unboil.js" 15 | }, 16 | "repository": { 17 | "type": "git", 18 | "url": "git+https://github.com/ngokevin/aframe-physics-components.git" 19 | }, 20 | "keywords": [ 21 | "aframe", 22 | "aframe-component", 23 | "aframe-physics-component", 24 | "aframe-physics-components", 25 | "aframe-physics-components", 26 | "aframe-physics", 27 | "layout", 28 | "aframe-vr", 29 | "vr", 30 | "aframe-layout", 31 | "mozvr", 32 | "webvr" 33 | ], 34 | "author": "Kevin Ngo ", 35 | "license": "MIT", 36 | "bugs": { 37 | "url": "https://github.com/ngokevin/aframe-physics-components/issues" 38 | }, 39 | "homepage": "https://github.com/ngokevin/aframe-physics-components#readme", 40 | "devDependencies": { 41 | "aframe": "^0.2.0", 42 | "browserify": "^12.0.1", 43 | "budo": "^7.1.0", 44 | "chai": "^3.4.1", 45 | "chai-shallow-deep-equal": "^1.3.0", 46 | "ghpages": "0.0.3", 47 | "json-loader": "^0.5.4", 48 | "karma": "^0.13.15", 49 | "karma-browserify": "^4.4.2", 50 | "karma-chai-shallow-deep-equal": "0.0.4", 51 | "karma-firefox-launcher": "^0.1.7", 52 | "karma-mocha": "^0.2.1", 53 | "karma-mocha-reporter": "^1.1.3", 54 | "karma-sinon-chai": "^1.1.0", 55 | "mocha": "^2.3.4", 56 | "webpack": "^1.12.9" 57 | }, 58 | "dependencies": { 59 | "cannon": "schteppe/cannon.js#022e8ba53fa83abf0ad8a0e4fd08623123838a17" 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/CannonDebugRenderer.js: -------------------------------------------------------------------------------- 1 | /* global CANNON,THREE,Detector */ 2 | 3 | /** 4 | * Adds Three.js primitives into the scene where all the Cannon bodies and shapes are. 5 | * @class CannonDebugRenderer 6 | * @param {THREE.Scene} scene 7 | * @param {CANNON.World} world 8 | * @param {object} [options] 9 | */ 10 | 11 | var CANNON = require('cannon'); 12 | 13 | THREE.CannonDebugRenderer = function(scene, world, options){ 14 | options = options || {}; 15 | 16 | this.scene = scene; 17 | this.world = world; 18 | 19 | this._meshes = []; 20 | 21 | this._material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true }); 22 | this._sphereGeometry = new THREE.SphereGeometry(1); 23 | this._boxGeometry = new THREE.BoxGeometry(1, 1, 1); 24 | this._planeGeometry = new THREE.PlaneGeometry( 10, 10, 10, 10 ); 25 | this._cylinderGeometry = new THREE.CylinderGeometry( 1, 1, 10, 10 ); 26 | }; 27 | 28 | THREE.CannonDebugRenderer.prototype = { 29 | 30 | tmpVec0: new CANNON.Vec3(), 31 | tmpVec1: new CANNON.Vec3(), 32 | tmpVec2: new CANNON.Vec3(), 33 | tmpQuat0: new CANNON.Vec3(), 34 | 35 | update: function(){ 36 | 37 | var bodies = this.world.bodies; 38 | var meshes = this._meshes; 39 | var shapeWorldPosition = this.tmpVec0; 40 | var shapeWorldQuaternion = this.tmpQuat0; 41 | 42 | var meshIndex = 0; 43 | 44 | for (var i = 0; i !== bodies.length; i++) { 45 | var body = bodies[i]; 46 | 47 | for (var j = 0; j !== body.shapes.length; j++) { 48 | var shape = body.shapes[j]; 49 | 50 | this._updateMesh(meshIndex, body, shape); 51 | 52 | var mesh = meshes[meshIndex]; 53 | 54 | if(mesh){ 55 | 56 | // Get world position 57 | body.quaternion.vmult(body.shapeOffsets[j], shapeWorldPosition); 58 | body.position.vadd(shapeWorldPosition, shapeWorldPosition); 59 | 60 | // Get world quaternion 61 | body.quaternion.mult(body.shapeOrientations[j], shapeWorldQuaternion); 62 | 63 | // Copy to meshes 64 | mesh.position.copy(shapeWorldPosition); 65 | mesh.quaternion.copy(shapeWorldQuaternion); 66 | } 67 | 68 | meshIndex++; 69 | } 70 | } 71 | 72 | for(var i = meshIndex; i < meshes.length; i++){ 73 | var mesh = meshes[i]; 74 | if(mesh){ 75 | this.scene.remove(mesh); 76 | } 77 | } 78 | 79 | meshes.length = meshIndex; 80 | }, 81 | 82 | _updateMesh: function(index, body, shape){ 83 | var mesh = this._meshes[index]; 84 | if(!this._typeMatch(mesh, shape)){ 85 | if(mesh){ 86 | this.scene.remove(mesh); 87 | } 88 | mesh = this._meshes[index] = this._createMesh(shape); 89 | } 90 | this._scaleMesh(mesh, shape); 91 | }, 92 | 93 | _typeMatch: function(mesh, shape){ 94 | if(!mesh){ 95 | return false; 96 | } 97 | var geo = mesh.geometry; 98 | return ( 99 | (geo instanceof THREE.SphereGeometry && shape instanceof CANNON.Sphere) || 100 | (geo instanceof THREE.BoxGeometry && shape instanceof CANNON.Box) || 101 | (geo instanceof THREE.PlaneGeometry && shape instanceof CANNON.Plane) || 102 | (geo.id === shape.geometryId && shape instanceof CANNON.ConvexPolyhedron) || 103 | (geo.id === shape.geometryId && shape instanceof CANNON.Trimesh) || 104 | (geo.id === shape.geometryId && shape instanceof CANNON.Heightfield) 105 | ); 106 | }, 107 | 108 | _createMesh: function(shape){ 109 | var mesh; 110 | var material = this._material; 111 | 112 | switch(shape.type){ 113 | 114 | case CANNON.Shape.types.SPHERE: 115 | mesh = new THREE.Mesh(this._sphereGeometry, material); 116 | break; 117 | 118 | case CANNON.Shape.types.BOX: 119 | mesh = new THREE.Mesh(this._boxGeometry, material); 120 | break; 121 | 122 | case CANNON.Shape.types.PLANE: 123 | mesh = new THREE.Mesh(this._planeGeometry, material); 124 | break; 125 | 126 | case CANNON.Shape.types.CONVEXPOLYHEDRON: 127 | // Create mesh 128 | var geo = new THREE.Geometry(); 129 | 130 | // Add vertices 131 | for (var i = 0; i < shape.vertices.length; i++) { 132 | var v = shape.vertices[i]; 133 | geo.vertices.push(new THREE.Vector3(v.x, v.y, v.z)); 134 | } 135 | 136 | for(var i=0; i < shape.faces.length; i++){ 137 | var face = shape.faces[i]; 138 | 139 | // add triangles 140 | var a = face[0]; 141 | for (var j = 1; j < face.length - 1; j++) { 142 | var b = face[j]; 143 | var c = face[j + 1]; 144 | geo.faces.push(new THREE.Face3(a, b, c)); 145 | } 146 | } 147 | geo.computeBoundingSphere(); 148 | geo.computeFaceNormals(); 149 | 150 | mesh = new THREE.Mesh(geo, material); 151 | shape.geometryId = geo.id; 152 | break; 153 | 154 | case CANNON.Shape.types.TRIMESH: 155 | var geometry = new THREE.Geometry(); 156 | var v0 = this.tmpVec0; 157 | var v1 = this.tmpVec1; 158 | var v2 = this.tmpVec2; 159 | for (var i = 0; i < shape.indices.length / 3; i++) { 160 | shape.getTriangleVertices(i, v0, v1, v2); 161 | geometry.vertices.push( 162 | new THREE.Vector3(v0.x, v0.y, v0.z), 163 | new THREE.Vector3(v1.x, v1.y, v1.z), 164 | new THREE.Vector3(v2.x, v2.y, v2.z) 165 | ); 166 | var j = geometry.vertices.length - 3; 167 | geometry.faces.push(new THREE.Face3(j, j+1, j+2)); 168 | } 169 | geometry.computeBoundingSphere(); 170 | geometry.computeFaceNormals(); 171 | mesh = new THREE.Mesh(geometry, material); 172 | shape.geometryId = geometry.id; 173 | break; 174 | 175 | case CANNON.Shape.types.HEIGHTFIELD: 176 | var geometry = new THREE.Geometry(); 177 | 178 | var v0 = this.tmpVec0; 179 | var v1 = this.tmpVec1; 180 | var v2 = this.tmpVec2; 181 | for (var xi = 0; xi < shape.data.length - 1; xi++) { 182 | for (var yi = 0; yi < shape.data[xi].length - 1; yi++) { 183 | for (var k = 0; k < 2; k++) { 184 | shape.getConvexTrianglePillar(xi, yi, k===0); 185 | v0.copy(shape.pillarConvex.vertices[0]); 186 | v1.copy(shape.pillarConvex.vertices[1]); 187 | v2.copy(shape.pillarConvex.vertices[2]); 188 | v0.vadd(shape.pillarOffset, v0); 189 | v1.vadd(shape.pillarOffset, v1); 190 | v2.vadd(shape.pillarOffset, v2); 191 | geometry.vertices.push( 192 | new THREE.Vector3(v0.x, v0.y, v0.z), 193 | new THREE.Vector3(v1.x, v1.y, v1.z), 194 | new THREE.Vector3(v2.x, v2.y, v2.z) 195 | ); 196 | var i = geometry.vertices.length - 3; 197 | geometry.faces.push(new THREE.Face3(i, i+1, i+2)); 198 | } 199 | } 200 | } 201 | geometry.computeBoundingSphere(); 202 | geometry.computeFaceNormals(); 203 | mesh = new THREE.Mesh(geometry, material); 204 | shape.geometryId = geometry.id; 205 | break; 206 | } 207 | 208 | if(mesh){ 209 | this.scene.add(mesh); 210 | } 211 | 212 | return mesh; 213 | }, 214 | 215 | _scaleMesh: function(mesh, shape){ 216 | switch(shape.type){ 217 | 218 | case CANNON.Shape.types.SPHERE: 219 | var radius = shape.radius; 220 | mesh.scale.set(radius, radius, radius); 221 | break; 222 | 223 | case CANNON.Shape.types.BOX: 224 | mesh.scale.copy(shape.halfExtents); 225 | mesh.scale.multiplyScalar(2); 226 | break; 227 | 228 | case CANNON.Shape.types.CONVEXPOLYHEDRON: 229 | mesh.scale.set(1,1,1); 230 | break; 231 | 232 | case CANNON.Shape.types.TRIMESH: 233 | mesh.scale.copy(shape.scale); 234 | break; 235 | 236 | case CANNON.Shape.types.HEIGHTFIELD: 237 | mesh.scale.set(1,1,1); 238 | break; 239 | 240 | } 241 | } 242 | }; 243 | 244 | module.exports = THREE.CannonDebugRenderer; 245 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | var CANNON = require('cannon'); 2 | require('./wasd-physics-controls'); 3 | require('./CannonDebugRenderer'); 4 | var coordinates = AFRAME.utils.coordinates; 5 | var diff = AFRAME.utils.diff; 6 | 7 | var rad = THREE.Math.degToRad; 8 | var deg = THREE.Math.radToDeg; 9 | var cannonDebugRenderer = null; 10 | 11 | // CANNON.World component. 12 | AFRAME.registerComponent('physics-world', { 13 | schema: { 14 | gravity: { type: 'vec3', default: { x: 0, y: -9.82, z: 0 } }, 15 | debug: { default: false } 16 | }, 17 | 18 | init: function () { 19 | var el = this.el; 20 | var world = this.world = new CANNON.World(); 21 | 22 | this.fixedTimeStep = 1.0 / 60.0; 23 | this.maxSubSteps = 3; 24 | 25 | // Artificially bubble physics-world events to entity. 26 | ['beginContact', 'endContact'].forEach(function (eventName) { 27 | world.addEventListener(eventName, function (event) { 28 | el.emit('physics-' + eventName, { 29 | bodyA: event.bodyA.el, 30 | bodyB: event.bodyB.el, 31 | target: event.target, 32 | bubbles: false 33 | }); 34 | }); 35 | }); 36 | 37 | var scene = this.el.sceneEl.object3D; 38 | 39 | if (this.data.debug) { 40 | cannonDebugRenderer = new THREE.CannonDebugRenderer(scene, world); 41 | } 42 | }, 43 | 44 | update: function (oldData) { 45 | var gravity = this.data.gravity; 46 | var world = this.world; 47 | world.broadphase = new CANNON.NaiveBroadphase(); 48 | world.gravity.set(gravity.x, gravity.y, gravity.z); 49 | }, 50 | 51 | tick: function (time) { 52 | // Simulation loop. 53 | var fixedTimeStep = this.fixedTimeStep; 54 | var maxSubSteps = this.maxSubsteps; 55 | var world = this.world; 56 | 57 | if (this.lastTime !== undefined){ 58 | var timeChange = (time - this.lastTime) / 1000; 59 | world.step(fixedTimeStep, timeChange, maxSubSteps); 60 | world.bodies.forEach(function (body) { 61 | if (body.tickWorld) { body.tickWorld(); } 62 | }); 63 | 64 | if (cannonDebugRenderer) 65 | cannonDebugRenderer.update(); 66 | } 67 | this.lastTime = time; 68 | } 69 | }); 70 | 71 | // CANNON.Body component. 72 | AFRAME.registerComponent('physics-body', { 73 | dependencies: ['position'], 74 | 75 | schema: { 76 | angularVelocity: { type: 'vec3' }, 77 | angularDamping: { default: 0.01 }, 78 | boundingBox: { type: 'vec3' }, 79 | linearDamping: { default: 0.01 }, 80 | mass: { default: 1 }, 81 | velocity: { type: 'vec3' } 82 | }, 83 | 84 | /** 85 | * TODO: Don't force physics-world to be on scene to allow for multiple physics worlds. 86 | */ 87 | init: function () { 88 | var self = this; 89 | var sceneEl = this.el.sceneEl; 90 | 91 | var run = function() { 92 | if (!('physics-world' in sceneEl.components)) { 93 | console.warn('physics-world must be specified on scene for physics to work.'); 94 | } 95 | var world = self.world = sceneEl.components['physics-world'].world; 96 | var body = self.body = self.getBody(self.el, self.data); 97 | world.add(body); 98 | }; 99 | 100 | this.tickWorldBound = this.tickWorld.bind(this); 101 | 102 | if (sceneEl.hasLoaded) { 103 | run(); 104 | } else { 105 | sceneEl.addEventListener('loaded', run) 106 | }; 107 | }, 108 | 109 | update: function (oldData) { 110 | if (!this.world) { return; } 111 | var diffData = diff(this.data, oldData || this.data); 112 | 113 | if ('velocity' in diffData) { 114 | this.body.velocity.x = diffData.velocity.x; 115 | this.body.velocity.y = diffData.velocity.y; 116 | this.body.velocity.z = diffData.velocity.z; 117 | } 118 | }, 119 | 120 | applyImpulse: function (forceVec3, pointVec3) { 121 | pointVec3 = pointVec3 || { x: 0, y: 0, z: 0 }; 122 | this.body.applyImpulse( 123 | new CANNON.Vec3(forceVec3.x, forceVec3.y, forceVec3.z), 124 | new CANNON.Vec3(pointVec3.x, pointVec3.y, pointVec3.z) 125 | ); 126 | }, 127 | 128 | getBody: function (el, data) { 129 | var boundingBox = data.boundingBox; 130 | var position = el.getAttribute('position'); 131 | var angularVelocity = data.angularVelocity; 132 | var velocity = data.velocity; 133 | 134 | var bodyProperties = { 135 | angularDamping: data.angularDamping, 136 | angularVelocity: new CANNON.Vec3(rad(angularVelocity.x), rad(angularVelocity.y), 137 | rad(angularVelocity.z)), 138 | linearDamping: data.linearDamping, 139 | mass: data.mass, 140 | position: new CANNON.Vec3(position.x, position.y, position.z), 141 | shape: new CANNON.Box(new CANNON.Vec3(boundingBox.x / 2, boundingBox.y / 2, 142 | boundingBox.z / 2)), 143 | velocity: new CANNON.Vec3(velocity.x, velocity.y, velocity.z) 144 | }; 145 | 146 | body = new CANNON.Body(bodyProperties); 147 | 148 | // Attach A-Frame stuff. 149 | body.el = el; 150 | body.tickWorld = this.tickWorldBound; 151 | 152 | // Artificially bubble physics-body event to entity. 153 | body.addEventListener('collide', function (event) { 154 | el.emit('physics-collide', { 155 | body: event.body, 156 | contact: event.contact, 157 | target: event.target, 158 | bubbles: false 159 | }); 160 | }); 161 | 162 | return body; 163 | }, 164 | 165 | /** 166 | * Copy CANNON rigid body properties to THREE object3D. 167 | */ 168 | tickWorld: function () { 169 | var body = this.body; 170 | var el = this.el; 171 | el.setAttribute('position', body.position); 172 | 173 | // Don't rotate camera around. 174 | if (this.el.components.camera) { return; } 175 | 176 | el.setAttribute('rotation', { 177 | x: deg(body.quaternion.x), 178 | y: deg(body.quaternion.y), 179 | z: deg(body.quaternion.z) 180 | }); 181 | } 182 | }); 183 | 184 | // CANNON.Material component. 185 | AFRAME.registerComponent('physics-material', { 186 | dependencies: ['physics-body'], 187 | 188 | schema: { 189 | angularVelocity: { type: 'vec3' }, 190 | angularDamping: { default: 0.01 }, 191 | boundingBox: { type: 'vec3' }, 192 | linearDamping: { default: 0.01 }, 193 | mass: { default: 1 }, 194 | velocity: { type: 'vec3' } 195 | }, 196 | 197 | /** 198 | * TODO: Don't force physics-world to be on scene to allow for multiple physics worlds. 199 | */ 200 | init: function () { 201 | var self = this; 202 | var sceneEl = this.el.sceneEl; 203 | 204 | this.tickWorldBound = this.tickWorld.bind(this); 205 | 206 | // Wait for scene to load to initialize physics world. 207 | sceneEl.addEventListener('loaded', function () { 208 | if (!('physics-world' in sceneEl.components)) { 209 | console.warn('physics-world must be specified on scene for physics to work.'); 210 | } 211 | var world = self.world = sceneEl.components['physics-world'].world; 212 | var body = self.body = self.getBody(self.el, self.data); 213 | world.add(body); 214 | }); 215 | }, 216 | 217 | update: function () { 218 | if (!this.world) { return; } 219 | }, 220 | 221 | applyImpulse: function (forceVec3, pointVec3) { 222 | pointVec3 = pointVec3 || { x: 0, y: 0, z: 0 }; 223 | this.body.applyImpulse( 224 | new CANNON.Vec3(forceVec3.x, forceVec3.y, forceVec3.z), 225 | new CANNON.Vec3(pointVec3.x, pointVec3.y, pointVec3.z) 226 | ); 227 | }, 228 | 229 | getBody: function (el, data) { 230 | var boundingBox = data.boundingBox; 231 | var position = el.getAttribute('position'); 232 | var angularVelocity = data.angularVelocity; 233 | var velocity = data.velocity; 234 | 235 | var bodyProperties = { 236 | angularDamping: data.angularDamping, 237 | angularVelocity: new CANNON.Vec3(rad(angularVelocity.x), rad(angularVelocity.y), 238 | rad(angularVelocity.z)), 239 | linearDamping: data.linearDamping, 240 | mass: data.mass, 241 | position: new CANNON.Vec3(position.x, position.y, position.z), 242 | shape: new CANNON.Box(new CANNON.Vec3(boundingBox.x / 2, boundingBox.y / 2, 243 | boundingBox.z / 2)), 244 | velocity: new CANNON.Vec3(velocity.x, velocity.y, velocity.z) 245 | }; 246 | 247 | body = new CANNON.Body(bodyProperties); 248 | 249 | // Attach A-Frame stuff. 250 | body.el = el; 251 | body.tick = this.tickWorldBound; 252 | 253 | // Artificially bubble physics-body event to entity. 254 | body.addEventListener('collide', function (event) { 255 | el.emit('physics-collide', { 256 | body: event.body, 257 | contact: event.contact, 258 | target: event.target, 259 | bubbles: false 260 | }); 261 | }); 262 | 263 | return body; 264 | }, 265 | 266 | /** 267 | * Copy CANNON rigid body properties to THREE object3D. 268 | */ 269 | tickWorld: function () { 270 | var body = this.body; 271 | var el = this.el; 272 | el.setAttribute('position', body.position); 273 | el.setAttribute('rotation', { 274 | x: deg(body.quaternion.x), 275 | y: deg(body.quaternion.y), 276 | z: deg(body.quaternion.z) 277 | }); 278 | } 279 | }); 280 | -------------------------------------------------------------------------------- /src/wasd-physics-controls.js: -------------------------------------------------------------------------------- 1 | var MAX_DELTA = 0.2; 2 | 3 | /** 4 | * Control an entity with WASD keys. 5 | */ 6 | AFRAME.registerComponent('wasd-physics-controls', { 7 | dependendencies: ['physics-body'], 8 | 9 | schema: { 10 | easing: { default: 20 }, 11 | acceleration: { default: 65 }, 12 | enabled: { default: true }, 13 | fly: { default: false }, 14 | wsAxis: { default: 'z', oneOf: [ 'x', 'y', 'z' ] }, 15 | adAxis: { default: 'x', oneOf: [ 'x', 'y', 'z' ] }, 16 | wsInverted: { default: false }, 17 | wsEnabled: { default: true }, 18 | adInverted: { default: false }, 19 | adEnabled: { default: true } 20 | }, 21 | 22 | init: function () { 23 | this.velocity = new THREE.Vector3(); 24 | // To keep track of the pressed keys 25 | this.keys = {}; 26 | this.onKeyDown = this.onKeyDown.bind(this); 27 | this.onKeyUp = this.onKeyUp.bind(this); 28 | }, 29 | 30 | update: function (previousData) { 31 | var data = this.data; 32 | var acceleration = data.acceleration; 33 | var easing = data.easing; 34 | var velocity = this.velocity; 35 | var prevTime = this.prevTime = this.prevTime || Date.now(); 36 | var time = window.performance.now(); 37 | var delta = (time - prevTime) / 1000; 38 | var keys = this.keys; 39 | var movementVector; 40 | var adAxis = data.adAxis; 41 | var wsAxis = data.wsAxis; 42 | var adSign = data.adInverted ? -1 : 1; 43 | var wsSign = data.wsInverted ? -1 : 1; 44 | var el = this.el; 45 | this.prevTime = time; 46 | 47 | // If data changed or FPS too low, reset velocity. 48 | if (previousData || delta > MAX_DELTA) { 49 | velocity[adAxis] = 0; 50 | velocity[wsAxis] = 0; 51 | return; 52 | } 53 | 54 | velocity[adAxis] -= velocity[adAxis] * easing * delta; 55 | velocity[wsAxis] -= velocity[wsAxis] * easing * delta; 56 | 57 | if (data.enabled) { 58 | if (data.adEnabled) { 59 | if (keys[65]) { velocity[adAxis] -= adSign * acceleration * delta; } // Left 60 | if (keys[68]) { velocity[adAxis] += adSign * acceleration * delta; } // Right 61 | } 62 | if (data.wsEnabled) { 63 | if (keys[87]) { velocity[wsAxis] -= wsSign * acceleration * delta; } // Up 64 | if (keys[83]) { velocity[wsAxis] += wsSign * acceleration * delta; } // Down 65 | } 66 | } 67 | 68 | velocity = this.getMovementVector(velocity); 69 | el.setAttribute('physics-body', 'velocity', { 70 | x: velocity.x, 71 | y: velocity.y, 72 | z: velocity.z 73 | }); 74 | }, 75 | 76 | play: function () { 77 | this.attachEventListeners(); 78 | }, 79 | 80 | pause: function () { 81 | this.removeEventListeners(); 82 | }, 83 | 84 | tick: function (t) { 85 | this.update(); 86 | }, 87 | 88 | remove: function () { 89 | this.pause(); 90 | }, 91 | 92 | attachEventListeners: function () { 93 | // Keyboard events 94 | window.addEventListener('keydown', this.onKeyDown, false); 95 | window.addEventListener('keyup', this.onKeyUp, false); 96 | }, 97 | 98 | removeEventListeners: function () { 99 | // Keyboard events 100 | window.removeEventListener('keydown', this.onKeyDown); 101 | window.removeEventListener('keyup', this.onKeyUp); 102 | }, 103 | 104 | onKeyDown: function (event) { 105 | this.keys[event.keyCode] = true; 106 | }, 107 | 108 | onKeyUp: function (event) { 109 | this.keys[event.keyCode] = false; 110 | }, 111 | 112 | getMovementVector: function (velocity) { 113 | var direction = new THREE.Vector3(0, 0, 0); 114 | var rotation = new THREE.Euler(0, 0, 0, 'YXZ'); 115 | var velocity = velocity; 116 | var elRotation = this.el.getAttribute('rotation'); 117 | 118 | direction.copy(velocity); 119 | if (!elRotation) { return direction; } 120 | if (!this.data.fly) { elRotation.x = 0; } 121 | rotation.set(THREE.Math.degToRad(elRotation.x), 122 | THREE.Math.degToRad(elRotation.y), 0); 123 | direction.applyEuler(rotation); 124 | return direction; 125 | } 126 | }); 127 | -------------------------------------------------------------------------------- /tests/__init.test.js: -------------------------------------------------------------------------------- 1 | /* global sinon, setup, teardown */ 2 | 3 | /** 4 | * __init.test.js is run before every test case. 5 | */ 6 | window.debug = true; 7 | 8 | var AScene = require('aframe-core').AScene; 9 | 10 | beforeEach(function () { 11 | this.sinon = sinon.sandbox.create(); 12 | // Stub to not create a WebGL context since Travis CI runs headless. 13 | this.sinon.stub(AScene.prototype, 'attachedCallback'); 14 | }); 15 | 16 | afterEach(function () { 17 | // Clean up any attached elements. 18 | ['canvas', 'a-assets', 'a-scene'].forEach(function (tagName) { 19 | var els = document.querySelectorAll(tagName); 20 | for (var i = 0; i < els.length; i++) { 21 | els[i].parentNode.removeChild(els[i]); 22 | } 23 | }); 24 | AScene.scene = null; 25 | 26 | this.sinon.restore(); 27 | }); 28 | -------------------------------------------------------------------------------- /tests/helpers.js: -------------------------------------------------------------------------------- 1 | /* global suite */ 2 | 3 | /** 4 | * Helper method to create a scene, create an entity, add entity to scene, 5 | * add scene to document. 6 | * 7 | * @returns {object} An `` element. 8 | */ 9 | module.exports.entityFactory = function () { 10 | var scene = document.createElement('a-scene'); 11 | var entity = document.createElement('a-entity'); 12 | scene.appendChild(entity); 13 | document.body.appendChild(scene); 14 | return entity; 15 | }; 16 | 17 | /** 18 | * Creates and attaches a mixin element (and an `` element if necessary). 19 | * 20 | * @param {string} id - ID of mixin. 21 | * @param {object} obj - Map of component names to attribute values. 22 | * @returns {object} An attached `` element. 23 | */ 24 | module.exports.mixinFactory = function (id, obj) { 25 | var mixinEl = document.createElement('a-mixin'); 26 | mixinEl.setAttribute('id', id); 27 | Object.keys(obj).forEach(function (componentName) { 28 | mixinEl.setAttribute(componentName, obj[componentName]); 29 | }); 30 | 31 | var assetsEl = document.querySelector('a-assets'); 32 | if (!assetsEl) { 33 | assetsEl = document.createElement('a-assets'); 34 | document.body.appendChild(assetsEl); 35 | } 36 | assetsEl.appendChild(mixinEl); 37 | 38 | return mixinEl; 39 | }; 40 | 41 | /** 42 | * Test that is only run locally and is skipped on CI. 43 | */ 44 | module.exports.getSkipCISuite = function () { 45 | if (window.__env__.TEST_ENV === 'ci') { 46 | return suite.skip; 47 | } else { 48 | return suite; 49 | } 50 | }; 51 | -------------------------------------------------------------------------------- /tests/index.test.js: -------------------------------------------------------------------------------- 1 | var Aframe = require('aframe-core'); 2 | var example = require('../index.js').component; 3 | var entityFactory = require('./helpers').entityFactory; 4 | 5 | Aframe.registerComponent('example', example); 6 | 7 | describe('example', function () { 8 | beforeEach(function (done) { 9 | this.el = entityFactory(); 10 | this.el.addEventListener('loaded', function () { 11 | done(); 12 | }); 13 | }); 14 | 15 | describe('example property', function () { 16 | it('is good', function () { 17 | assert.equal(1, 1); 18 | }); 19 | }); 20 | }); 21 | -------------------------------------------------------------------------------- /tests/karma.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | module.exports = function (config) { 3 | config.set({ 4 | basePath: '../', 5 | browserify: { 6 | paths: ['./'] 7 | }, 8 | browsers: ['firefox_latest'], 9 | customLaunchers: { 10 | firefox_latest: { 11 | base: 'FirefoxNightly', 12 | prefs: { /* empty */ } 13 | } 14 | }, 15 | client: { 16 | captureConsole: true, 17 | mocha: {ui: 'bdd'} 18 | }, 19 | envPreprocessor: [ 20 | 'TEST_ENV' 21 | ], 22 | files: [ 23 | 'tests/**/*.test.js', 24 | ], 25 | frameworks: ['mocha', 'sinon-chai', 'chai-shallow-deep-equal', 'browserify'], 26 | preprocessors: { 27 | 'tests/**/*.js': ['browserify'] 28 | }, 29 | reporters: ['mocha'] 30 | }); 31 | }; 32 | --------------------------------------------------------------------------------