@@ -1614,12 +1614,22 @@ Broadphase.aabbCheck = function(bodyA, bodyB){
16141614 * @return {Boolean }
16151615 */
16161616Broadphase . canCollide = function ( bodyA , bodyB ) {
1617+
16171618 // Cannot collide static bodies
1618- if ( bodyA . motionState & Body . STATIC && bodyB . motionState & Body . STATIC )
1619+ if ( bodyA . motionState == Body . STATIC && bodyB . motionState == Body . STATIC )
1620+ return false ;
1621+
1622+ // Cannot collide static vs kinematic bodies
1623+ if ( ( bodyA . motionState == Body . KINEMATIC && bodyB . motionState == Body . STATIC ) ||
1624+ ( bodyA . motionState == Body . STATIC && bodyB . motionState == Body . KINEMATIC ) )
1625+ return false ;
1626+
1627+ // Cannot collide kinematic vs kinematic
1628+ if ( bodyA . motionState == Body . KINEMATIC && bodyB . motionState == Body . KINEMATIC )
16191629 return false ;
16201630
1621- // Cannot collide sleeping bodies
1622- if ( bodyA . sleepState & Body . SLEEPING && bodyB . sleepState & Body . SLEEPING )
1631+ // Cannot collide both sleeping bodies
1632+ if ( bodyA . sleepState == Body . SLEEPING && bodyB . sleepState == Body . SLEEPING )
16231633 return false ;
16241634
16251635 return true ;
@@ -2027,9 +2037,9 @@ Narrowphase.prototype.createContactEquation = function(bodyA,bodyB,shapeA,shapeB
20272037 c . firstImpact = ! this . collidedLastStep ( bodyA , bodyB ) ;
20282038 c . enabled = true ;
20292039
2030- if ( bodyA . allowSleep && ( bodyA . motionState & Body . DYNAMIC ) && ! ( bodyB . motionState & Body . STATIC || bodyB . sleepState === Body . SLEEPY ) )
2040+ if ( bodyA . allowSleep && ( bodyA . motionState == Body . DYNAMIC ) && ! ( bodyB . motionState == Body . STATIC || bodyB . sleepState === Body . SLEEPY ) )
20312041 bodyA . wakeUp ( ) ;
2032- if ( bodyB . allowSleep && ( bodyB . motionState & Body . DYNAMIC ) && ! ( bodyA . motionState & Body . STATIC || bodyA . sleepState === Body . SLEEPY ) )
2042+ if ( bodyB . allowSleep && ( bodyB . motionState == Body . DYNAMIC ) && ! ( bodyA . motionState == Body . STATIC || bodyA . sleepState === Body . SLEEPY ) )
20332043 bodyB . wakeUp ( ) ;
20342044
20352045 return c ;
@@ -4111,9 +4121,11 @@ SAPBroadphase.prototype.getCollisionPairs = function(world){
41114121 break ;
41124122
41134123 // add pair to preliminary list
4114- var key = bi . id < bj . id ? bi . id + ' ' + bj . id : bj . id + ' ' + bi . id ;
4115- preliminaryList [ key ] = true ;
4116- preliminaryList . keys . push ( key ) ;
4124+ if ( Broadphase . canCollide ( bi , bj ) ) {
4125+ var key = bi . id < bj . id ? bi . id + ' ' + bj . id : bj . id + ' ' + bi . id ;
4126+ preliminaryList [ key ] = true ;
4127+ preliminaryList . keys . push ( key ) ;
4128+ }
41174129 }
41184130 }
41194131
@@ -4128,9 +4140,11 @@ SAPBroadphase.prototype.getCollisionPairs = function(world){
41284140 break ;
41294141
41304142 // If in preliminary list, add to final result
4131- var key = bi . id < bj . id ? bi . id + ' ' + bj . id : bj . id + ' ' + bi . id ;
4132- if ( preliminaryList [ key ] && Broadphase . boundingRadiusCheck ( bi , bj ) )
4133- result . push ( bi , bj ) ;
4143+ if ( Broadphase . canCollide ( bi , bj ) ) {
4144+ var key = bi . id < bj . id ? bi . id + ' ' + bj . id : bj . id + ' ' + bi . id ;
4145+ if ( preliminaryList [ key ] && Broadphase . boundingRadiusCheck ( bi , bj ) )
4146+ result . push ( bi , bj ) ;
4147+ }
41344148 }
41354149 }
41364150
@@ -6793,6 +6807,12 @@ function Body(options){
67936807 */
67946808 this . sleepTimeLimit = 1 ;
67956809
6810+ /**
6811+ * Gravity scaling factor. If you want the body to ignore gravity, set this to zero. If you want to reverse gravity, set it to -1.
6812+ * @property {Number } gravityScale
6813+ */
6814+ this . gravityScale = 1 ;
6815+
67966816 this . timeLastSleepy = 0 ;
67976817
67986818 this . concavePath = null ;
@@ -7040,6 +7060,7 @@ Body.prototype.fromPolygon = function(path,options){
70407060
70417061 var p = new decomp . Polygon ( ) ;
70427062 p . vertices = path ;
7063+
70437064 // Make it counter-clockwise
70447065 p . makeCCW ( ) ;
70457066
@@ -7174,7 +7195,7 @@ Body.prototype.addConstraintVelocity = function(){
71747195 * @param {number } dt Current time step
71757196 */
71767197Body . prototype . applyDamping = function ( dt ) {
7177- if ( this . motionState & Body . DYNAMIC ) { // Only for dynamic bodies
7198+ if ( this . motionState == Body . DYNAMIC ) { // Only for dynamic bodies
71787199
71797200 // Since Math.pow generates garbage we check if we can reuse the scaling coefficient from last step
71807201 if ( dt != this . lastDampingTimeStep ) {
@@ -8619,7 +8640,7 @@ function getUnvisitedNode(nodes){
86198640 var Nnodes = nodes . length ;
86208641 for ( var i = 0 ; i !== Nnodes ; i ++ ) {
86218642 var node = nodes [ i ] ;
8622- if ( ! node . visited && ! ( node . body . motionState & STATIC ) ) { // correct?
8643+ if ( ! node . visited && ! ( node . body . motionState == STATIC ) ) { // correct?
86238644 return node ;
86248645 }
86258646 }
@@ -9401,7 +9422,7 @@ World.prototype.internalStep = function(dt){
94019422 for ( var i = 0 ; i !== Nbodies ; i ++ ) {
94029423 var b = bodies [ i ] ,
94039424 fi = b . force ;
9404- vec2 . scale ( mg , g , b . mass ) ; // F=m*g
9425+ vec2 . scale ( mg , g , b . mass * b . gravityScale ) ; // F=m*g
94059426 add ( fi , fi , mg ) ;
94069427 }
94079428 }
@@ -9417,7 +9438,8 @@ World.prototype.internalStep = function(dt){
94179438 if ( this . applyDamping ) {
94189439 for ( var i = 0 ; i !== Nbodies ; i ++ ) {
94199440 var b = bodies [ i ] ;
9420- b . applyDamping ( dt ) ;
9441+ if ( b . motionState == Body . DYNAMIC )
9442+ b . applyDamping ( dt ) ;
94219443 }
94229444 }
94239445
@@ -9466,13 +9488,14 @@ World.prototype.internalStep = function(dt){
94669488
94679489 // Emit shape end overlap events
94689490 var last = this . overlappingShapesLastState ;
9469- for ( var i = 0 ; i < last . keys . length ; i ++ ) {
9491+ for ( var i = 0 ; i !== last . keys . length ; i ++ ) {
94709492 var key = last . keys [ i ] ;
9471- if ( key . indexOf ( "shape" ) != - 1 || key . indexOf ( "body" ) != - 1 )
9472- break ;
9493+
9494+ if ( last [ key ] !== true )
9495+ continue ;
94739496
94749497 if ( ! this . overlappingShapesCurrentState [ key ] ) {
9475- // Not overlapping any more! Emit event.
9498+ // Not overlapping in current state, but in last state. Emit event!
94769499 var e = this . endContactEvent ;
94779500
94789501 // Add shapes to the event object
@@ -9482,19 +9505,24 @@ World.prototype.internalStep = function(dt){
94829505 e . bodyB = last [ key + "_bodyB" ] ;
94839506 this . emit ( e ) ;
94849507 }
9508+ }
94859509
9486- // Clear old data
9487- delete last [ key ] ;
9488- delete last [ key + "_shapeA" ] ;
9489- delete last [ key + "_shapeB" ] ;
9490- delete last [ key + "_bodyA" ] ;
9491- delete last [ key + "_bodyB" ] ;
9510+ // Clear last object
9511+ for ( var i = 0 ; i !== last . keys . length ; i ++ )
9512+ delete last [ last . keys [ i ] ] ;
9513+ last . keys . length = 0 ;
9514+
9515+ // Transfer from new object to old
9516+ var current = this . overlappingShapesCurrentState ;
9517+ for ( var i = 0 ; i !== current . keys . length ; i ++ ) {
9518+ last [ current . keys [ i ] ] = current [ current . keys [ i ] ] ;
9519+ last . keys . push ( current . keys [ i ] ) ;
94929520 }
9493- this . overlappingShapesLastState . keys . length = 0 ;
9494- // Swap state objects
9495- var tmp = this . overlappingShapesLastState ;
9496- this . overlappingShapesLastState = this . overlappingShapesCurrentState ;
9497- this . overlappingShapesCurrentState = tmp ;
9521+
9522+ // Clear current object
9523+ for ( var i = 0 ; i !== current . keys . length ; i ++ )
9524+ delete current [ current . keys [ i ] ] ;
9525+ current . keys . length = 0 ;
94989526
94999527 var preSolveEvent = this . preSolveEvent ;
95009528 preSolveEvent . contactEquations = np . contactEquations ;
@@ -9522,7 +9550,7 @@ World.prototype.internalStep = function(dt){
95229550 for ( var i = 0 ; i !== Nbodies ; i ++ ) {
95239551 var body = bodies [ i ] ;
95249552
9525- if ( body . sleepState !== Body . SLEEPING && body . mass > 0 ) {
9553+ if ( body . sleepState !== Body . SLEEPING && body . motionState != Body . STATIC ) {
95269554 World . integrateBody ( body , dt ) ;
95279555 }
95289556 }
0 commit comments