UNPKG

threex

Version:

Game Extensions for three.js http://www.threejsgames.com/extensions/

347 lines (210 loc) 6.11 kB
var THREEx = THREEx || {} THREEx.MagnetControls = function(object3d){ // export object3d this.object3d = object3d this.id = THREEx.MagnetControls.nextId++ // physics constant var velocity = new THREE.Vector3() this.velocity = velocity var acceleration= new THREE.Vector3() this.acceleration=acceleration var damping = new THREE.Vector3().set(1,1,1).multiplyScalar(0.9) this.damping = damping this.applyForces = function(){ // handle physics velocity.multiply(damping) velocity.add(acceleration) acceleration.set(0,0,0) // update object3d position object3d.position.add(velocity) } ////////////////////////////////////////////////////////////////////////////////// // force // ////////////////////////////////////////////////////////////////////////////////// /** * * queue bunch of funciton for physics * * onComputeForces = [] * * this.computeForces run all of them */ this.computeForces = function(others, controlsIdx){ for(var i = controlsIdx+1; i < others.length; i++){ var other = others[i] computeInteraction(this, others[i]) } function computeInteraction(controls1, controls2){ var object3d1 = controls1.object3d var object3d2 = controls2.object3d var distance = object3d1.position.distanceTo(object3d2.position) var maxDistance = 2 if( distance > maxDistance ) return // compute force intensity var proximity = distance/maxDistance // console.assert(proximity>= 0 && proximity <= 1) var easing = THREEx.MagnetControls.Easing var intensity = easing.Cubic.In(1-proximity)*0.1 // compute force vector var force = object3d1.position.clone() .sub(object3d2.position) .multiplyScalar(intensity) // apply the force to acceleration controls1.acceleration.add(force) controls2.acceleration.sub(force) } } } THREEx.MagnetControls.nextId = 0 // directly from tween.js THREEx.MagnetControls.Easing = { Linear: { None: function ( k ) { return k; } }, Quadratic: { In: function ( k ) { return k * k; }, Out: function ( k ) { return k * ( 2 - k ); }, InOut: function ( k ) { if ( ( k *= 2 ) < 1 ) return 0.5 * k * k; return - 0.5 * ( --k * ( k - 2 ) - 1 ); } }, Cubic: { In: function ( k ) { return k * k * k; }, Out: function ( k ) { return --k * k * k + 1; }, InOut: function ( k ) { if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k; return 0.5 * ( ( k -= 2 ) * k * k + 2 ); } }, Quartic: { In: function ( k ) { return k * k * k * k; }, Out: function ( k ) { return 1 - ( --k * k * k * k ); }, InOut: function ( k ) { if ( ( k *= 2 ) < 1) return 0.5 * k * k * k * k; return - 0.5 * ( ( k -= 2 ) * k * k * k - 2 ); } }, Quintic: { In: function ( k ) { return k * k * k * k * k; }, Out: function ( k ) { return --k * k * k * k * k + 1; }, InOut: function ( k ) { if ( ( k *= 2 ) < 1 ) return 0.5 * k * k * k * k * k; return 0.5 * ( ( k -= 2 ) * k * k * k * k + 2 ); } }, Sinusoidal: { In: function ( k ) { return 1 - Math.cos( k * Math.PI / 2 ); }, Out: function ( k ) { return Math.sin( k * Math.PI / 2 ); }, InOut: function ( k ) { return 0.5 * ( 1 - Math.cos( Math.PI * k ) ); } }, Exponential: { In: function ( k ) { return k === 0 ? 0 : Math.pow( 1024, k - 1 ); }, Out: function ( k ) { return k === 1 ? 1 : 1 - Math.pow( 2, - 10 * k ); }, InOut: function ( k ) { if ( k === 0 ) return 0; if ( k === 1 ) return 1; if ( ( k *= 2 ) < 1 ) return 0.5 * Math.pow( 1024, k - 1 ); return 0.5 * ( - Math.pow( 2, - 10 * ( k - 1 ) ) + 2 ); } }, Circular: { In: function ( k ) { return 1 - Math.sqrt( 1 - k * k ); }, Out: function ( k ) { return Math.sqrt( 1 - ( --k * k ) ); }, InOut: function ( k ) { if ( ( k *= 2 ) < 1) return - 0.5 * ( Math.sqrt( 1 - k * k) - 1); return 0.5 * ( Math.sqrt( 1 - ( k -= 2) * k) + 1); } }, Elastic: { In: function ( k ) { var s, a = 0.1, p = 0.4; if ( k === 0 ) return 0; if ( k === 1 ) return 1; if ( !a || a < 1 ) { a = 1; s = p / 4; } else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); return - ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); }, Out: function ( k ) { var s, a = 0.1, p = 0.4; if ( k === 0 ) return 0; if ( k === 1 ) return 1; if ( !a || a < 1 ) { a = 1; s = p / 4; } else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); return ( a * Math.pow( 2, - 10 * k) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) + 1 ); }, InOut: function ( k ) { var s, a = 0.1, p = 0.4; if ( k === 0 ) return 0; if ( k === 1 ) return 1; if ( !a || a < 1 ) { a = 1; s = p / 4; } else s = p * Math.asin( 1 / a ) / ( 2 * Math.PI ); if ( ( k *= 2 ) < 1 ) return - 0.5 * ( a * Math.pow( 2, 10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) ); return a * Math.pow( 2, -10 * ( k -= 1 ) ) * Math.sin( ( k - s ) * ( 2 * Math.PI ) / p ) * 0.5 + 1; } }, Back: { In: function ( k ) { var s = 1.70158; return k * k * ( ( s + 1 ) * k - s ); }, Out: function ( k ) { var s = 1.70158; return --k * k * ( ( s + 1 ) * k + s ) + 1; }, InOut: function ( k ) { var s = 1.70158 * 1.525; if ( ( k *= 2 ) < 1 ) return 0.5 * ( k * k * ( ( s + 1 ) * k - s ) ); return 0.5 * ( ( k -= 2 ) * k * ( ( s + 1 ) * k + s ) + 2 ); } }, Bounce: { In: function ( k ) { return 1 - TWEEN.Easing.Bounce.Out( 1 - k ); }, Out: function ( k ) { if ( k < ( 1 / 2.75 ) ) { return 7.5625 * k * k; } else if ( k < ( 2 / 2.75 ) ) { return 7.5625 * ( k -= ( 1.5 / 2.75 ) ) * k + 0.75; } else if ( k < ( 2.5 / 2.75 ) ) { return 7.5625 * ( k -= ( 2.25 / 2.75 ) ) * k + 0.9375; } else { return 7.5625 * ( k -= ( 2.625 / 2.75 ) ) * k + 0.984375; } }, InOut: function ( k ) { if ( k < 0.5 ) return TWEEN.Easing.Bounce.In( k * 2 ) * 0.5; return TWEEN.Easing.Bounce.Out( k * 2 - 1 ) * 0.5 + 0.5; } } };