diff --git a/echo/Shape.hx b/echo/Shape.hx index 1938a1f..30b0875 100644 --- a/echo/Shape.hx +++ b/echo/Shape.hx @@ -206,11 +206,11 @@ class Shape #if cog implements cog.IComponent #end { public function collides(s:Shape):Null return null; - function collide_rect(r:Rect):Null return null; + function collide_rect(r:Rect, flip:Bool = false):Null return null; - function collide_circle(c:Circle):Null return null; + function collide_circle(c:Circle, flip:Bool = false):Null return null; - function collide_polygon(p:Polygon):Null return null; + function collide_polygon(p:Polygon, flip:Bool = false):Null return null; function toString() { var s = switch (type) { diff --git a/echo/shape/Circle.hx b/echo/shape/Circle.hx index 833e6e3..d3ad065 100644 --- a/echo/shape/Circle.hx +++ b/echo/shape/Circle.hx @@ -87,13 +87,13 @@ class Circle extends Shape implements Poolable { return false; } - override inline function collides(s:Shape):Null return s.collide_circle(this); + override inline function collides(s:Shape):Null return s.collide_circle(this, true); - override inline function collide_rect(r:Rect):Null return r.rect_and_circle(this, true); + override inline function collide_rect(r:Rect, flip:Bool = false):Null return r.rect_and_circle(this, !flip); - override inline function collide_circle(c:Circle):Null return c.circle_and_circle(this); + override inline function collide_circle(c:Circle, flip:Bool = false):Null return c.circle_and_circle(this, !flip); - override inline function collide_polygon(p:Polygon):Null return this.circle_and_polygon(p, true); + override inline function collide_polygon(p:Polygon, flip:Bool = false):Null return this.circle_and_polygon(p, flip); // getters inline function get_radius():Float return local_radius * scale_x; diff --git a/echo/shape/Polygon.hx b/echo/shape/Polygon.hx index add301f..3df13ea 100644 --- a/echo/shape/Polygon.hx +++ b/echo/shape/Polygon.hx @@ -197,13 +197,13 @@ class Polygon extends Shape implements Poolable { return false; } - override inline function collides(s:Shape):Null return s.collide_polygon(this); + override inline function collides(s:Shape):Null return s.collide_polygon(this, true); - override inline function collide_rect(r:Rect):Null return r.rect_and_polygon(this, true); + override inline function collide_rect(r:Rect, flip:Bool = false):Null return r.rect_and_polygon(this, !flip); - override inline function collide_circle(c:Circle):Null return c.circle_and_polygon(this); + override inline function collide_circle(c:Circle, flip:Bool = false):Null return c.circle_and_polygon(this, !flip); - override inline function collide_polygon(p:Polygon):Null return p.polygon_and_polygon(this, true); + override inline function collide_polygon(p:Polygon, flip:Bool = false):Null return this.polygon_and_polygon(p, flip); override inline function get_top():Float { if (count == 0 || vertices[0] == null) return y; diff --git a/echo/shape/Rect.hx b/echo/shape/Rect.hx index 7d5ba23..1658339 100644 --- a/echo/shape/Rect.hx +++ b/echo/shape/Rect.hx @@ -174,13 +174,13 @@ class Rect extends Shape implements Poolable { return false; } - override inline function collides(s:Shape):Null return s.collide_rect(this); + override inline function collides(s:Shape):Null return s.collide_rect(this, true); - override inline function collide_rect(r:Rect):Null return r.rect_and_rect(this); + override inline function collide_rect(r:Rect, flip:Bool = false):Null return this.rect_and_rect(r, flip); - override inline function collide_circle(c:Circle):Null return this.rect_and_circle(c); + override inline function collide_circle(c:Circle, flip:Bool = false):Null return this.rect_and_circle(c, flip); - override inline function collide_polygon(p:Polygon):Null return this.rect_and_polygon(p); + override inline function collide_polygon(p:Polygon, flip:Bool = false):Null return this.rect_and_polygon(p, flip); override function set_parent(?body:Body) { super.set_parent(body); diff --git a/echo/util/SAT.hx b/echo/util/SAT.hx index e3868e0..473e88c 100644 --- a/echo/util/SAT.hx +++ b/echo/util/SAT.hx @@ -190,17 +190,17 @@ class SAT { var col:CollisionData = null; if (rect1.rotation != 0 || rect2.rotation != 0) { if (rect1.transformed_rect != null) { - col = rect_and_polygon(rect2, rect1.transformed_rect, flip); + col = rect_and_polygon(rect2, rect1.transformed_rect, !flip); if (col == null) return null; - if (flip) col.sa = rect1; + if (flip) col.sa = rect2; else col.sb = rect1; return col; } if (rect2.transformed_rect != null) { - col = rect_and_polygon(rect1, rect2.transformed_rect, !flip); + col = rect_and_polygon(rect1, rect2.transformed_rect, flip); if (col == null) return null; @@ -318,6 +318,7 @@ class SAT { data1.put(); return data2; } + /** * Test a Rect and a Circle for a Collision. * @param r @@ -327,19 +328,21 @@ class SAT { */ public static function rect_and_circle(r:Rect, c:Circle, flip:Bool = false):Null { if (r.transformed_rect != null && r.rotation != 0) { - var col = circle_and_polygon(c, r.transformed_rect, flip); + var col = circle_and_polygon(c, r.transformed_rect, !flip); if (col == null) return null; - if (flip) col.sa = r; + // collisions used the transformed rect, set the collision data's shape back + // to the original rect + if (!flip) col.sa = r; else col.sb = r; return col; } // Vector from A to B - var nx = flip ? c.x - r.x : r.x - c.x; - var ny = flip ? c.y - r.y : r.y - c.y; + var nx = flip ? r.x - c.x : c.x - r.x; + var ny = flip ? r.y - c.y : c.y - r.y; // Closest point on A to center of B var cx = nx; var cy = ny; @@ -407,6 +410,8 @@ class SAT { if (col == null) return null; + // collisions were done with a polygon derrived from the provided rect + // so we need to set our collision data shape back to the original rectangle if (flip) col.sb = r; else col.sa = r; @@ -495,7 +500,7 @@ class SAT { test1 = min1 - max2; test2 = min2 - max1; - // Preform another test + // Perform another test if (test1 > 0 || test2 > 0) { col.put(); return null; @@ -579,7 +584,9 @@ class SAT { col.sa = flip ? polygon2 : polygon1; col.sb = flip ? polygon1 : polygon2; - if (flip) { + // collision normal is calculated as resolution for poly2, so we need to + // negate the normal if we are not flipping the collision check. + if (!flip) { col.normal.negate(); } diff --git a/sample/Main.hx b/sample/Main.hx index df38fa2..7e20393 100644 --- a/sample/Main.hx +++ b/sample/Main.hx @@ -50,6 +50,7 @@ class Main extends BaseApp { PolygonState, StackingState, MultiShapeState, ShapesState, GroupsState, StaticState, LinecastState, Linecast2State, TileMapState, TileMapState2, BezierState, VerletState ]; + index = 0; // Create a State Manager and pass it the World and the first Sample fsm = new FSM(world, Type.createInstance(sample_states[index], []));