├── Makefile ├── README.md ├── examples ├── basic.html ├── domino.html ├── images │ ├── rocks.jpg │ └── screenshot-threex-cannonjs-512x512.jpg ├── manual.html ├── remove.html ├── three2cannon.html └── vendor │ └── three.js │ ├── build │ └── three.min.js │ └── examples │ └── js │ └── modifiers │ └── SubdivisionModifier.js ├── threex.cannonbody.js ├── threex.cannonworld.js └── vendor └── cannon.js ├── .gitignore ├── .jshintignore ├── .jshintrc ├── Gruntfile.js ├── LICENSE ├── README.markdown ├── VERSION ├── build ├── cannon.demo.js ├── cannon.js ├── cannon.min.js └── cannon.pretty.js ├── demos ├── README.markdown ├── bounce.html ├── bunny.html ├── bunny.js ├── callbacks.html ├── collisionFilter.html ├── collisions.html ├── compound.html ├── constraints.html ├── container.html ├── convexhull.html ├── events.html ├── friction.html ├── impulses.html ├── motionstates.html ├── pile.html ├── rotational.html ├── shapes.html ├── singleBodyOnPlane.html ├── sleep.html ├── sph.html ├── splitSolver.html ├── stacks.html └── style.css ├── examples ├── README.markdown ├── js │ ├── PointerLockControls.js │ └── VoxelLandscape.js ├── scenejs.html ├── sunflower.jpg ├── threejs.html ├── threejs_cloth.html ├── threejs_fps.html ├── threejs_voxel_fps.html └── worker.html ├── libs ├── Detector.js ├── Stats.js ├── Three.js ├── dat.gui.js ├── scenejs.js └── smoothie.js ├── package.json ├── src ├── Cannon.js ├── collision │ ├── Broadphase.js │ ├── GridBroadphase.js │ ├── NaiveBroadphase.js │ └── Ray.js ├── constraints │ ├── Constraint.js │ ├── ContactEquation.js │ ├── DistanceConstraint.js │ ├── Equation.js │ ├── FrictionEquation.js │ ├── HingeConstraint.js │ ├── PointToPointConstraint.js │ ├── RotationalEquation.js │ └── RotationalMotorEquation.js ├── demo │ └── Demo.js ├── material │ ├── ContactMaterial.js │ └── Material.js ├── math │ ├── Mat3.js │ ├── MatN.js │ ├── Quaternion.js │ └── Vec3.js ├── objects │ ├── Body.js │ ├── Box.js │ ├── Compound.js │ ├── ConvexPolyhedron.js │ ├── Cylinder.js │ ├── Particle.js │ ├── Plane.js │ ├── RigidBody.js │ ├── SPHSystem.js │ ├── Shape.js │ └── Sphere.js ├── solver │ ├── GSSolver.js │ ├── Solver.js │ └── SplitSolver.js ├── utils │ ├── EventTarget.js │ ├── Pool.js │ └── Vec3Pool.js ├── world │ ├── ContactGenerator.js │ └── World.js └── wrapper │ ├── End.js │ └── Start.js ├── test ├── Box.js ├── Compound.js ├── ConvexHull.js ├── ConvexPolyhedron.js ├── Mat3.js ├── Quaternion.js ├── Ray.js ├── RigidBody.js ├── Vec3.js └── World.js └── utils ├── JSCompress.py └── build.py /Makefile: -------------------------------------------------------------------------------- 1 | # makefile to automatize simple operations 2 | 3 | server: 4 | python -m SimpleHTTPServer 5 | 6 | deploy: 7 | # assume there is something to commit 8 | # use "git diff --exit-code HEAD" to know if there is something to commit 9 | # so two lines: one if no commit, one if something to commit 10 | git commit -a -m "New deploy" && git push -f origin HEAD:gh-pages && git reset HEAD~ 11 | 12 | install: 13 | git submodule update --init -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | threex.cannonjs 2 | =============== 3 | 4 | threex.cannonjs is a [threex game extension for three.js](http://jeromeetienne.github.io/threex/). It provides realistic physics easy to include in your own games. So you can take object in your game and make them fall as if it was the real world! You can code a [pool game](http://en.wikipedia.org/wiki/Pool_\(cue_sports\)) in a day! You make rocks falls from the sky in a realistic fasion! Sky is the limit! 5 | It is a warper over the excelent library [cannon.js](http://cannonjs.org/) physics library. It has been written by [Stefan Hedman](http://steffe.se/) or [@schteppe](https://twitter.com/schteppe) on twitter. 6 | 7 | Show Don't Tell 8 | =============== 9 | * [examples/basic.html](http://jeromeetienne.github.io/threex.cannonjs/examples/basic.html) 10 | \[[view source](https://github.com/jeromeetienne/threex.cannonjs/blob/master/examples/basic.html)\] : 11 | It shows this feature, and that one which is coded like that. 12 | * [examples/domino.html](http://jeromeetienne.github.io/threex.cannonjs/examples/domino.html) 13 | \[[view source](https://github.com/jeromeetienne/threex.cannonjs/blob/master/examples/domino.html)\] : 14 | It show dominos falling on each others like on tv :) 15 | 16 | A Screenshot 17 | ============ 18 | [![screenshot](https://raw.githubusercontent.com/jeromeetienne/threex.cannonjs/master/examples/images/screenshot-threex-cannonjs-512x512.jpg)](http://jeromeetienne.github.io/threex.cannonjs/examples/domino.html) 19 | 20 | How To Install It 21 | ================= 22 | 23 | You can install it manually. Just do 24 | 25 | ```html 26 | 27 | ``` 28 | 29 | You can install with [bower](http://bower.io/). 30 | 31 | ```bash 32 | bower install threex.cannonjs 33 | ``` 34 | 35 | then you add that in your html 36 | 37 | ```html 38 | 39 | ``` 40 | 41 | 42 | How To Install it ? 43 | =================== 44 | Init the physics world 45 | 46 | ```javascript 47 | var worldx = new THREEx.CannonWorld().start(); 48 | ``` 49 | 50 | create a physics body from a ```THREE.Mesh``` 51 | 52 | ```javascript 53 | var bodyx = new THREEx.CannonBody(mesh) 54 | ``` 55 | 56 | add this physics body to our physics world and keep updating it 57 | 58 | ```javascript 59 | worldx.add(bodyx) 60 | updateFcts.push(function(delta, now){ 61 | bodyx.update(delta, now); 62 | }); 63 | ``` 64 | 65 | one may wish to setup an initial velocity 66 | 67 | ```javacript 68 | bodyx.body.angularVelocity.set(0,2,0); 69 | ``` 70 | -------------------------------------------------------------------------------- /examples/basic.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 96 | -------------------------------------------------------------------------------- /examples/images/rocks.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeromeetienne/threex.cannonjs/ef51fa76a7dd3e7c28f7b4fca224d9b3a423ba46/examples/images/rocks.jpg -------------------------------------------------------------------------------- /examples/images/screenshot-threex-cannonjs-512x512.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeromeetienne/threex.cannonjs/ef51fa76a7dd3e7c28f7b4fca224d9b3a423ba46/examples/images/screenshot-threex-cannonjs-512x512.jpg -------------------------------------------------------------------------------- /examples/manual.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 78 | -------------------------------------------------------------------------------- /examples/remove.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 115 | -------------------------------------------------------------------------------- /examples/three2cannon.html: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 7 | 8 | 9 | 132 | -------------------------------------------------------------------------------- /threex.cannonbody.js: -------------------------------------------------------------------------------- 1 | var THREEx = THREEx || {} 2 | 3 | THREEx.CannonBody = function(opts){ 4 | // handle parameter polymorphism 5 | if( arguments.length === 1 && opts instanceof THREE.Object3D ) opts = {mesh:opts}; 6 | // handle parameters optional value 7 | opts = opts || {}; 8 | var mesh = opts.mesh !== undefined ? opts.mesh : console.assert(false) 9 | var mass = opts.mass !== undefined ? opts.mass : null; 10 | var shape = opts.shape !== undefined ? opts.shape : null; 11 | var material = opts.material !== undefined ? opts.material : undefined; 12 | var geometry = opts.geometry || mesh.geometry 13 | var cannon2three= opts.cannon2three !== undefined ? opts.cannon2three : true 14 | // 15 | if( geometry instanceof THREE.SphereGeometry ){ 16 | geometry.computeBoundingBox() 17 | var boundingBox = geometry.boundingBox 18 | var radius = ((boundingBox.max.x - boundingBox.min.x)* mesh.scale.x) /2 19 | if( shape === null ) shape = new CANNON.Sphere(radius) 20 | if( mass === null ) mass = 4/3 * Math.PI * Math.pow(radius, 3) 21 | }else if( geometry instanceof THREE.CubeGeometry ){ 22 | geometry.computeBoundingBox() 23 | var boundingBox = geometry.boundingBox 24 | var width = (boundingBox.max.x - boundingBox.min.x) * mesh.scale.x 25 | var height = (boundingBox.max.y - boundingBox.min.y) * mesh.scale.y 26 | var depth = (boundingBox.max.z - boundingBox.min.z) * mesh.scale.z 27 | if( shape === null ) shape = new CANNON.Box(new CANNON.Vec3(width/2, height/2, depth/2)) 28 | if( mass === null ) mass = Math.pow(width*width + height*height + depth*depth, 1/3) 29 | }else if( geometry instanceof THREE.PlaneGeometry ){ 30 | if( shape === null ) shape = new CANNON.Plane() 31 | if( mass === null ){ 32 | geometry.computeBoundingBox() 33 | var boundingBox = geometry.boundingBox 34 | var width = (boundingBox.max.x - boundingBox.min.x) * mesh.scale.x 35 | var height = (boundingBox.max.y - boundingBox.min.y) * mesh.scale.y 36 | var depth = (boundingBox.max.z - boundingBox.min.z) * mesh.scale.z 37 | mass = Math.pow(width*width + height*height, 1/2) 38 | } 39 | }else console.assert(false, 'unknown geometry type') 40 | 41 | var body = new CANNON.RigidBody(mass, shape, material) 42 | this.body = body 43 | // @TODO to remove 44 | Object.defineProperty(this, 'origin', { 45 | get : function(){ 46 | console.warn('THREEx.cannonBody depreciate .origin, use .body instead') 47 | return body 48 | } 49 | }) 50 | 51 | body.userData = body.userData || {} 52 | body.userData.object3d = mesh 53 | 54 | this.mesh = mesh 55 | 56 | // use quaternion 57 | mesh.userData.cannonBody= this 58 | 59 | // copy mesh.position to body.position 60 | body.position.x = mesh.position.x 61 | body.position.y = mesh.position.y 62 | body.position.z = mesh.position.z 63 | // copy mesh.quaternion to body.quaternion 64 | body.quaternion.x = mesh.quaternion.x 65 | body.quaternion.y = mesh.quaternion.y 66 | body.quaternion.z = mesh.quaternion.z 67 | body.quaternion.w = mesh.quaternion.w 68 | 69 | if( cannon2three ){ 70 | this.update = function(delta, now){ 71 | // copy body.position to mesh.position 72 | mesh.position.x = body.position.x 73 | mesh.position.y = body.position.y 74 | mesh.position.z = body.position.z 75 | // copy body.quaternion to mesh.quaternion 76 | mesh.quaternion.x = body.quaternion.x; 77 | mesh.quaternion.y = body.quaternion.y; 78 | mesh.quaternion.z = body.quaternion.z; 79 | mesh.quaternion.w = body.quaternion.w; 80 | } 81 | }else{ 82 | 83 | var pos 84 | this.update = function(delta, now){ 85 | // get position/quaternion in worldMatrix 86 | mesh.updateMatrixWorld() 87 | var position = new THREE.Vector3().getPositionFromMatrix(mesh.matrixWorld) 88 | var quaternion = new THREE.Quaternion().setFromRotationMatrix(mesh.matrixWorld) 89 | // copy mesh.position to body.position 90 | body.position.x = position.x 91 | body.position.y = position.y 92 | body.position.z = position.z 93 | // copy mesh.quaternion to body.quaternion 94 | body.quaternion.x = quaternion.x 95 | body.quaternion.y = quaternion.y 96 | body.quaternion.z = quaternion.z 97 | body.quaternion.w = quaternion.w 98 | } 99 | } 100 | } 101 | 102 | ////////////////////////////////////////////////////////////////////////////////// 103 | // Helpers // 104 | ////////////////////////////////////////////////////////////////////////////////// 105 | 106 | THREEx.CannonBody.prototype.applyImpulse = function(force, deltaTime) { 107 | var ball = this.mesh 108 | var impulse = force.clone().multiplyScalar(deltaTime) 109 | // apply the force to the center of the ball 110 | ball.updateMatrixWorld(); 111 | // get world position 112 | var ballPosition= new THREE.Vector3().getPositionFromMatrix( ball.matrixWorld ) 113 | 114 | // do an impulse to the ball 115 | var body = ball.userData.cannonBody.body 116 | var worldPoint = new CANNON.Vec3(ballPosition.x, ballPosition.y, ballPosition.z) 117 | var impulse = new CANNON.Vec3(impulse.x, impulse.y, impulse.z) 118 | body.applyImpulse(impulse, worldPoint); 119 | } 120 | 121 | THREEx.CannonBody.prototype.applyForce = function(force) { 122 | var ball = this.mesh 123 | // apply the force to the center of the ball 124 | ball.updateMatrixWorld(); 125 | // get world position 126 | var ballPosition= new THREE.Vector3().getPositionFromMatrix( ball.matrixWorld ) 127 | 128 | // do an impulse to the ball 129 | var body = ball.userData.cannonBody.body 130 | var worldPoint = new CANNON.Vec3(ballPosition.x, ballPosition.y, ballPosition.z) 131 | var cforce = new CANNON.Vec3(force.x, force.y, force.z) 132 | body.applyForce(cforce, worldPoint); 133 | } 134 | 135 | ////////////////////////////////////////////////////////////////////////////////// 136 | // Helpers // 137 | ////////////////////////////////////////////////////////////////////////////////// 138 | 139 | 140 | THREEx.CannonBody.prototype.addTo = function(worldx) { 141 | worldx.world.add(this.body) 142 | return this; 143 | }; 144 | 145 | THREEx.CannonBody.prototype.removeFrom = function(worldx) { 146 | worldx.world.remove(this.body) 147 | return this; 148 | }; -------------------------------------------------------------------------------- /threex.cannonworld.js: -------------------------------------------------------------------------------- 1 | var THREEx = THREEx || {} 2 | 3 | THREEx.CannonWorld = function(){ 4 | // physics world init 5 | var world = new CANNON.World() 6 | world.gravity.set(0,-9.81,0); 7 | world.broadphase = new CANNON.NaiveBroadphase(); 8 | 9 | // var solver = new CANNON.GSSolver(); 10 | // // world.defaultContactMaterial.contactEquationStiffness = 1e9; 11 | // // world.defaultContactMaterial.contactEquationRegularizationTime = 10; 12 | // solver.iterations = 30; 13 | // solver.tolerance = 0.01; 14 | // world.solver = new CANNON.SplitSolver(solver); 15 | 16 | 17 | // world.solver.iterations = 30 18 | 19 | this.world = world 20 | // @TODO to remove 21 | Object.defineProperty(this, 'origin', { 22 | get : function(){ 23 | console.warn('THREEx.cannonWorld depreciate .origin, use .world instead') 24 | return world 25 | } 26 | }) 27 | 28 | 29 | var timerId = null; 30 | 31 | 32 | /** 33 | * contains bodies to remove post world.step() - needed as it is impossible 34 | * to remove body during .step() - so inside a 'collide' notification 35 | * @type {Array[]} 36 | */ 37 | this.bodiesToRemove = [] 38 | 39 | /** 40 | * start periodically updating - it must not be done on animation frame 41 | * @param {Number} period the period to use for update. default to 1/60seconds 42 | */ 43 | this.start = function(period){ 44 | if( this.isRunning() === true ) return 45 | period = period !== undefined ? period : 1/60; 46 | timerId = setInterval(function(){ 47 | world.step(period); 48 | // honor this.bodiesToRemove 49 | this.bodiesToRemove.forEach(function(body){ 50 | world.remove(body) 51 | }) 52 | this.bodiesToRemove = [] 53 | }.bind(this), period*1000) 54 | return this; 55 | }.bind(this) 56 | /** 57 | * stop updating 58 | */ 59 | this.stop = function(){ 60 | if( this.isRunning() === false ) return 61 | clearInterval(timerId) 62 | timerId = null; 63 | } 64 | /** 65 | * test if world is running or not 66 | * @return {booleant} true if the world is running, false otherwise 67 | */ 68 | this.isRunning = function(){ 69 | return timerId !== null ? true : false 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vendor/cannon.js/.gitignore: -------------------------------------------------------------------------------- 1 | # Python compiled files 2 | *.pyc 3 | 4 | # Temp files 5 | *~ 6 | *# 7 | 8 | # Node Modules 9 | node_modules/* 10 | 11 | # File system 12 | .DS_Store -------------------------------------------------------------------------------- /vendor/cannon.js/.jshintignore: -------------------------------------------------------------------------------- 1 | src/wrapper 2 | src/objects/sph.js 3 | src/demo 4 | build 5 | examples 6 | demos 7 | libs 8 | node_modules 9 | test 10 | utils 11 | Gruntfile.js -------------------------------------------------------------------------------- /vendor/cannon.js/.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // environments 3 | "node" : true, 4 | "es5" : true, 5 | "browser" : true, 6 | 7 | // options 8 | "boss" : false, 9 | "curly": true, 10 | "debug": false, 11 | "devel": false, 12 | "eqeqeq": true, 13 | "eqnull": true, 14 | "evil": false, 15 | "forin": false, 16 | "immed": true, 17 | "laxbreak": false, 18 | "newcap": true, 19 | "noarg": true, 20 | "noempty": false, 21 | "nonew": false, 22 | "plusplus": false, 23 | "regexp": false, 24 | "smarttabs": true, 25 | "sub": true, 26 | "strict": false, 27 | "trailing" : true, 28 | "undef": true, 29 | "indent":4, 30 | "shadow" : true, 31 | "globals": { 32 | "CANNON": true 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /vendor/cannon.js/Gruntfile.js: -------------------------------------------------------------------------------- 1 | module.exports = function(grunt) { 2 | 3 | grunt.initConfig({ 4 | pkg: grunt.file.readJSON('package.json'), 5 | concat: { 6 | options: { 7 | separator: '\n\n' 8 | }, 9 | cannon : { 10 | src: [// Wrapper start 11 | "LICENSE", 12 | "src/wrapper/Start.js", 13 | "src/Cannon.js", 14 | 15 | // Math 16 | "src/math/Mat3.js", 17 | "src/math/Vec3.js", 18 | "src/math/Quaternion.js", 19 | 20 | // Utils 21 | "src/utils/EventTarget.js", 22 | "src/utils/Pool.js", 23 | "src/utils/Vec3Pool.js", 24 | 25 | // Objects 26 | "src/objects/Shape.js", 27 | "src/objects/Body.js", 28 | "src/objects/Particle.js", 29 | "src/objects/RigidBody.js", 30 | "src/objects/Sphere.js", 31 | "src/objects/SPHSystem.js", 32 | "src/objects/Box.js", 33 | "src/objects/Plane.js", 34 | "src/objects/Compound.js", 35 | "src/objects/ConvexPolyhedron.js", 36 | "src/objects/Cylinder.js", 37 | 38 | // Collision 39 | "src/collision/Ray.js", 40 | "src/collision/Broadphase.js", 41 | "src/collision/NaiveBroadphase.js", 42 | "src/collision/GridBroadphase.js", 43 | 44 | // Solver 45 | "src/solver/Solver.js", 46 | "src/solver/GSSolver.js", 47 | "src/solver/SplitSolver.js", 48 | 49 | // Material 50 | "src/material/Material.js", 51 | "src/material/ContactMaterial.js", 52 | 53 | // World 54 | "src/world/World.js", 55 | "src/world/ContactGenerator.js", 56 | 57 | // Constraints 58 | "src/constraints/Equation.js", 59 | "src/constraints/ContactEquation.js", 60 | "src/constraints/FrictionEquation.js", 61 | "src/constraints/RotationalEquation.js", 62 | "src/constraints/Constraint.js", 63 | "src/constraints/DistanceConstraint.js", 64 | "src/constraints/RotationalMotorEquation.js", 65 | "src/constraints/HingeConstraint.js", 66 | "src/constraints/PointToPointConstraint.js", 67 | 68 | // Wrapper end 69 | "src/wrapper/End.js", 70 | ], 71 | dest: 'build/cannon.js' 72 | }, 73 | 74 | demo : { 75 | src: ['src/demo/Demo.js'], 76 | dest: 'build/cannon.demo.js' 77 | }, 78 | }, 79 | 80 | uglify : { 81 | build : { 82 | src : ['build/cannon.js'], 83 | dest : 'build/cannon.min.js' 84 | } 85 | } 86 | }); 87 | 88 | grunt.loadNpmTasks('grunt-contrib-uglify'); 89 | grunt.loadNpmTasks('grunt-contrib-concat'); 90 | grunt.registerTask('default', ['concat:cannon', 'concat:demo', 'uglify']); 91 | 92 | }; 93 | -------------------------------------------------------------------------------- /vendor/cannon.js/LICENSE: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2012 cannon.js Authors 3 | * 4 | * Permission is hereby granted, free of charge, to any person 5 | * obtaining a copy of this software and associated documentation 6 | * files (the "Software"), to deal in the Software without 7 | * restriction, including without limitation the rights to use, copy, 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies 9 | * 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 13 | * included in all copies or substantial portions of the Software. 14 | * 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | */ 23 | -------------------------------------------------------------------------------- /vendor/cannon.js/VERSION: -------------------------------------------------------------------------------- 1 | 0.6.0 -------------------------------------------------------------------------------- /vendor/cannon.js/demos/README.markdown: -------------------------------------------------------------------------------- 1 | # Demo scenes 2 | 3 | Demo scenes to test or show off functionality in the engine. The CANNON.Demo class is used to produce interactive demos. -------------------------------------------------------------------------------- /vendor/cannon.js/demos/bounce.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - bounce demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 74 | 75 | 76 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/bunny.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - bunny demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/callbacks.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - callbacks demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/collisionFilter.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - collisionfilter demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/collisions.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - collisions demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 137 | 138 | 139 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/compound.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - compound demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/container.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - container demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 116 | 117 | 118 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/events.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - events demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/friction.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - friction demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/impulses.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - impulse demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 99 | 100 | 101 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/motionstates.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - motion states demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/pile.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - pile demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 97 | 98 | 99 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/rotational.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - callbacks demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 127 | 128 | 129 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/singleBodyOnPlane.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - single body on plane demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/sleep.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - sleep demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 125 | 126 | 127 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/sph.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - sph demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 110 | 111 | 112 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/splitSolver.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | cannon.js - splitsolver demo 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /vendor/cannon.js/demos/style.css: -------------------------------------------------------------------------------- 1 | * { 2 | margin:0; 3 | padding:0; 4 | } 5 | body { 6 | overflow: hidden; 7 | font-family: Monospace; 8 | } -------------------------------------------------------------------------------- /vendor/cannon.js/examples/README.markdown: -------------------------------------------------------------------------------- 1 | # How to render a Cannon.js scene 2 | 3 | You've learnt how to render really cool 3D in the browser, and now you want your mesh to move. You add your favorite physics engine (cannon.js) to your project, and then... what? 4 | 5 | These examples demonstrates how to render a Cannon.js physics scene using commonly used 3D libraries. The main problem is to make a mesh move according to a ```CANNON.RigidBody``` by synchronizing coordinates (position and orientation). 6 | 7 | If you are looking for more in-depth examples on how to use Cannon.js, go to the [demos](https://github.com/schteppe/cannon.js/tree/master/demos) instead. 8 | 9 | ### Three.js 10 | 11 | One of the most convenient ways of using Cannon.js with [Three.js](https://github.com/mrdoob/three.js/) is by enabling use of quaternions: 12 | 13 | ```javascript 14 | mesh.useQuaternion = true; 15 | ``` 16 | 17 | Then it gets really simple to copy over position+orientation data to the Three.js mesh: 18 | ```javascript 19 | rigidbody.position.copy(mesh.position); 20 | rigidbody.quaternion.copy(mesh.quaternion); 21 | ``` 22 | 23 | See [threejs.html](https://github.com/schteppe/cannon.js/blob/master/examples/threejs.html) for a full example. 24 | 25 | ### SceneJS 26 | 27 | [SceneJS](http://scenejs.org/) [supports quaternions](http://scenejs.wikispaces.com/quaternion), too. When setting up your scene, make sure to create a translation node and a quaternion node for your mesh. 28 | 29 | ``` 30 | ... 31 | { 32 | type: "translate", 33 | id: "my-translate", 34 | x : 0.0, y : 0.0, z : 0.0, 35 | 36 | nodes: [ 37 | { 38 | type: "quaternion", 39 | id: "my-quaternion", 40 | x : 1.0, y : 0.0, z : 0.0, angle : 0.0, 41 | 42 | nodes: [ 43 | ... 44 | ``` 45 | The update of these nodes can be done like this: 46 | ``` 47 | scene.findNode("my-translate").set("xyz",{ x:0.0, y:0.0, z:0.0}); 48 | scene.findNode("my-quaternion").set("rotation",{ x:0.0, y:0.0, z:0.0, angle:0.0 }); 49 | ``` 50 | The full example, and how to get the axis/angle representation of the ```CANNON.Quaternion```, can be found in [scenejs.html](https://github.com/schteppe/cannon.js/blob/master/examples/scenejs.html). 51 | 52 | ### KickJS (as of 0.5.1) 53 | 54 | You can easily update your KickJS game objects by copying the position and rotation vectors from cannon.js like this: 55 | 56 | ```javascript 57 | pos = rigidbody.position 58 | quat = rigidbody.quaternion 59 | gameObject.transform.position = [pos.x, pos.y, pos.z] 60 | gameObject.transform.rotation = [quat.x, quat.y, quat.z, quat.w] 61 | ``` 62 | 63 | Also, an easy way to step the physics simulation is to create a component with the following update-function and add it to a game object: 64 | 65 | ```javascript 66 | this.update = function() { 67 | world.step(0.001 * engine.time.deltaTime) 68 | } 69 | ``` 70 | -------------------------------------------------------------------------------- /vendor/cannon.js/examples/js/PointerLockControls.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author mrdoob / http://mrdoob.com/ 3 | * @author schteppe / https://github.com/schteppe 4 | */ 5 | var PointerLockControls = function ( camera, cannonBody ) { 6 | 7 | var eyeYPos = 2; // eyes are 2 meters above the ground 8 | var velocityFactor = 0.2; 9 | var jumpVelocity = 20; 10 | var scope = this; 11 | 12 | var pitchObject = new THREE.Object3D(); 13 | pitchObject.add( camera ); 14 | 15 | var yawObject = new THREE.Object3D(); 16 | yawObject.position.y = 2; 17 | yawObject.add( pitchObject ); 18 | 19 | var quat = new THREE.Quaternion(); 20 | 21 | var moveForward = false; 22 | var moveBackward = false; 23 | var moveLeft = false; 24 | var moveRight = false; 25 | 26 | var canJump = false; 27 | 28 | var contactNormal = new CANNON.Vec3(); // Normal in the contact, pointing *out* of whatever the player touched 29 | var upAxis = new CANNON.Vec3(0,1,0); 30 | cannonBody.addEventListener("collide",function(e){ 31 | var contact = e.contact; 32 | 33 | // contact.bi and contact.bj are the colliding bodies, and contact.ni is the collision normal. 34 | // We do not yet know which one is which! Let's check. 35 | if(contact.bi.id == cannonBody.id) // bi is the player body, flip the contact normal 36 | contact.ni.negate(contactNormal); 37 | else 38 | contact.ni.copy(contactNormal); // bi is something else. Keep the normal as it is 39 | 40 | // If contactNormal.dot(upAxis) is between 0 and 1, we know that the contact normal is somewhat in the up direction. 41 | if(contactNormal.dot(upAxis) > 0.5) // Use a "good" threshold value between 0 and 1 here! 42 | canJump = true; 43 | }); 44 | 45 | var velocity = cannonBody.velocity; 46 | 47 | var PI_2 = Math.PI / 2; 48 | 49 | var onMouseMove = function ( event ) { 50 | 51 | if ( scope.enabled === false ) return; 52 | 53 | var movementX = event.movementX || event.mozMovementX || event.webkitMovementX || 0; 54 | var movementY = event.movementY || event.mozMovementY || event.webkitMovementY || 0; 55 | 56 | yawObject.rotation.y -= movementX * 0.002; 57 | pitchObject.rotation.x -= movementY * 0.002; 58 | 59 | pitchObject.rotation.x = Math.max( - PI_2, Math.min( PI_2, pitchObject.rotation.x ) ); 60 | }; 61 | 62 | var onKeyDown = function ( event ) { 63 | 64 | switch ( event.keyCode ) { 65 | 66 | case 38: // up 67 | case 87: // w 68 | moveForward = true; 69 | break; 70 | 71 | case 37: // left 72 | case 65: // a 73 | moveLeft = true; break; 74 | 75 | case 40: // down 76 | case 83: // s 77 | moveBackward = true; 78 | break; 79 | 80 | case 39: // right 81 | case 68: // d 82 | moveRight = true; 83 | break; 84 | 85 | case 32: // space 86 | if ( canJump === true ){ 87 | velocity.y = jumpVelocity; 88 | } 89 | canJump = false; 90 | break; 91 | } 92 | 93 | }; 94 | 95 | var onKeyUp = function ( event ) { 96 | 97 | switch( event.keyCode ) { 98 | 99 | case 38: // up 100 | case 87: // w 101 | moveForward = false; 102 | break; 103 | 104 | case 37: // left 105 | case 65: // a 106 | moveLeft = false; 107 | break; 108 | 109 | case 40: // down 110 | case 83: // a 111 | moveBackward = false; 112 | break; 113 | 114 | case 39: // right 115 | case 68: // d 116 | moveRight = false; 117 | break; 118 | 119 | } 120 | 121 | }; 122 | 123 | document.addEventListener( 'mousemove', onMouseMove, false ); 124 | document.addEventListener( 'keydown', onKeyDown, false ); 125 | document.addEventListener( 'keyup', onKeyUp, false ); 126 | 127 | this.enabled = false; 128 | 129 | this.getObject = function () { 130 | return yawObject; 131 | }; 132 | 133 | this.getDirection = function(targetVec){ 134 | targetVec.set(0,0,-1); 135 | quat.multiplyVector3(targetVec); 136 | } 137 | 138 | // Moves the camera to the Cannon.js object position and adds velocity to the object if the run key is down 139 | var inputVelocity = new THREE.Vector3(); 140 | this.update = function ( delta ) { 141 | 142 | if ( scope.enabled === false ) return; 143 | 144 | delta *= 0.1; 145 | 146 | inputVelocity.set(0,0,0); 147 | 148 | if ( moveForward ){ 149 | inputVelocity.z = -velocityFactor * delta; 150 | } 151 | if ( moveBackward ){ 152 | inputVelocity.z = velocityFactor * delta; 153 | } 154 | 155 | if ( moveLeft ){ 156 | inputVelocity.x = -velocityFactor * delta; 157 | } 158 | if ( moveRight ){ 159 | inputVelocity.x = velocityFactor * delta; 160 | } 161 | 162 | // Convert velocity to world coordinates 163 | quat.setFromEuler({x:pitchObject.rotation.x, y:yawObject.rotation.y, z:0},"XYZ"); 164 | quat.multiplyVector3(inputVelocity); 165 | 166 | // Add to the object 167 | velocity.x += inputVelocity.x; 168 | velocity.z += inputVelocity.z; 169 | 170 | cannonBody.position.copy(yawObject.position); 171 | }; 172 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/examples/sunflower.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jeromeetienne/threex.cannonjs/ef51fa76a7dd3e7c28f7b4fca224d9b3a423ba46/vendor/cannon.js/examples/sunflower.jpg -------------------------------------------------------------------------------- /vendor/cannon.js/examples/threejs.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | three.js / cannon.js example 5 | 6 | 7 | 8 | 9 | 10 | 11 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /vendor/cannon.js/libs/Detector.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @author alteredq / http://alteredqualia.com/ 3 | * @author mr.doob / http://mrdoob.com/ 4 | */ 5 | 6 | Detector = { 7 | 8 | canvas: !! window.CanvasRenderingContext2D, 9 | webgl: ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )(), 10 | workers: !! window.Worker, 11 | fileapi: window.File && window.FileReader && window.FileList && window.Blob, 12 | 13 | getWebGLErrorMessage: function () { 14 | 15 | var element = document.createElement( 'div' ); 16 | element.id = 'webgl-error-message'; 17 | element.style.fontFamily = 'monospace'; 18 | element.style.fontSize = '13px'; 19 | element.style.fontWeight = 'normal'; 20 | element.style.textAlign = 'center'; 21 | element.style.background = '#fff'; 22 | element.style.color = '#000'; 23 | element.style.padding = '1.5em'; 24 | element.style.width = '400px'; 25 | element.style.margin = '5em auto 0'; 26 | 27 | if ( ! this.webgl ) { 28 | 29 | element.innerHTML = window.WebGLRenderingContext ? [ 30 | 'Your graphics card does not seem to support WebGL.
', 31 | 'Find out how to get it here.' 32 | ].join( '\n' ) : [ 33 | 'Your browser does not seem to support WebGL.
', 34 | 'Find out how to get it here.' 35 | ].join( '\n' ); 36 | 37 | } 38 | 39 | return element; 40 | 41 | }, 42 | 43 | addGetWebGLMessage: function ( parameters ) { 44 | 45 | var parent, id, element; 46 | 47 | parameters = parameters || {}; 48 | 49 | parent = parameters.parent !== undefined ? parameters.parent : document.body; 50 | id = parameters.id !== undefined ? parameters.id : 'oldie'; 51 | 52 | element = Detector.getWebGLErrorMessage(); 53 | element.id = id; 54 | 55 | parent.appendChild( element ); 56 | 57 | } 58 | 59 | }; 60 | -------------------------------------------------------------------------------- /vendor/cannon.js/libs/Stats.js: -------------------------------------------------------------------------------- 1 | // stats.js r8 - http://github.com/mrdoob/stats.js 2 | var Stats=function(){var h,a,n=0,o=0,i=Date.now(),u=i,p=i,l=0,q=1E3,r=0,e,j,f,b=[[16,16,48],[0,255,255]],m=0,s=1E3,t=0,d,k,g,c=[[16,48,16],[0,255,0]];h=document.createElement("div");h.style.cursor="pointer";h.style.width="80px";h.style.opacity="0.9";h.style.zIndex="10001";h.addEventListener("mousedown",function(a){a.preventDefault();n=(n+1)%2;n==0?(e.style.display="block",d.style.display="none"):(e.style.display="none",d.style.display="block")},!1);e=document.createElement("div");e.style.textAlign= 3 | "left";e.style.lineHeight="1.2em";e.style.backgroundColor="rgb("+Math.floor(b[0][0]/2)+","+Math.floor(b[0][1]/2)+","+Math.floor(b[0][2]/2)+")";e.style.padding="0 0 3px 3px";h.appendChild(e);j=document.createElement("div");j.style.fontFamily="Helvetica, Arial, sans-serif";j.style.fontSize="9px";j.style.color="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";j.style.fontWeight="bold";j.innerHTML="FPS";e.appendChild(j);f=document.createElement("div");f.style.position="relative";f.style.width="74px";f.style.height= 4 | "30px";f.style.backgroundColor="rgb("+b[1][0]+","+b[1][1]+","+b[1][2]+")";for(e.appendChild(f);f.children.length<74;)a=document.createElement("span"),a.style.width="1px",a.style.height="30px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+b[0][0]+","+b[0][1]+","+b[0][2]+")",f.appendChild(a);d=document.createElement("div");d.style.textAlign="left";d.style.lineHeight="1.2em";d.style.backgroundColor="rgb("+Math.floor(c[0][0]/2)+","+Math.floor(c[0][1]/2)+","+Math.floor(c[0][2]/2)+")";d.style.padding= 5 | "0 0 3px 3px";d.style.display="none";h.appendChild(d);k=document.createElement("div");k.style.fontFamily="Helvetica, Arial, sans-serif";k.style.fontSize="9px";k.style.color="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";k.style.fontWeight="bold";k.innerHTML="MS";d.appendChild(k);g=document.createElement("div");g.style.position="relative";g.style.width="74px";g.style.height="30px";g.style.backgroundColor="rgb("+c[1][0]+","+c[1][1]+","+c[1][2]+")";for(d.appendChild(g);g.children.length<74;)a=document.createElement("span"), 6 | a.style.width="1px",a.style.height=Math.random()*30+"px",a.style.cssFloat="left",a.style.backgroundColor="rgb("+c[0][0]+","+c[0][1]+","+c[0][2]+")",g.appendChild(a);return{domElement:h,update:function(){i=Date.now();m=i-u;s=Math.min(s,m);t=Math.max(t,m);k.textContent=m+" MS ("+s+"-"+t+")";var a=Math.min(30,30-m/200*30);g.appendChild(g.firstChild).style.height=a+"px";u=i;o++;if(i>p+1E3)l=Math.round(o*1E3/(i-p)),q=Math.min(q,l),r=Math.max(r,l),j.textContent=l+" FPS ("+q+"-"+r+")",a=Math.min(30,30-l/ 7 | 100*30),f.appendChild(f.firstChild).style.height=a+"px",p=i,o=0}}}; 8 | 9 | -------------------------------------------------------------------------------- /vendor/cannon.js/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cannon", 3 | "version": "0.5.0", 4 | "description": "A lightweight 3D physics engine written in JavaScript. Perfect to use with three.js, for example.", 5 | "homepage": "https://github.com/schteppe/cannon.js", 6 | "author": "Stefan Hedman (http://steffe.se)", 7 | "keywords": [ 8 | "cannon.js", 9 | "cannon", 10 | "physics", 11 | "engine", 12 | "3d" 13 | ], 14 | "main": "./build/cannon.js", 15 | "engines": { 16 | "node": "*" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/schteppe/cannon.js.git" 21 | }, 22 | "bugs": { 23 | "url": "https://github.com/schteppe/cannon.js/issues" 24 | }, 25 | "licenses" : [ 26 | { 27 | "type" : "MIT" 28 | } 29 | ], 30 | "devDependencies" : { 31 | "jshint" : "latest", 32 | "uglify-js" : "latest", 33 | "nodeunit" : "latest", 34 | "grunt": "~0.4.0", 35 | "grunt-contrib-jshint": "~0.1.1", 36 | "grunt-contrib-nodeunit": "~0.1.2", 37 | "grunt-contrib-concat": "~0.1.3", 38 | "grunt-contrib-uglify": "*" 39 | }, 40 | "dependencies" : { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/Cannon.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @page About 3 | * cannon.js is a lightweight 3D physics engine for web applications. For more information and source code, go to the Github repository [schteppe/cannon.js](https://github.com/schteppe/cannon.js). 4 | */ 5 | 6 | /** 7 | * @library cannon.js 8 | * @version 0.4.3 9 | * @brief A lightweight 3D physics engine for the web 10 | */ 11 | 12 | var CANNON = CANNON || {}; 13 | 14 | // Maintain compatibility with older browsers 15 | if(!this.Int32Array){ 16 | this.Int32Array=Array; 17 | this.Float32Array=Array; 18 | } -------------------------------------------------------------------------------- /vendor/cannon.js/src/collision/GridBroadphase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.GridBroadphase 3 | * @brief Axis aligned uniform grid broadphase. 4 | * @extends CANNON.Broadphase 5 | * @todo Needs support for more than just planes and spheres. 6 | * @param CANNON.Vec3 aabbMin 7 | * @param CANNON.Vec3 aabbMax 8 | * @param int nx Number of boxes along x 9 | * @param int ny Number of boxes along y 10 | * @param int nz Number of boxes along z 11 | */ 12 | CANNON.GridBroadphase = function(aabbMin,aabbMax,nx,ny,nz){ 13 | CANNON.Broadphase.apply(this); 14 | this.nx = nx || 10; 15 | this.ny = ny || 10; 16 | this.nz = nz || 10; 17 | this.aabbMin = aabbMin || new CANNON.Vec3(100,100,100); 18 | this.aabbMax = aabbMax || new CANNON.Vec3(-100,-100,-100); 19 | this.bins = []; 20 | }; 21 | CANNON.GridBroadphase.prototype = new CANNON.Broadphase(); 22 | CANNON.GridBroadphase.prototype.constructor = CANNON.GridBroadphase; 23 | 24 | /** 25 | * @method collisionPairs 26 | * @memberof CANNON.GridBroadphase 27 | * @brief Get all the collision pairs in the physics world 28 | * @param CANNON.World world 29 | * @param Array pairs1 30 | * @param Array pairs2 31 | */ 32 | var GridBroadphase_collisionPairs_d = new CANNON.Vec3(); 33 | var GridBroadphase_collisionPairs_binPos = new CANNON.Vec3(); 34 | CANNON.GridBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){ 35 | var N = world.numObjects(), 36 | bodies = world.bodies; 37 | 38 | var max = this.aabbMax, 39 | min = this.aabbMin, 40 | nx = this.nx, 41 | ny = this.ny, 42 | nz = this.nz; 43 | 44 | var xmax = max.x, 45 | ymax = max.y, 46 | zmax = max.z, 47 | xmin = min.x, 48 | ymin = min.y, 49 | zmin = min.z; 50 | 51 | var xmult = nx / (xmax-xmin), 52 | ymult = ny / (ymax-ymin), 53 | zmult = nz / (zmax-zmin); 54 | 55 | var binsizeX = (xmax - xmin) / nx, 56 | binsizeY = (ymax - ymin) / ny, 57 | binsizeZ = (zmax - zmin) / nz; 58 | 59 | var types = CANNON.Shape.types; 60 | var SPHERE = types.SPHERE, 61 | PLANE = types.PLANE, 62 | BOX = types.BOX, 63 | COMPOUND = types.COMPOUND, 64 | CONVEXPOLYHEDRON = types.CONVEXPOLYHEDRON; 65 | 66 | var bins=this.bins, 67 | Nbins=nx*ny*nz; 68 | 69 | // Reset bins 70 | for(var i=bins.length-1; i!==Nbins; i++){ 71 | bins.push([]); 72 | } 73 | for(var i=0; i!==Nbins; i++){ 74 | bins[i].length = 0; 75 | } 76 | 77 | var floor = Math.floor; 78 | 79 | // Put all bodies into the bins 80 | for(var i=0; i!==N; i++){ 81 | var bi = bodies[i]; 82 | var si = bi.shape; 83 | 84 | switch(si.type){ 85 | case SPHERE: 86 | // Put in bin 87 | // check if overlap with other bins 88 | var x = bi.position.x, 89 | y = bi.position.y, 90 | z = bi.position.z; 91 | var r = si.radius; 92 | 93 | var xi1 = floor(xmult * (x-r - xmin)), 94 | yi1 = floor(ymult * (y-r - ymin)), 95 | zi1 = floor(zmult * (z-r - zmin)), 96 | xi2 = floor(xmult * (x+r - xmin)), 97 | yi2 = floor(ymult * (y+r - ymin)), 98 | zi2 = floor(zmult * (z+r - zmin)); 99 | 100 | for(var j=xi1; j!==xi2+1; j++){ 101 | for(var k=yi1; k!==yi2+1; k++){ 102 | for(var l=zi1; l!==zi2+1; l++){ 103 | var xi = j, 104 | yi = k, 105 | zi = l; 106 | var idx = xi * ( ny - 1 ) * ( nz - 1 ) + yi * ( nz - 1 ) + zi; 107 | if(idx >= 0 && idx < Nbins){ 108 | bins[ idx ].push( bi ); 109 | } 110 | } 111 | } 112 | } 113 | break; 114 | 115 | case PLANE: 116 | // Put in all bins for now 117 | // @todo put only in bins that are actually intersecting the plane 118 | var d = GridBroadphase_collisionPairs_d; 119 | var binPos = GridBroadphase_collisionPairs_binPos; 120 | var binRadiusSquared = (binsizeX*binsizeX + binsizeY*binsizeY + binsizeZ*binsizeZ) * 0.25; 121 | 122 | var planeNormal = si.worldNormal; 123 | if(si.worldNormalNeedsUpdate){ 124 | si.computeWorldNormal(bi.quaternion); 125 | } 126 | 127 | for(var j=0; j!==nx; j++){ 128 | for(var k=0; k!==ny; k++){ 129 | for(var l=0; l!==nz; l++){ 130 | var xi = j, 131 | yi = k, 132 | zi = l; 133 | 134 | binPos.set(xi*binsizeX+xmin, yi*binsizeY+ymin, zi*binsizeZ+zmin); 135 | binPos.vsub(bi.position, d); 136 | 137 | if(d.dot(planeNormal) < binRadiusSquared){ 138 | var idx = xi * ( ny - 1 ) * ( nz - 1 ) + yi * ( nz - 1 ) + zi; 139 | bins[ idx ].push( bi ); 140 | } 141 | } 142 | } 143 | } 144 | break; 145 | 146 | default: 147 | console.warn("Shape "+si.type+" not supported in GridBroadphase!"); 148 | break; 149 | } 150 | } 151 | 152 | // Check each bin 153 | for(var i=0; i!==Nbins; i++){ 154 | var bin = bins[i]; 155 | 156 | // Do N^2 broadphase inside 157 | for(var j=0, NbodiesInBin=bin.length; j!==NbodiesInBin; j++){ 158 | var bi = bin[j]; 159 | 160 | for(var k=0; k!==j; k++){ 161 | var bj = bin[k]; 162 | if(this.needBroadphaseCollision(bi,bj)){ 163 | this.intersectionTest(bi,bj,pairs1,pairs2); 164 | } 165 | } 166 | } 167 | } 168 | 169 | this.makePairsUnique(pairs1,pairs2); 170 | }; 171 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/collision/NaiveBroadphase.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.NaiveBroadphase 3 | * @brief Naive broadphase implementation, used in lack of better ones. 4 | * @description The naive broadphase looks at all possible pairs without restriction, therefore it has complexity N^2 (which is bad) 5 | * @extends CANNON.Broadphase 6 | */ 7 | CANNON.NaiveBroadphase = function(){ 8 | CANNON.Broadphase.apply(this); 9 | }; 10 | CANNON.NaiveBroadphase.prototype = new CANNON.Broadphase(); 11 | CANNON.NaiveBroadphase.prototype.constructor = CANNON.NaiveBroadphase; 12 | 13 | /** 14 | * @method collisionPairs 15 | * @memberof CANNON.NaiveBroadphase 16 | * @brief Get all the collision pairs in the physics world 17 | * @param CANNON.World world 18 | * @param Array pairs1 19 | * @param Array pairs2 20 | */ 21 | CANNON.NaiveBroadphase.prototype.collisionPairs = function(world,pairs1,pairs2){ 22 | var bodies = world.bodies, 23 | n = bodies.length, 24 | i,j,bi,bj; 25 | 26 | // Naive N^2 ftw! 27 | for(i=0; i!==n; i++){ 28 | for(j=0; j!==i; j++){ 29 | 30 | bi = bodies[i]; 31 | bj = bodies[j]; 32 | 33 | if(!this.needBroadphaseCollision(bi,bj)){ 34 | continue; 35 | } 36 | 37 | this.intersectionTest(bi,bj,pairs1,pairs2); 38 | } 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/Constraint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Constraint 3 | * @brief Constraint base class 4 | * @author schteppe 5 | * @param CANNON.Body bodyA 6 | * @param CANNON.Body bodyB 7 | */ 8 | CANNON.Constraint = function(bodyA,bodyB){ 9 | 10 | /** 11 | * @property Array equations 12 | * @memberOf CANNON.Constraint 13 | * @brief Equations to be solved in this constraint 14 | */ 15 | this.equations = []; 16 | 17 | /** 18 | * @property CANNON.Body bodyA 19 | * @memberOf CANNON.Constraint 20 | */ 21 | this.bodyA = bodyA; 22 | 23 | /** 24 | * @property CANNON.Body bodyB 25 | * @memberOf CANNON.Constraint 26 | */ 27 | this.bodyB = bodyB; 28 | }; 29 | 30 | /** 31 | * @method update 32 | * @memberOf CANNON.Constraint 33 | */ 34 | CANNON.Constraint.prototype.update = function(){ 35 | throw new Error("method update() not implmemented in this Constraint subclass!"); 36 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/DistanceConstraint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.DistanceConstraint 3 | * @brief Constrains two bodies to be at a constant distance from each other. 4 | * @author schteppe 5 | * @param CANNON.Body bodyA 6 | * @param CANNON.Body bodyB 7 | * @param float distance 8 | * @param float maxForce 9 | */ 10 | CANNON.DistanceConstraint = function(bodyA,bodyB,distance,maxForce){ 11 | CANNON.Constraint.call(this,bodyA,bodyB); 12 | 13 | if(typeof(maxForce)==="undefined" ) { 14 | maxForce = 1e6; 15 | } 16 | 17 | // Equations to be fed to the solver 18 | var eqs = this.equations = [ 19 | new CANNON.ContactEquation(bodyA,bodyB), // Just in the normal direction 20 | ]; 21 | 22 | var normal = eqs[0]; 23 | 24 | normal.minForce = -maxForce; 25 | normal.maxForce = maxForce; 26 | 27 | // Update 28 | this.update = function(){ 29 | bodyB.position.vsub(bodyA.position,normal.ni); 30 | normal.ni.normalize(); 31 | /*bodyA.quaternion.vmult(pivotA,normal.ri); 32 | bodyB.quaternion.vmult(pivotB,normal.rj);*/ 33 | normal.ni.mult( distance*0.5,normal.ri); 34 | normal.ni.mult( -distance*0.5,normal.rj); 35 | }; 36 | }; 37 | CANNON.DistanceConstraint.prototype = new CANNON.Constraint(); 38 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/Equation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Equation 3 | * @brief Equation base class 4 | * @author schteppe 5 | * @param CANNON.Body bi 6 | * @param CANNON.Body bj 7 | * @param float minForce Minimum (read: negative max) force to be applied by the constraint. 8 | * @param float maxForce Maximum (read: positive max) force to be applied by the constraint. 9 | */ 10 | CANNON.Equation = function(bi,bj,minForce,maxForce){ 11 | this.id = -1; 12 | 13 | /** 14 | * @property float minForce 15 | * @memberof CANNON.Equation 16 | */ 17 | this.minForce = typeof(minForce)==="undefined" ? -1e6 : minForce; 18 | 19 | /** 20 | * @property float maxForce 21 | * @memberof CANNON.Equation 22 | */ 23 | this.maxForce = typeof(maxForce)==="undefined" ? 1e6 : maxForce; 24 | 25 | /** 26 | * @property CANNON.Body bi 27 | * @memberof CANNON.Equation 28 | */ 29 | this.bi = bi; 30 | 31 | /** 32 | * @property CANNON.Body bj 33 | * @memberof CANNON.Equation 34 | */ 35 | this.bj = bj; 36 | 37 | /** 38 | * @property float stiffness 39 | * @brief Corresponds to spring stiffness. Makes constraints stiffer, but harder to solve. 40 | * @memberof CANNON.Equation 41 | */ 42 | this.stiffness = 1e7; 43 | 44 | /** 45 | * @property float regularizationTime 46 | * @brief Similar to damping. Represents the number of timesteps needed to stabilize the constraint. 47 | * @memberof CANNON.Equation 48 | */ 49 | this.regularizationTime = 5; 50 | 51 | /** 52 | * @property float a 53 | * @brief SPOOK parameter 54 | * @memberof CANNON.Equation 55 | */ 56 | this.a = 0.0; 57 | 58 | /** 59 | * @property float b 60 | * @brief SPOOK parameter 61 | * @memberof CANNON.Equation 62 | */ 63 | this.b = 0.0; 64 | 65 | /** 66 | * @property float eps 67 | * @brief SPOOK parameter 68 | * @memberof CANNON.Equation 69 | */ 70 | this.eps = 0.0; 71 | 72 | /** 73 | * @property bool spookParamsNeedsUpdate 74 | * @brief Set to true if you just changed stiffness or regularization. The parameters a,b,eps will be recalculated by the solver before solve. 75 | * @memberof CANNON.Equation 76 | */ 77 | this.spookParamsNeedsUpdate = true; 78 | }; 79 | CANNON.Equation.prototype.constructor = CANNON.Equation; 80 | 81 | /** 82 | * @method updateSpookParams 83 | * @brief Recalculates a,b,eps. 84 | * @memberof CANNON.Equation 85 | */ 86 | CANNON.Equation.prototype.updateSpookParams = function(h){ 87 | var d = this.regularizationTime, 88 | k = this.stiffness; 89 | this.a = 4.0 / (h * (1 + 4 * d)); 90 | this.b = (4.0 * d) / (1 + 4 * d); 91 | this.eps = 4.0 / (h * h * k * (1 + 4 * d)); 92 | }; 93 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/HingeConstraint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.HingeConstraint 3 | * @brief Hinge constraint. Tries to keep the local body axes equal. 4 | * @author schteppe 5 | * @param CANNON.RigidBody bodyA 6 | * @param CANNON.Vec3 pivotA A point defined locally in bodyA. This defines the offset of axisA. 7 | * @param CANNON.Vec3 axisA an axis that bodyA can rotate around. 8 | * @param CANNON.RigidBody bodyB 9 | * @param CANNON.Vec3 pivotB 10 | * @param CANNON.Vec3 axisB 11 | * @param float maxForce 12 | */ 13 | CANNON.HingeConstraint = function(bodyA, pivotA, axisA, bodyB, pivotB, axisB, maxForce){ 14 | CANNON.Constraint.call(this,bodyA,bodyB); 15 | 16 | maxForce = maxForce || 1e6; 17 | var that = this; 18 | // Equations to be fed to the solver 19 | var eqs = this.equations = [ 20 | new CANNON.RotationalEquation(bodyA,bodyB), // rotational1 21 | new CANNON.RotationalEquation(bodyA,bodyB), // rotational2 22 | new CANNON.ContactEquation(bodyA,bodyB), // p2pNormal 23 | new CANNON.ContactEquation(bodyA,bodyB), // p2pTangent1 24 | new CANNON.ContactEquation(bodyA,bodyB), // p2pTangent2 25 | ]; 26 | 27 | this.getRotationalEquation1 = function(){ return eqs[0]; }; 28 | this.getRotationalEquation2 = function(){ return eqs[1]; }; 29 | this.getPointToPointEquation1 = function(){ return eqs[2]; }; 30 | this.getPointToPointEquation2 = function(){ return eqs[3]; }; 31 | this.getPointToPointEquation3 = function(){ return eqs[4]; }; 32 | 33 | var r1 = this.getRotationalEquation1(); 34 | var r2 = this.getRotationalEquation2(); 35 | var normal = this.getPointToPointEquation1(); 36 | var t1 = this.getPointToPointEquation2(); 37 | var t2 = this.getPointToPointEquation3(); 38 | var motor; // not activated by default 39 | 40 | t1.minForce = t2.minForce = normal.minForce = -maxForce; 41 | t1.maxForce = t2.maxForce = normal.maxForce = maxForce; 42 | 43 | var unitPivotA = pivotA.unit(); 44 | var unitPivotB = pivotB.unit(); 45 | 46 | var axisA_x_pivotA = new CANNON.Vec3(); 47 | var axisA_x_axisA_x_pivotA = new CANNON.Vec3(); 48 | var axisB_x_pivotB = new CANNON.Vec3(); 49 | axisA.cross(unitPivotA,axisA_x_pivotA); 50 | axisA.cross(axisA_x_pivotA,axisA_x_axisA_x_pivotA); 51 | axisB.cross(unitPivotB,axisB_x_pivotB); 52 | 53 | axisA_x_pivotA.normalize(); 54 | axisB_x_pivotB.normalize(); 55 | 56 | // Motor stuff 57 | var motorEnabled = false; 58 | this.motorTargetVelocity = 0; 59 | this.motorMinForce = -maxForce; 60 | this.motorMaxForce = maxForce; 61 | this.enableMotor = function(){ 62 | if(!motorEnabled){ 63 | motor = new CANNON.RotationalMotorEquation(bodyA,bodyB,maxForce); 64 | eqs.push(motor); 65 | motorEnabled = true; 66 | } 67 | }; 68 | this.disableMotor = function(){ 69 | if(motorEnabled){ 70 | motorEnabled = false; 71 | motor = null; 72 | eqs.pop(); 73 | } 74 | }; 75 | 76 | // Update 77 | this.update = function(){ 78 | // Update world positions of pivots 79 | /* 80 | bodyB.position.vsub(bodyA.position,normal.ni); 81 | normal.ni.normalize(); 82 | */ 83 | normal.ni.set(1,0,0); 84 | t1.ni.set(0,1,0); 85 | t2.ni.set(0,0,1); 86 | bodyA.quaternion.vmult(pivotA,normal.ri); 87 | bodyB.quaternion.vmult(pivotB,normal.rj); 88 | 89 | //normal.ni.tangents(t1.ni,t2.ni); 90 | normal.ri.copy(t1.ri); 91 | normal.rj.copy(t1.rj); 92 | normal.ri.copy(t2.ri); 93 | normal.rj.copy(t2.rj); 94 | 95 | // update rotational constraints 96 | bodyA.quaternion.vmult(axisA_x_pivotA, r1.ni); 97 | bodyB.quaternion.vmult(axisB, r1.nj); 98 | bodyA.quaternion.vmult(axisA_x_axisA_x_pivotA, r2.ni); 99 | bodyB.quaternion.vmult(axisB, r2.nj); 100 | 101 | if(motorEnabled){ 102 | bodyA.quaternion.vmult(axisA,motor.axisA); 103 | bodyB.quaternion.vmult(axisB,motor.axisB); 104 | motor.targetVelocity = that.motorTargetVelocity; 105 | motor.maxForce = that.motorMaxForce; 106 | motor.minForce = that.motorMinForce; 107 | } 108 | }; 109 | }; 110 | CANNON.HingeConstraint.prototype = new CANNON.Constraint(); -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/PointToPointConstraint.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.PointToPointConstraint 3 | * @brief Connects two bodies at given offset points 4 | * @author schteppe 5 | * @param CANNON.Body bodyA 6 | * @param CANNON.Vec3 pivotA The point relative to the center of mass of bodyA which bodyA is constrained to. 7 | * @param CANNON.Body bodyB Body that will be constrained in a similar way to the same point as bodyA. We will therefore get sort of a link between bodyA and bodyB. If not specified, bodyA will be constrained to a static point. 8 | * @param CANNON.Vec3 pivotB See pivotA. 9 | * @param float maxForce The maximum force that should be applied to constrain the bodies. 10 | * @extends CANNON.Constraint 11 | */ 12 | CANNON.PointToPointConstraint = function(bodyA,pivotA,bodyB,pivotB,maxForce){ 13 | CANNON.Constraint.call(this,bodyA,bodyB); 14 | 15 | // Equations to be fed to the solver 16 | var eqs = this.equations = [ 17 | new CANNON.ContactEquation(bodyA,bodyB), // Normal 18 | new CANNON.ContactEquation(bodyA,bodyB), // Tangent2 19 | new CANNON.ContactEquation(bodyA,bodyB), // Tangent2 20 | ]; 21 | 22 | var normal = eqs[0]; 23 | var t1 = eqs[1]; 24 | var t2 = eqs[2]; 25 | 26 | t1.minForce = t2.minForce = normal.minForce = -maxForce; 27 | t1.maxForce = t2.maxForce = normal.maxForce = maxForce; 28 | 29 | // Update 30 | this.update = function(){ 31 | bodyB.position.vsub(bodyA.position,normal.ni); 32 | normal.ni.normalize(); 33 | bodyA.quaternion.vmult(pivotA,normal.ri); 34 | bodyB.quaternion.vmult(pivotB,normal.rj); 35 | 36 | normal.ni.tangents(t1.ni,t2.ni); 37 | normal.ri.copy(t1.ri); 38 | normal.rj.copy(t1.rj); 39 | normal.ri.copy(t2.ri); 40 | normal.rj.copy(t2.rj); 41 | }; 42 | }; 43 | CANNON.PointToPointConstraint.prototype = new CANNON.Constraint(); 44 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/RotationalEquation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.RotationalEquation 3 | * @brief Rotational constraint. Works to keep the local vectors orthogonal to each other. 4 | * @author schteppe 5 | * @param CANNON.RigidBody bj 6 | * @param CANNON.Vec3 localVectorInBodyA 7 | * @param CANNON.RigidBody bi 8 | * @param CANNON.Vec3 localVectorInBodyB 9 | * @extends CANNON.Equation 10 | */ 11 | CANNON.RotationalEquation = function(bodyA, bodyB){ 12 | CANNON.Equation.call(this,bodyA,bodyB,-1e6,1e6); 13 | this.ni = new CANNON.Vec3(); // World oriented localVectorInBodyA 14 | this.nj = new CANNON.Vec3(); // ...and B 15 | 16 | this.nixnj = new CANNON.Vec3(); 17 | this.njxni = new CANNON.Vec3(); 18 | 19 | this.invIi = new CANNON.Mat3(); 20 | this.invIj = new CANNON.Mat3(); 21 | 22 | this.relVel = new CANNON.Vec3(); 23 | this.relForce = new CANNON.Vec3(); 24 | }; 25 | 26 | CANNON.RotationalEquation.prototype = new CANNON.Equation(); 27 | CANNON.RotationalEquation.prototype.constructor = CANNON.RotationalEquation; 28 | 29 | CANNON.RotationalEquation.prototype.computeB = function(h){ 30 | var a = this.a, 31 | b = this.b; 32 | var bi = this.bi; 33 | var bj = this.bj; 34 | 35 | var ni = this.ni; 36 | var nj = this.nj; 37 | 38 | var nixnj = this.nixnj; 39 | var njxni = this.njxni; 40 | 41 | var vi = bi.velocity; 42 | var wi = bi.angularVelocity ? bi.angularVelocity : new CANNON.Vec3(); 43 | var fi = bi.force; 44 | var taui = bi.tau ? bi.tau : new CANNON.Vec3(); 45 | 46 | var vj = bj.velocity; 47 | var wj = bj.angularVelocity ? bj.angularVelocity : new CANNON.Vec3(); 48 | var fj = bj.force; 49 | var tauj = bj.tau ? bj.tau : new CANNON.Vec3(); 50 | 51 | var invMassi = bi.invMass; 52 | var invMassj = bj.invMass; 53 | 54 | var invIi = this.invIi; 55 | var invIj = this.invIj; 56 | 57 | if(bi.invInertia){ 58 | invIi.setTrace(bi.invInertia); 59 | } else { 60 | invIi.identity(); // ok? 61 | } 62 | if(bj.invInertia) { 63 | invIj.setTrace(bj.invInertia); 64 | } else { 65 | invIj.identity(); // ok? 66 | } 67 | 68 | // Caluclate cross products 69 | ni.cross(nj,nixnj); 70 | nj.cross(ni,njxni); 71 | 72 | // g = ni * nj 73 | // gdot = (nj x ni) * wi + (ni x nj) * wj 74 | // G = [0 njxni 0 nixnj] 75 | // W = [vi wi vj wj] 76 | var Gq = -ni.dot(nj); 77 | var GW = njxni.dot(wi) + nixnj.dot(wj); 78 | var GiMf = 0;//njxni.dot(invIi.vmult(taui)) + nixnj.dot(invIj.vmult(tauj)); 79 | 80 | var B = - Gq * a - GW * b - h*GiMf; 81 | 82 | return B; 83 | }; 84 | 85 | // Compute C = GMG+eps 86 | CANNON.RotationalEquation.prototype.computeC = function(){ 87 | var bi = this.bi; 88 | var bj = this.bj; 89 | var nixnj = this.nixnj; 90 | var njxni = this.njxni; 91 | var invMassi = bi.invMass; 92 | var invMassj = bj.invMass; 93 | 94 | var C = /*invMassi + invMassj +*/ this.eps; 95 | 96 | var invIi = this.invIi; 97 | var invIj = this.invIj; 98 | 99 | if(bi.invInertia){ 100 | invIi.setTrace(bi.invInertia); 101 | } else { 102 | invIi.identity(); // ok? 103 | } 104 | if(bj.invInertia){ 105 | invIj.setTrace(bj.invInertia); 106 | } else { 107 | invIj.identity(); // ok? 108 | } 109 | 110 | C += invIi.vmult(njxni).dot(njxni); 111 | C += invIj.vmult(nixnj).dot(nixnj); 112 | 113 | return C; 114 | }; 115 | 116 | var computeGWlambda_ulambda = new CANNON.Vec3(); 117 | CANNON.RotationalEquation.prototype.computeGWlambda = function(){ 118 | var bi = this.bi; 119 | var bj = this.bj; 120 | var ulambda = computeGWlambda_ulambda; 121 | 122 | var GWlambda = 0.0; 123 | //bj.vlambda.vsub(bi.vlambda, ulambda); 124 | //GWlambda += ulambda.dot(this.ni); 125 | 126 | // Angular 127 | if(bi.wlambda){ 128 | GWlambda += bi.wlambda.dot(this.njxni); 129 | } 130 | if(bj.wlambda){ 131 | GWlambda += bj.wlambda.dot(this.nixnj); 132 | } 133 | 134 | //console.log("GWlambda:",GWlambda); 135 | 136 | return GWlambda; 137 | }; 138 | 139 | CANNON.RotationalEquation.prototype.addToWlambda = function(deltalambda){ 140 | var bi = this.bi; 141 | var bj = this.bj; 142 | var nixnj = this.nixnj; 143 | var njxni = this.njxni; 144 | var invMassi = bi.invMass; 145 | var invMassj = bj.invMass; 146 | 147 | // Add to linear velocity 148 | //bi.vlambda.vsub(n.mult(invMassi * deltalambda),bi.vlambda); 149 | //bj.vlambda.vadd(n.mult(invMassj * deltalambda),bj.vlambda); 150 | 151 | // Add to angular velocity 152 | if(bi.wlambda){ 153 | var I = this.invIi; 154 | bi.wlambda.vsub(I.vmult(nixnj).mult(deltalambda),bi.wlambda); 155 | } 156 | if(bj.wlambda){ 157 | var I = this.invIj; 158 | bj.wlambda.vadd(I.vmult(nixnj).mult(deltalambda),bj.wlambda); 159 | } 160 | }; 161 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/constraints/RotationalMotorEquation.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.RotationalMotorEquation 3 | * @brief Rotational motor constraint. Works to keep the relative angular velocity of the bodies to a given value 4 | * @author schteppe 5 | * @param CANNON.RigidBody bodyA 6 | * @param CANNON.RigidBody bodyB 7 | * @extends CANNON.Equation 8 | */ 9 | CANNON.RotationalMotorEquation = function(bodyA, bodyB, maxForce){ 10 | maxForce = maxForce || 1e6; 11 | CANNON.Equation.call(this,bodyA,bodyB,-maxForce,maxForce); 12 | this.axisA = new CANNON.Vec3(); // World oriented rotational axis 13 | this.axisB = new CANNON.Vec3(); // World oriented rotational axis 14 | 15 | this.invIi = new CANNON.Mat3(); 16 | this.invIj = new CANNON.Mat3(); 17 | this.targetVelocity = 0; 18 | }; 19 | 20 | CANNON.RotationalMotorEquation.prototype = new CANNON.Equation(); 21 | CANNON.RotationalMotorEquation.prototype.constructor = CANNON.RotationalMotorEquation; 22 | 23 | CANNON.RotationalMotorEquation.prototype.computeB = function(h){ 24 | var a = this.a, 25 | b = this.b; 26 | var bi = this.bi; 27 | var bj = this.bj; 28 | 29 | var axisA = this.axisA; 30 | var axisB = this.axisB; 31 | 32 | var vi = bi.velocity; 33 | var wi = bi.angularVelocity ? bi.angularVelocity : new CANNON.Vec3(); 34 | var fi = bi.force; 35 | var taui = bi.tau ? bi.tau : new CANNON.Vec3(); 36 | 37 | var vj = bj.velocity; 38 | var wj = bj.angularVelocity ? bj.angularVelocity : new CANNON.Vec3(); 39 | var fj = bj.force; 40 | var tauj = bj.tau ? bj.tau : new CANNON.Vec3(); 41 | 42 | var invMassi = bi.invMass; 43 | var invMassj = bj.invMass; 44 | 45 | var invIi = this.invIi; 46 | var invIj = this.invIj; 47 | 48 | if(bi.invInertia){ 49 | invIi.setTrace(bi.invInertia); 50 | } else { 51 | invIi.identity(); // ok? 52 | } 53 | if(bj.invInertia){ 54 | invIj.setTrace(bj.invInertia); 55 | } else { 56 | invIj.identity(); // ok? 57 | } 58 | 59 | // g = 0 60 | // gdot = axisA * wi - axisB * wj 61 | // G = [0 axisA 0 -axisB] 62 | // W = [vi wi vj wj] 63 | var Gq = 0; 64 | var GW = axisA.dot(wi) + axisB.dot(wj) + this.targetVelocity; 65 | var GiMf = 0;//axis.dot(invIi.vmult(taui)) + axis.dot(invIj.vmult(tauj)); 66 | 67 | var B = - Gq * a - GW * b - h*GiMf; 68 | 69 | return B; 70 | }; 71 | 72 | // Compute C = GMG+eps 73 | CANNON.RotationalMotorEquation.prototype.computeC = function(){ 74 | var bi = this.bi; 75 | var bj = this.bj; 76 | var axisA = this.axisA; 77 | var axisB = this.axisB; 78 | var invMassi = bi.invMass; 79 | var invMassj = bj.invMass; 80 | 81 | var C = this.eps; 82 | 83 | var invIi = this.invIi; 84 | var invIj = this.invIj; 85 | 86 | if(bi.invInertia){ 87 | invIi.setTrace(bi.invInertia); 88 | } else { 89 | invIi.identity(); // ok? 90 | } 91 | if(bj.invInertia){ 92 | invIj.setTrace(bj.invInertia); 93 | } else { 94 | invIj.identity(); // ok? 95 | } 96 | 97 | C += invIi.vmult(axisA).dot(axisB); 98 | C += invIj.vmult(axisB).dot(axisB); 99 | 100 | return C; 101 | }; 102 | 103 | var computeGWlambda_ulambda = new CANNON.Vec3(); 104 | CANNON.RotationalMotorEquation.prototype.computeGWlambda = function(){ 105 | var bi = this.bi; 106 | var bj = this.bj; 107 | var ulambda = computeGWlambda_ulambda; 108 | var axisA = this.axisA; 109 | var axisB = this.axisB; 110 | 111 | var GWlambda = 0.0; 112 | //bj.vlambda.vsub(bi.vlambda, ulambda); 113 | //GWlambda += ulambda.dot(this.ni); 114 | 115 | // Angular 116 | if(bi.wlambda){ 117 | GWlambda += bi.wlambda.dot(axisA); 118 | } 119 | if(bj.wlambda){ 120 | GWlambda += bj.wlambda.dot(axisB); 121 | } 122 | 123 | //console.log("GWlambda:",GWlambda); 124 | 125 | return GWlambda; 126 | }; 127 | 128 | CANNON.RotationalMotorEquation.prototype.addToWlambda = function(deltalambda){ 129 | var bi = this.bi; 130 | var bj = this.bj; 131 | var axisA = this.axisA; 132 | var axisB = this.axisB; 133 | var invMassi = bi.invMass; 134 | var invMassj = bj.invMass; 135 | 136 | // Add to linear velocity 137 | //bi.vlambda.vsub(n.mult(invMassi * deltalambda),bi.vlambda); 138 | //bj.vlambda.vadd(n.mult(invMassj * deltalambda),bj.vlambda); 139 | 140 | // Add to angular velocity 141 | if(bi.wlambda){ 142 | var I = this.invIi; 143 | bi.wlambda.vsub(I.vmult(axisA).mult(deltalambda),bi.wlambda); 144 | } 145 | if(bj.wlambda){ 146 | var I = this.invIj; 147 | bj.wlambda.vadd(I.vmult(axisB).mult(deltalambda),bj.wlambda); 148 | } 149 | }; 150 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/material/ContactMaterial.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.ContactMaterial 3 | * @brief Defines what happens when two materials meet. 4 | * @param CANNON.Material m1 5 | * @param CANNON.Material m2 6 | * @param float friction 7 | * @param float restitution 8 | * @todo Contact solving parameters here too? 9 | */ 10 | CANNON.ContactMaterial = function(m1, m2, friction, restitution){ 11 | 12 | /// Contact material index in the world, -1 until added to the world 13 | this.id = -1; 14 | 15 | /// The two materials participating in the contact 16 | this.materials = [m1,m2]; 17 | 18 | /// Kinetic friction 19 | this.friction = friction!==undefined ? Number(friction) : 0.3; 20 | 21 | /// Restitution 22 | this.restitution = restitution !== undefined ? Number(restitution) : 0.3; 23 | 24 | // Parameters to pass to the constraint when it is created 25 | this.contactEquationStiffness = 1e7; 26 | this.contactEquationRegularizationTime = 3; 27 | this.frictionEquationStiffness = 1e7; 28 | this.frictionEquationRegularizationTime = 3; 29 | }; 30 | 31 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/material/Material.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Material 3 | * @brief Defines a physics material. 4 | * @param string name 5 | * @author schteppe 6 | */ 7 | CANNON.Material = function(name){ 8 | /** 9 | * @property string name 10 | * @memberof CANNON.Material 11 | */ 12 | this.name = name; 13 | this.id = -1; 14 | }; 15 | 16 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/math/MatN.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.MatN 3 | * @brief Any matrix size class 4 | * @author schteppe 5 | * @param int cols 6 | * @param int rows 7 | * @param array elements 8 | */ 9 | CANNON.MatN = function(cols,rows,elements){ 10 | /** 11 | * @property Float32Array elements 12 | * @memberof CANNON.MatN 13 | * @brief A vector containing all matrix elements 14 | */ 15 | if(elements){ 16 | this.elements = new Float32Array(elements); 17 | } else { 18 | this.elements = new Float32Array(cols*rows); 19 | } 20 | }; 21 | 22 | /** 23 | * @method identity 24 | * @memberof CANNON.MatN 25 | * @brief Sets the matrix to identity 26 | * @todo Should perhaps be renamed to setIdentity() to be more clear. 27 | * @todo Create another function that immediately creates an identity matrix eg. eye() 28 | */ 29 | CANNON.MatN.prototype.identity = function(){ 30 | for(var i=0; i max.x){ 128 | max.x = aabbmaxTemp.x; 129 | } 130 | if(aabbmaxTemp.y > max.y){ 131 | max.y = aabbmaxTemp.y; 132 | } 133 | if(aabbmaxTemp.z > max.z){ 134 | max.z = aabbmaxTemp.z; 135 | } 136 | } 137 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/src/objects/Cylinder.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Cylinder 3 | * @extends CANNON.ConvexPolyhedron 4 | * @author schteppe / https://github.com/schteppe 5 | * @param float radiusTop 6 | * @param float radiusBottom 7 | * @param float height 8 | * @param int numSegments The number of segments to build the cylinder out of 9 | */ 10 | CANNON.Cylinder = function( radiusTop, radiusBottom, height , numSegments ) { 11 | var N = numSegments, 12 | verts = [], 13 | normals = [], 14 | faces = [], 15 | bottomface = [], 16 | topface = [], 17 | cos = Math.cos, 18 | sin = Math.sin; 19 | 20 | // First bottom point 21 | verts.push(new CANNON.Vec3(radiusBottom*cos(0), 22 | radiusBottom*sin(0), 23 | -height*0.5)); 24 | bottomface.push(0); 25 | 26 | // First top point 27 | verts.push(new CANNON.Vec3(radiusTop*cos(0), 28 | radiusTop*sin(0), 29 | height*0.5)); 30 | topface.push(1); 31 | 32 | for(var i=0; i0 ? 1.0/mass : 0; 62 | 63 | /** 64 | * @property CANNON.Material material 65 | * @memberof CANNON.Particle 66 | */ 67 | this.material = material; 68 | 69 | /** 70 | * @property float linearDamping 71 | * @memberof CANNON.Particle 72 | */ 73 | this.linearDamping = 0.01; // Perhaps default should be zero here? 74 | 75 | /** 76 | * @property int motionstate 77 | * @memberof CANNON.Particle 78 | * @brief One of the states CANNON.Body.DYNAMIC, CANNON.Body.STATIC and CANNON.Body.KINEMATIC 79 | */ 80 | this.motionstate = (mass <= 0.0 ? CANNON.Body.STATIC : CANNON.Body.DYNAMIC); 81 | 82 | /** 83 | * @property bool allowSleep 84 | * @memberof CANNON.Particle 85 | * @brief If true, the body will automatically fall to sleep. 86 | */ 87 | this.allowSleep = true; 88 | 89 | // 0:awake, 1:sleepy, 2:sleeping 90 | this.sleepState = 0; 91 | 92 | /** 93 | * @property float sleepSpeedLimit 94 | * @memberof CANNON.Particle 95 | * @brief If the speed (the norm of the velocity) is smaller than this value, the body is considered sleepy. 96 | */ 97 | this.sleepSpeedLimit = 0.1; 98 | 99 | /** 100 | * @property float sleepTimeLimit 101 | * @memberof CANNON.Particle 102 | * @brief If the body has been sleepy for this sleepTimeLimit seconds, it is considered sleeping. 103 | */ 104 | this.sleepTimeLimit = 1; 105 | 106 | this.timeLastSleepy = 0; 107 | 108 | }; 109 | 110 | CANNON.Particle.prototype = new CANNON.Body(); 111 | CANNON.Particle.prototype.constructor = CANNON.Particle; 112 | 113 | /** 114 | * @method isAwake 115 | * @memberof CANNON.Particle 116 | * @return bool 117 | */ 118 | CANNON.Particle.prototype.isAwake = function(){ 119 | return this.sleepState === 0; 120 | }; 121 | 122 | /** 123 | * @method isSleepy 124 | * @memberof CANNON.Particle 125 | * @return bool 126 | */ 127 | CANNON.Particle.prototype.isSleepy = function(){ 128 | return this.sleepState === 1; 129 | }; 130 | 131 | /** 132 | * @method isSleeping 133 | * @memberof CANNON.Particle 134 | * @return bool 135 | */ 136 | CANNON.Particle.prototype.isSleeping = function(){ 137 | return this.sleepState === 2; 138 | }; 139 | 140 | /** 141 | * @method wakeUp 142 | * @memberof CANNON.Particle 143 | * @brief Wake the body up. 144 | */ 145 | CANNON.Particle.prototype.wakeUp = function(){ 146 | var s = this.sleepState; 147 | this.sleepState = 0; 148 | if(s === 2){ 149 | this.dispatchEvent({type:"wakeup"}); 150 | } 151 | }; 152 | 153 | /** 154 | * @method sleep 155 | * @memberof CANNON.Particle 156 | * @brief Force body sleep 157 | */ 158 | CANNON.Particle.prototype.sleep = function(){ 159 | this.sleepState = 2; 160 | }; 161 | 162 | /** 163 | * @method sleepTick 164 | * @memberof CANNON.Particle 165 | * @param float time The world time in seconds 166 | * @brief Called every timestep to update internal sleep timer and change sleep state if needed. 167 | */ 168 | CANNON.Particle.prototype.sleepTick = function(time){ 169 | if(this.allowSleep){ 170 | var sleepState = this.sleepState; 171 | var speedSquared = this.velocity.norm2(); 172 | var speedLimitSquared = Math.pow(this.sleepSpeedLimit,2); 173 | if(sleepState===0 && speedSquared < speedLimitSquared){ 174 | this.sleepState = 1; // Sleepy 175 | this.timeLastSleepy = time; 176 | this.dispatchEvent({type:"sleepy"}); 177 | } else if(sleepState===1 && speedSquared > speedLimitSquared){ 178 | this.wakeUp(); // Wake up 179 | } else if(sleepState===1 && (time - this.timeLastSleepy ) > this.sleepTimeLimit){ 180 | this.sleepState = 2; // Sleeping 181 | this.dispatchEvent({type:"sleep"}); 182 | } 183 | } 184 | }; 185 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/objects/Plane.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Plane 3 | * @extends CANNON.Shape 4 | * @param CANNON.Vec3 normal 5 | * @brief A plane, facing in the Z direction. 6 | * @description A plane, facing in the Z direction. The plane has its surface at z=0 and everything below z=0 is assumed to be solid plane. To make the plane face in some other direction than z, you must put it inside a RigidBody and rotate that body. See the demos. 7 | * @author schteppe 8 | */ 9 | CANNON.Plane = function(){ 10 | CANNON.Shape.call(this); 11 | this.type = CANNON.Shape.types.PLANE; 12 | 13 | // World oriented normal 14 | this.worldNormal = new CANNON.Vec3(); 15 | this.worldNormalNeedsUpdate = true; 16 | }; 17 | CANNON.Plane.prototype = new CANNON.Shape(); 18 | CANNON.Plane.prototype.constructor = CANNON.Plane; 19 | 20 | CANNON.Plane.prototype.computeWorldNormal = function(quat){ 21 | var n = this.worldNormal; 22 | n.set(0,0,1); 23 | quat.vmult(n,n); 24 | this.worldNormalNeedsUpdate = false; 25 | }; 26 | 27 | CANNON.Plane.prototype.calculateLocalInertia = function(mass,target){ 28 | target = target || new CANNON.Vec3(); 29 | return target; 30 | }; 31 | 32 | CANNON.Plane.prototype.volume = function(){ 33 | return Infinity; // The plane is infinite... 34 | }; 35 | 36 | var tempNormal = new CANNON.Vec3(); 37 | CANNON.Plane.prototype.calculateWorldAABB = function(pos,quat,min,max){ 38 | // The plane AABB is infinite, except if the normal is pointing along any axis 39 | tempNormal.set(0,0,1); // Default plane normal is z 40 | quat.vmult(tempNormal,tempNormal); 41 | min.set(-Infinity,-Infinity,-Infinity); 42 | max.set(Infinity,Infinity,Infinity); 43 | 44 | if(tempNormal.x === 1){ max.x = pos.x; } 45 | if(tempNormal.y === 1){ max.y = pos.y; } 46 | if(tempNormal.z === 1){ max.z = pos.z; } 47 | 48 | if(tempNormal.x === -1){ min.x = pos.x; } 49 | if(tempNormal.y === -1){ min.y = pos.y; } 50 | if(tempNormal.z === -1){ min.z = pos.z; } 51 | 52 | }; 53 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/objects/RigidBody.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.RigidBody 3 | * @brief Rigid body base class 4 | * @param float mass 5 | * @param CANNON.Shape shape 6 | * @param CANNON.Material material 7 | */ 8 | CANNON.RigidBody = function(mass,shape,material){ 9 | 10 | // Check input 11 | if(typeof(mass)!=="number"){ 12 | throw new Error("Argument 1 (mass) must be a number."); 13 | } 14 | if(typeof(material)!=="undefined" && !(material instanceof(CANNON.Material))){ 15 | throw new Error("Argument 3 (material) must be an instance of CANNON.Material."); 16 | } 17 | 18 | CANNON.Particle.call(this,mass,material); 19 | 20 | var that = this; 21 | 22 | /** 23 | * @property CANNON.Vec3 tau 24 | * @memberof CANNON.RigidBody 25 | * @brief Rotational force on the body, around center of mass 26 | */ 27 | this.tau = new CANNON.Vec3(); 28 | 29 | /** 30 | * @property CANNON.Quaternion quaternion 31 | * @memberof CANNON.RigidBody 32 | * @brief Orientation of the body 33 | */ 34 | this.quaternion = new CANNON.Quaternion(); 35 | 36 | /** 37 | * @property CANNON.Quaternion initQuaternion 38 | * @memberof CANNON.RigidBody 39 | */ 40 | this.initQuaternion = new CANNON.Quaternion(); 41 | 42 | /** 43 | * @property CANNON.Vec3 angularVelocity 44 | * @memberof CANNON.RigidBody 45 | */ 46 | this.angularVelocity = new CANNON.Vec3(); 47 | 48 | /** 49 | * @property CANNON.Vec3 initAngularVelocity 50 | * @memberof CANNON.RigidBody 51 | */ 52 | this.initAngularVelocity = new CANNON.Vec3(); 53 | 54 | /** 55 | * @property CANNON.Shape shape 56 | * @memberof CANNON.RigidBody 57 | */ 58 | this.shape = shape; 59 | 60 | /** 61 | * @property CANNON.Vec3 inertia 62 | * @memberof CANNON.RigidBody 63 | */ 64 | this.inertia = new CANNON.Vec3(); 65 | shape.calculateLocalInertia(mass,this.inertia); 66 | 67 | this.inertiaWorld = new CANNON.Vec3(); 68 | this.inertia.copy(this.inertiaWorld); 69 | this.inertiaWorldAutoUpdate = false; 70 | 71 | /** 72 | * @property CANNON.Vec3 intInertia 73 | * @memberof CANNON.RigidBody 74 | */ 75 | this.invInertia = new CANNON.Vec3(this.inertia.x>0 ? 1.0/this.inertia.x : 0, 76 | this.inertia.y>0 ? 1.0/this.inertia.y : 0, 77 | this.inertia.z>0 ? 1.0/this.inertia.z : 0); 78 | this.invInertiaWorld = new CANNON.Vec3(); 79 | this.invInertia.copy(this.invInertiaWorld); 80 | this.invInertiaWorldAutoUpdate = false; 81 | 82 | /** 83 | * @property float angularDamping 84 | * @memberof CANNON.RigidBody 85 | */ 86 | this.angularDamping = 0.01; // Perhaps default should be zero here? 87 | 88 | /** 89 | * @property CANNON.Vec3 aabbmin 90 | * @memberof CANNON.RigidBody 91 | */ 92 | this.aabbmin = new CANNON.Vec3(); 93 | 94 | /** 95 | * @property CANNON.Vec3 aabbmax 96 | * @memberof CANNON.RigidBody 97 | */ 98 | this.aabbmax = new CANNON.Vec3(); 99 | 100 | /** 101 | * @property bool aabbNeedsUpdate 102 | * @memberof CANNON.RigidBody 103 | * @brief Indicates if the AABB needs to be updated before use. 104 | */ 105 | this.aabbNeedsUpdate = true; 106 | 107 | this.wlambda = new CANNON.Vec3(); 108 | }; 109 | 110 | CANNON.RigidBody.prototype = new CANNON.Particle(0); 111 | CANNON.RigidBody.prototype.constructor = CANNON.RigidBody; 112 | 113 | CANNON.RigidBody.prototype.computeAABB = function(){ 114 | this.shape.calculateWorldAABB(this.position, 115 | this.quaternion, 116 | this.aabbmin, 117 | this.aabbmax); 118 | this.aabbNeedsUpdate = false; 119 | }; 120 | 121 | /** 122 | * Apply force to a world point. This could for example be a point on the RigidBody surface. Applying force this way will add to Body.force and Body.tau. 123 | * @param CANNON.Vec3 force The amount of force to add. 124 | * @param CANNON.Vec3 worldPoint A world point to apply the force on. 125 | */ 126 | var RigidBody_applyForce_r = new CANNON.Vec3(); 127 | var RigidBody_applyForce_rotForce = new CANNON.Vec3(); 128 | CANNON.RigidBody.prototype.applyForce = function(force,worldPoint){ 129 | // Compute point position relative to the body center 130 | var r = RigidBody_applyForce_r; 131 | worldPoint.vsub(this.position,r); 132 | 133 | // Compute produced rotational force 134 | var rotForce = RigidBody_applyForce_rotForce; 135 | r.cross(force,rotForce); 136 | 137 | // Add linear force 138 | this.force.vadd(force,this.force); 139 | 140 | // Add rotational force 141 | this.tau.vadd(rotForce,this.tau); 142 | }; 143 | 144 | /** 145 | * Apply impulse to a world point. This could for example be a point on the RigidBody surface. An impulse is a force added to a body during a short period of time (impulse = force * time). Impulses will be added to Body.velocity and Body.angularVelocity. 146 | * @param CANNON.Vec3 impulse The amount of impulse to add. 147 | * @param CANNON.Vec3 worldPoint A world point to apply the force on. 148 | */ 149 | var RigidBody_applyImpulse_r = new CANNON.Vec3(); 150 | var RigidBody_applyImpulse_velo = new CANNON.Vec3(); 151 | var RigidBody_applyImpulse_rotVelo = new CANNON.Vec3(); 152 | CANNON.RigidBody.prototype.applyImpulse = function(impulse,worldPoint){ 153 | // Compute point position relative to the body center 154 | var r = RigidBody_applyImpulse_r; 155 | worldPoint.vsub(this.position,r); 156 | 157 | // Compute produced central impulse velocity 158 | var velo = RigidBody_applyImpulse_velo; 159 | impulse.copy(velo); 160 | velo.mult(this.invMass,velo); 161 | 162 | // Add linear impulse 163 | this.velocity.vadd(velo, this.velocity); 164 | 165 | // Compute produced rotational impulse velocity 166 | var rotVelo = RigidBody_applyImpulse_rotVelo; 167 | r.cross(impulse,rotVelo); 168 | rotVelo.x *= this.invInertia.x; 169 | rotVelo.y *= this.invInertia.y; 170 | rotVelo.z *= this.invInertia.z; 171 | 172 | // Add rotational Impulse 173 | this.angularVelocity.vadd(rotVelo, this.angularVelocity); 174 | }; 175 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/objects/Shape.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Shape 3 | * @author schteppe 4 | * @brief Base class for shapes 5 | * @todo Should have a mechanism for caching bounding sphere radius instead of calculating it each time 6 | */ 7 | CANNON.Shape = function(){ 8 | 9 | /** 10 | * @property int type 11 | * @memberof CANNON.Shape 12 | * @brief The type of this shape. Must be set to an int > 0 by subclasses. 13 | * @see CANNON.Shape.types 14 | */ 15 | this.type = 0; 16 | 17 | this.aabbmin = new CANNON.Vec3(); 18 | this.aabbmax = new CANNON.Vec3(); 19 | 20 | this.boundingSphereRadius = 0; 21 | this.boundingSphereRadiusNeedsUpdate = true; 22 | }; 23 | CANNON.Shape.prototype.constructor = CANNON.Shape; 24 | 25 | /** 26 | * @method computeBoundingSphereRadius 27 | * @memberof CANNON.Shape 28 | * @brief Computes the bounding sphere radius. The result is stored in the property .boundingSphereRadius 29 | * @return float 30 | */ 31 | CANNON.Shape.prototype.computeBoundingSphereRadius = function(){ 32 | throw "computeBoundingSphereRadius() not implemented for shape type "+this.type; 33 | }; 34 | 35 | /** 36 | * @method getBoundingSphereRadius 37 | * @memberof CANNON.Shape 38 | * @brief Returns the bounding sphere radius. The result is stored in the property .boundingSphereRadius 39 | * @return float 40 | */ 41 | CANNON.Shape.prototype.getBoundingSphereRadius = function(){ 42 | if (this.boundingSphereRadiusNeedsUpdate) { 43 | this.computeBoundingSphereRadius(); 44 | } 45 | return this.boundingSphereRadius; 46 | }; 47 | 48 | /** 49 | * @method volume 50 | * @memberof CANNON.Shape 51 | * @brief Get the volume of this shape 52 | * @return float 53 | */ 54 | CANNON.Shape.prototype.volume = function(){ 55 | throw "volume() not implemented for shape type "+this.type; 56 | }; 57 | 58 | /** 59 | * @method calculateLocalInertia 60 | * @memberof CANNON.Shape 61 | * @brief Calculates the inertia in the local frame for this shape. 62 | * @return CANNON.Vec3 63 | * @see http://en.wikipedia.org/wiki/List_of_moments_of_inertia 64 | */ 65 | CANNON.Shape.prototype.calculateLocalInertia = function(mass,target){ 66 | throw "calculateLocalInertia() not implemented for shape type "+this.type; 67 | }; 68 | 69 | /** 70 | * @method calculateTransformedInertia 71 | * @memberof CANNON.Shape 72 | * @brief Calculates inertia in a specified frame for this shape. 73 | * @return CANNON.Vec3 74 | */ 75 | var Shape_calculateTransformedInertia_localInertia = new CANNON.Vec3(); 76 | var Shape_calculateTransformedInertia_worldInertia = new CANNON.Vec3(); 77 | CANNON.Shape.prototype.calculateTransformedInertia = function(mass,quat,target){ 78 | target = target || new CANNON.Vec3(); 79 | 80 | // Compute inertia in the world frame 81 | //quat.normalize(); 82 | var localInertia = Shape_calculateTransformedInertia_localInertia; 83 | var worldInertia = Shape_calculateTransformedInertia_worldInertia; 84 | this.calculateLocalInertia(mass,localInertia); 85 | 86 | // @todo Is this rotation OK? Check! 87 | quat.vmult(localInertia,worldInertia); 88 | target.x = Math.abs(worldInertia.x); 89 | target.y = Math.abs(worldInertia.y); 90 | target.z = Math.abs(worldInertia.z); 91 | return target; 92 | }; 93 | 94 | // Calculates the local aabb and sets the result to .aabbmax and .aabbmin 95 | CANNON.Shape.calculateLocalAABB = function(){ 96 | throw new Error(".calculateLocalAABB is not implemented for this Shape yet!"); 97 | }; 98 | 99 | /** 100 | * @property Object types 101 | * @memberof CANNON.Shape 102 | * @brief The available shape types. 103 | */ 104 | CANNON.Shape.types = { 105 | SPHERE:1, 106 | PLANE:2, 107 | BOX:4, 108 | COMPOUND:8, 109 | CONVEXPOLYHEDRON:16 110 | }; 111 | 112 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/objects/Sphere.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @brief Spherical rigid body 3 | * @class CANNON.Sphere 4 | * @extends CANNON.Shape 5 | * @param float radius 6 | * @author schteppe / http://github.com/schteppe 7 | */ 8 | CANNON.Sphere = function(radius){ 9 | CANNON.Shape.call(this); 10 | 11 | /** 12 | * @property float radius 13 | * @memberof CANNON.Sphere 14 | */ 15 | this.radius = radius!==undefined ? Number(radius) : 1.0; 16 | this.type = CANNON.Shape.types.SPHERE; 17 | }; 18 | CANNON.Sphere.prototype = new CANNON.Shape(); 19 | CANNON.Sphere.prototype.constructor = CANNON.Sphere; 20 | 21 | CANNON.Sphere.prototype.calculateLocalInertia = function(mass,target){ 22 | target = target || new CANNON.Vec3(); 23 | var I = 2.0*mass*this.radius*this.radius/5.0; 24 | target.x = I; 25 | target.y = I; 26 | target.z = I; 27 | return target; 28 | }; 29 | 30 | CANNON.Sphere.prototype.volume = function(){ 31 | return 4.0 * Math.PI * this.radius / 3.0; 32 | }; 33 | 34 | CANNON.Sphere.prototype.computeBoundingSphereRadius = function(){ 35 | this.boundingSphereRadiusNeedsUpdate = false; 36 | this.boundingSphereRadius = this.radius; 37 | }; 38 | 39 | CANNON.Sphere.prototype.calculateWorldAABB = function(pos,quat,min,max){ 40 | var r = this.radius; 41 | var axes = ['x','y','z']; 42 | for(var i=0; i c.maxForce){ 99 | deltalambda = c.maxForce - lambdaj; 100 | } 101 | lambda[j] += deltalambda; 102 | 103 | deltalambdaTot += deltalambda > 0.0 ? deltalambda : -deltalambda; // abs(deltalambda) 104 | 105 | c.addToWlambda(deltalambda); 106 | } 107 | 108 | // If the total error is small enough - stop iterate 109 | if(deltalambdaTot*deltalambdaTot < tolSquared){ 110 | break; 111 | } 112 | } 113 | 114 | // Add result to velocity 115 | for(var i=0; i!==Nbodies; i++){ 116 | var b=bodies[i], 117 | v=b.velocity, 118 | w=b.angularVelocity; 119 | v.vadd(b.vlambda, v); 120 | if(w){ 121 | w.vadd(b.wlambda, w); 122 | } 123 | } 124 | } 125 | 126 | return iter; 127 | }; 128 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/solver/Solver.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Solver 3 | * @brief Constraint equation solver base class. 4 | * @author schteppe / https://github.com/schteppe 5 | */ 6 | CANNON.Solver = function(){ 7 | // All equations to be solved 8 | this.equations = []; 9 | }; 10 | 11 | // Should be implemented in subclasses! 12 | CANNON.Solver.prototype.solve = function(dt,world){ 13 | // Should return the number of iterations done! 14 | return 0; 15 | }; 16 | 17 | CANNON.Solver.prototype.addEquation = function(eq){ 18 | this.equations.push(eq); 19 | }; 20 | 21 | CANNON.Solver.prototype.removeEquation = function(eq){ 22 | var eqs = this.equations; 23 | var i = eqs.indexOf(eq); 24 | if(i !== -1){ 25 | eqs.splice(i,1); 26 | } 27 | }; 28 | 29 | CANNON.Solver.prototype.removeAllEquations = function(){ 30 | this.equations.length = 0; 31 | }; 32 | 33 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/solver/SplitSolver.js: -------------------------------------------------------------------------------- 1 | CANNON.SplitSolver = function(subsolver){ 2 | CANNON.Solver.call(this); 3 | this.subsolver = subsolver; 4 | }; 5 | CANNON.SplitSolver.prototype = new CANNON.Solver(); 6 | 7 | // Returns the number of subsystems 8 | var SplitSolver_solve_nodes = []; // All allocated node objects 9 | var SplitSolver_solve_eqs = []; // Temp array 10 | var SplitSolver_solve_bds = []; // Temp array 11 | var SplitSolver_solve_dummyWorld = {bodies:null}; // Temp object 12 | CANNON.SplitSolver.prototype.solve = function(dt,world){ 13 | var nodes=SplitSolver_solve_nodes, 14 | bodies=world.bodies, 15 | equations=this.equations, 16 | Neq=equations.length, 17 | Nbodies=bodies.length, 18 | subsolver=this.subsolver; 19 | // Create needed nodes, reuse if possible 20 | for(var i=nodes.length; i!==Nbodies; i++){ 21 | nodes.push({ body:bodies[i], children:[], eqs:[], visited:false }); 22 | } 23 | 24 | // Reset node values 25 | for(var i=0; i!==Nbodies; i++){ 26 | var node = nodes[i]; 27 | node.body = bodies[i]; 28 | node.children.length = 0; 29 | node.eqs.length = 0; 30 | node.visited = false; 31 | } 32 | for(var k=0; k!==Neq; k++){ 33 | var eq=equations[k], 34 | i=bodies.indexOf(eq.bi), 35 | j=bodies.indexOf(eq.bj), 36 | ni=nodes[i], 37 | nj=nodes[j]; 38 | ni.children.push(nj); 39 | ni.eqs.push(eq); 40 | nj.children.push(ni); 41 | nj.eqs.push(eq); 42 | } 43 | 44 | var STATIC = CANNON.Body.STATIC; 45 | function getUnvisitedNode(nodes){ 46 | var Nnodes = nodes.length; 47 | for(var i=0; i!==Nnodes; i++){ 48 | var node = nodes[i]; 49 | if(!node.visited && !(node.body.motionstate & STATIC)){ 50 | return node; 51 | } 52 | } 53 | return false; 54 | } 55 | 56 | function bfs(root,visitFunc){ 57 | var queue = []; 58 | queue.push(root); 59 | root.visited = true; 60 | visitFunc(root); 61 | while(queue.length) { 62 | var node = queue.pop(); 63 | // Loop over unvisited child nodes 64 | var child; 65 | while((child = getUnvisitedNode(node.children))) { 66 | child.visited = true; 67 | visitFunc(child); 68 | queue.push(child); 69 | } 70 | } 71 | } 72 | 73 | var child, n=0, eqs=SplitSolver_solve_eqs, bds=SplitSolver_solve_bds; 74 | function visitFunc(node){ 75 | bds.push(node.body); 76 | var Neqs = node.eqs.length; 77 | for(var i=0; i!==Neqs; i++){ 78 | var eq = node.eqs[i]; 79 | if(eqs.indexOf(eq) === -1){ 80 | eqs.push(eq); 81 | } 82 | } 83 | } 84 | var dummyWorld = SplitSolver_solve_dummyWorld; 85 | while((child = getUnvisitedNode(nodes))){ 86 | eqs.length = 0; 87 | bds.length = 0; 88 | bfs(child,visitFunc); 89 | 90 | var Neqs = eqs.length; 91 | for(var i=0; i!==Neqs; i++){ 92 | subsolver.addEquation(eqs[i]); 93 | } 94 | 95 | dummyWorld.bodies = bds; 96 | var iter = subsolver.solve(dt,dummyWorld); 97 | subsolver.removeAllEquations(); 98 | n++; 99 | } 100 | 101 | return n; 102 | }; 103 | -------------------------------------------------------------------------------- /vendor/cannon.js/src/utils/EventTarget.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.EventTarget 3 | * @see https://github.com/mrdoob/eventtarget.js/ 4 | */ 5 | CANNON.EventTarget = function () { 6 | var listeners = {}; 7 | this.addEventListener = function ( type, listener ) { 8 | if ( listeners[ type ] === undefined ) { 9 | listeners[ type ] = []; 10 | } 11 | if ( listeners[ type ].indexOf( listener ) === - 1 ) { 12 | listeners[ type ].push( listener ); 13 | } 14 | }; 15 | this.dispatchEvent = function ( event ) { 16 | for ( var listener in listeners[ event.type ] ) { 17 | listeners[ event.type ][ listener ]( event ); 18 | } 19 | }; 20 | this.removeEventListener = function ( type, listener ) { 21 | var index = listeners[ type ].indexOf( listener ); 22 | if ( index !== - 1 ) { 23 | listeners[ type ].splice( index, 1 ); 24 | } 25 | }; 26 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/src/utils/Pool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.ObjectPool 3 | * @brief For pooling objects that can be reused. 4 | */ 5 | CANNON.ObjectPool = function(){ 6 | this.objects = []; 7 | this.type = Object; 8 | }; 9 | 10 | CANNON.ObjectPool.prototype.release = function(){ 11 | var Nargs = arguments.length; 12 | for(var i=0; i!==Nargs; i++){ 13 | this.objects.push(arguments[i]); 14 | } 15 | }; 16 | 17 | CANNON.ObjectPool.prototype.get = function(){ 18 | if(this.objects.length===0){ 19 | return this.constructObject(); 20 | } else { 21 | return this.objects.pop(); 22 | } 23 | }; 24 | 25 | CANNON.ObjectPool.prototype.constructObject = function(){ 26 | throw new Error("constructObject() not implemented in this ObjectPool subclass yet!"); 27 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/src/utils/Vec3Pool.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @class CANNON.Vec3Pool 3 | */ 4 | CANNON.Vec3Pool = function(){ 5 | CANNON.ObjectPool.call(this); 6 | this.type = CANNON.Vec3; 7 | }; 8 | CANNON.Vec3Pool.prototype = new CANNON.ObjectPool(); 9 | 10 | CANNON.Vec3Pool.prototype.constructObject = function(){ 11 | return new CANNON.Vec3(); 12 | }; -------------------------------------------------------------------------------- /vendor/cannon.js/src/wrapper/End.js: -------------------------------------------------------------------------------- 1 | if (typeof module !== 'undefined') { 2 | // export for node 3 | module.exports = CANNON; 4 | } else { 5 | // assign to window 6 | this.CANNON = CANNON; 7 | } 8 | 9 | }).apply(this); -------------------------------------------------------------------------------- /vendor/cannon.js/src/wrapper/Start.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | -------------------------------------------------------------------------------- /vendor/cannon.js/test/Box.js: -------------------------------------------------------------------------------- 1 | var C = require("../build/cannon"); 2 | 3 | exports.Box = { 4 | forEachWOrldCorner : function(test){ 5 | var box = new C.Box(new C.Vec3(1,1,1)); 6 | var pos = new C.Vec3(); 7 | var quat = new C.Quaternion(); 8 | quat.setFromAxisAngle(new C.Vec3(0,0,1),Math.PI*0.25); 9 | var numCorners = 0; 10 | var unique = []; 11 | box.forEachWorldCorner(pos,quat,function(x,y,z){ 12 | var corner = new C.Vec3(x,y,z); 13 | for(var i=0; i