@@ -23,6 +23,7 @@ export interface onCollisionCallbackParams {
2323 otherObject : PhysicsObject ;
2424 simulationResult : {
2525 velocity : Vec2
26+ position : Vec2
2627 }
2728 // collisionPlane: Vec2;
2829}
@@ -42,7 +43,7 @@ export interface PhysicalObjectCallbackAggregate {
4243}
4344
4445enum CollisionQuadrant {
45- TopLeft ,
46+ TopLeft = 1 ,
4647 TopRight ,
4748 BottomLeft ,
4849 BottomRight
@@ -72,21 +73,35 @@ export class Physx {
7273 }
7374
7475 private checkCollision ( objectA : PhysicsObject , objectB : PhysicsObject ) : Vec2 | null {
75- const [ x1 , y1 , w1 , h1 ] = objectA . aabb ;
76- const [ x2 , y2 , w2 , h2 ] = objectB . aabb ;
77-
7876 if ( objectA . isContainer ) {
7977 return this . checkCollisionContainer ( objectA , objectB ) ;
8078 } else if ( objectB . isContainer ) {
8179 return this . checkCollisionContainer ( objectB , objectA ) ;
8280 }
8381
82+ return this . checkCollisionClassic ( objectA , objectB ) ;
83+ }
84+
85+ private checkCollisionClassic ( objectA : PhysicsObject , objectB : PhysicsObject ) : Vec2 | null {
86+ const [ x1 , y1 , w1 , h1 ] = objectA . aabb ;
87+ const [ x2 , y2 , w2 , h2 ] = objectB . aabb ;
88+
89+ const x1v = x1 + objectA . velocity . x ;
90+ const y1v = y1 + objectA . velocity . y ;
91+ const x2v = x2 + objectB . velocity . x ;
92+ const y2v = y2 + objectB . velocity . y ;
93+
94+ const xw1v = x1v + w1 ;
95+ const yh1v = y1v + h1 ;
96+ const xw2v = x2v + w2 ;
97+ const yh2v = y2v + h2 ;
98+
8499 // normal collision detection
85100 if (
86- x1 < x2 + w2 &&
87- x1 + w1 > x2 &&
88- y1 < y2 + h2 &&
89- y1 + h1 > y2
101+ x1v < xw2v &&
102+ xw1v > x2v &&
103+ y1v < yh2v &&
104+ yh1v > y2v
90105 ) {
91106 return new Vec2 ( ) ;
92107 }
@@ -98,83 +113,32 @@ export class Physx {
98113 const [ x1 , y1 , w1 , h1 ] = container . aabb ;
99114 const [ x2 , y2 , w2 , h2 ] = objectB . aabb ;
100115
101- const xw1 = x1 + w1 ;
102- const yh1 = y1 + h1 ;
103- const xw2 = x2 + w2 ;
104- const yh2 = y2 + h2 ;
105-
106- let result : Vec2 | null = null ;
107- let collisionQuadrant : CollisionQuadrant | null = null ;
108-
109- // another way might be to find the center of mass of each object and get the normal based on the
110- // position of the objectB related to the center of mass of the container
111- const containerCenterOfMass = new Vec2 ( x1 + w1 / 2 , y1 + h1 / 2 ) ;
112- const objectBCenterOfMass = new Vec2 ( x2 + w2 / 2 , y2 + h2 / 2 ) ;
113-
114- if ( containerCenterOfMass . x <= objectBCenterOfMass . x && containerCenterOfMass . y <= objectBCenterOfMass . y ) {
115- collisionQuadrant = CollisionQuadrant . TopRight ;
116- } else if ( objectBCenterOfMass . x < containerCenterOfMass . x && containerCenterOfMass . y <= objectBCenterOfMass . y ) {
117- collisionQuadrant = CollisionQuadrant . TopLeft ;
118- } else if ( containerCenterOfMass . x <= objectBCenterOfMass . x && objectBCenterOfMass . y < containerCenterOfMass . y ) {
119- collisionQuadrant = CollisionQuadrant . BottomRight ;
120- } else {
121- collisionQuadrant = CollisionQuadrant . BottomLeft ;
122- }
116+ const x1v = x1 + container . velocity . x ;
117+ const y1v = y1 + container . velocity . y ;
118+ const x2v = x2 + objectB . velocity . x ;
119+ const y2v = y2 + objectB . velocity . y ;
120+
121+ const xw1v = x1v + w1 ;
122+ const yh1v = y1v + h1 ;
123+ const xw2v = x2v + w2 ;
124+ const yh2v = y2v + h2 ;
123125
124- if ( collisionQuadrant === CollisionQuadrant . TopRight && ( xw2 > xw1 || yh2 > yh1 ) ) {
125- // if xw2 - xw1 < yh2 - yh1 - the smaller negative number wins as it's the one with the greatest collision area
126- // normal is a vector facing left
127- // else is a vector facing down
128- // new velocity is the reflection of the object original velocity related to the normal
129-
130- result = Vec2 . from ( objectB . velocity ) ;
131-
132- if ( xw2 - xw1 < yh2 - yh1 ) {
133- result . reflect ( Vec2 . LEFT ) ;
134- } else {
135- result . reflect ( Vec2 . DOWN ) ;
136- }
137- } else if ( collisionQuadrant === CollisionQuadrant . BottomRight && ( xw2 > xw1 || y2 < y1 ) ) {
138- // if xw2 - xw1 < y2 - y1
139- // normal is a vector facing left
140- // else a vector facing up
141- // new velocity is the reflection of the object original velocity related to the normal
142-
143- result = Vec2 . from ( objectB . velocity ) ;
144-
145- if ( xw2 - xw1 < y2 - y1 ) {
146- result . reflect ( Vec2 . LEFT ) ;
147- } else {
148- result . reflect ( Vec2 . UP ) ;
149- }
150- } else if ( collisionQuadrant === CollisionQuadrant . BottomLeft && ( x2 < x1 || y2 < y1 ) ) {
151- // if x2 - x1 > y2 - y1 - on the left the bigger positive number wins
152- // normal is a vector facing right
153- // else a vector facing up
154- // new velocity is the reflection of the object original velocity related to the normal
155-
156- result = Vec2 . from ( objectB . velocity ) ;
157-
158- if ( x2 - x1 > y2 - y1 ) {
159- result . reflect ( Vec2 . RIGHT ) ;
160- } else {
161- result . reflect ( Vec2 . UP ) ;
162- }
163- } else if ( collisionQuadrant === CollisionQuadrant . TopLeft && ( x2 < x1 || yh2 > yh1 ) ) {
164- // if x2 - x1 > yh2 - yh1 - on the left the bigger positive number wins
165- // normal is a vector facing right
166- // else a vector facing down
167- // new velocity is the reflection of the object original velocity related to the normal
168-
169- result = Vec2 . from ( objectB . velocity ) ;
170-
171- if ( x2 - x1 > yh2 - yh1 ) {
172- result . reflect ( Vec2 . RIGHT ) ;
173- } else {
174- result . reflect ( Vec2 . DOWN ) ;
175- }
126+ if ( xw2v > xw1v ) {
127+ return new Vec2 ( ) ;
176128 }
177-
178- return result ;
129+
130+ if ( yh2v > yh1v ) {
131+ return new Vec2 ( ) ;
132+ }
133+
134+ if ( x2v < x1v ) {
135+ return new Vec2 ( ) ;
136+ }
137+
138+ if ( y2v < y1v ) {
139+ return new Vec2 ( ) ;
140+ }
141+
142+ return null ;
179143 }
180144}
0 commit comments