Skip to content

Commit

Permalink
more tinkering. physics oddities isolated to circles
Browse files Browse the repository at this point in the history
  • Loading branch information
MondayHopscotch committed Jan 16, 2024
1 parent 99beaab commit bdf99d8
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 31 deletions.
6 changes: 3 additions & 3 deletions echo/Shape.hx
Original file line number Diff line number Diff line change
Expand Up @@ -206,11 +206,11 @@ class Shape #if cog implements cog.IComponent #end {

public function collides(s:Shape):Null<CollisionData> return null;

function collide_rect(r:Rect):Null<CollisionData> return null;
function collide_rect(r:Rect, flip:Bool = false):Null<CollisionData> return null;

function collide_circle(c:Circle):Null<CollisionData> return null;
function collide_circle(c:Circle, flip:Bool = false):Null<CollisionData> return null;

function collide_polygon(p:Polygon):Null<CollisionData> return null;
function collide_polygon(p:Polygon, flip:Bool = false):Null<CollisionData> return null;

function toString() {
var s = switch (type) {
Expand Down
6 changes: 3 additions & 3 deletions echo/shape/Circle.hx
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,11 @@ class Circle extends Shape implements Poolable {

override inline function collides(s:Shape):Null<CollisionData> return s.collide_circle(this);

override inline function collide_rect(r:Rect):Null<CollisionData> return r.rect_and_circle(this, true);
override inline function collide_rect(r:Rect, flip:Bool = false):Null<CollisionData> return r.rect_and_circle(this, !flip);

override inline function collide_circle(c:Circle):Null<CollisionData> return c.circle_and_circle(this);
override inline function collide_circle(c:Circle, flip:Bool = false):Null<CollisionData> return c.circle_and_circle(this, !flip);

override inline function collide_polygon(p:Polygon):Null<CollisionData> return this.circle_and_polygon(p, true);
override inline function collide_polygon(p:Polygon, flip:Bool = false):Null<CollisionData> return this.circle_and_polygon(p, flip);

// getters
inline function get_radius():Float return local_radius * scale_x;
Expand Down
8 changes: 4 additions & 4 deletions echo/shape/Polygon.hx
Original file line number Diff line number Diff line change
Expand Up @@ -197,13 +197,13 @@ class Polygon extends Shape implements Poolable {
return false;
}

override inline function collides(s:Shape):Null<CollisionData> return s.collide_polygon(this);
override inline function collides(s:Shape):Null<CollisionData> return s.collide_polygon(this, true);

override inline function collide_rect(r:Rect):Null<CollisionData> return r.rect_and_polygon(this, true);
override inline function collide_rect(r:Rect, flip:Bool = false):Null<CollisionData> return r.rect_and_polygon(this, !flip);

override inline function collide_circle(c:Circle):Null<CollisionData> return c.circle_and_polygon(this);
override inline function collide_circle(c:Circle, flip:Bool = false):Null<CollisionData> return c.circle_and_polygon(this, !flip);

override inline function collide_polygon(p:Polygon):Null<CollisionData> return p.polygon_and_polygon(this, true);
override inline function collide_polygon(p:Polygon, flip:Bool = false):Null<CollisionData> return this.polygon_and_polygon(p, flip);

override inline function get_top():Float {
if (count == 0 || vertices[0] == null) return y;
Expand Down
8 changes: 4 additions & 4 deletions echo/shape/Rect.hx
Original file line number Diff line number Diff line change
Expand Up @@ -174,13 +174,13 @@ class Rect extends Shape implements Poolable {
return false;
}

override inline function collides(s:Shape):Null<CollisionData> return s.collide_rect(this);
override inline function collides(s:Shape):Null<CollisionData> return s.collide_rect(this, true);

override inline function collide_rect(r:Rect):Null<CollisionData> return r.rect_and_rect(this);
override inline function collide_rect(r:Rect, flip:Bool = false):Null<CollisionData> return this.rect_and_rect(r, flip);

override inline function collide_circle(c:Circle):Null<CollisionData> return this.rect_and_circle(c);
override inline function collide_circle(c:Circle, flip:Bool = false):Null<CollisionData> return this.rect_and_circle(c, flip);

override inline function collide_polygon(p:Polygon):Null<CollisionData> return this.rect_and_polygon(p);
override inline function collide_polygon(p:Polygon, flip:Bool = false):Null<CollisionData> return this.rect_and_polygon(p, flip);

override function set_parent(?body:Body) {
super.set_parent(body);
Expand Down
31 changes: 21 additions & 10 deletions echo/util/SAT.hx
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -318,6 +318,7 @@ class SAT {
data1.put();
return data2;
}

/**
* Test a Rect and a Circle for a Collision.
* @param r
Expand All @@ -327,12 +328,17 @@ class SAT {
*/
public static function rect_and_circle(r:Rect, c:Circle, flip:Bool = false):Null<CollisionData> {
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;
else col.sb = 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;
}
Expand Down Expand Up @@ -407,8 +413,13 @@ class SAT {

if (col == null) return null;

if (flip) col.sb = r;
else col.sa = r;
// 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;
}

return col;
}
Expand Down Expand Up @@ -518,7 +529,7 @@ class SAT {

col.overlap = Math.abs(col.overlap);

if (flip) {
if (!flip) {
col.normal.negate();
}

Expand Down Expand Up @@ -579,7 +590,7 @@ class SAT {
col.sa = flip ? polygon2 : polygon1;
col.sb = flip ? polygon1 : polygon2;

if (flip) {
if (!flip) {
col.normal.negate();
}

Expand Down
2 changes: 1 addition & 1 deletion sample/Main.hx
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class Main extends BaseApp {

// Set up our Sample States
sample_states = [
ListenerState, PolygonState, StackingState, MultiShapeState, ShapesState, GroupsState, StaticState, LinecastState, Linecast2State, TileMapState, TileMapState2,
OverlappingSpawnState, ListenerState, PolygonState, StackingState, MultiShapeState, ShapesState, GroupsState, StaticState, LinecastState, Linecast2State, TileMapState, TileMapState2,
BezierState, VerletState
];
index = 0;
Expand Down
7 changes: 4 additions & 3 deletions sample/state/ListenerState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ class ListenerState extends BaseState {
var bodyA = new Body({
x: Random.range(60, world.width - 60),
y: Random.range(0, world.height / 2),
rotation: Random.range(0, 360),
// rotation: Random.range(0, 360),
material: material,
shapes: [
{
Expand Down Expand Up @@ -59,9 +59,10 @@ class ListenerState extends BaseState {
var dbgOpts:ListenerOptions = {
enter: (a, b, data) -> {
trace('bodyA == listener `a`: ${bodyA == a}');
trace('bodyA shape == data `shape a`: ${bodyA.shape == data[0].sa}');
// the second shape is our 'bottom' shape that is making the collision
trace('bodyA owns data `shape a`: ${bodyA.shapes.contains(data[0].sa)}');
trace('bodyB == listener `b`: ${bodyB == b}');
trace('bodyB shape == data `shape b`: ${bodyB.shape == data[0].sb}');
trace('bodyB owns `shape b`: ${bodyB.shapes.contains(data[0].sb)}');
},
};

Expand Down
78 changes: 78 additions & 0 deletions sample/state/OverlappingSpawnState.hx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package state;

import echo.data.Options.ListenerOptions;
import echo.Material;
import echo.Body;
import echo.World;
import util.Random;

class OverlappingSpawnState extends BaseState {

override public function enter(world:World) {
Main.instance.state_text.text = "Sample: Collision Listener";

// Create a material for all the shapes to share
var material:Material = {elasticity: 0.7};

var body = new Body({
x: 200,
y: 50,
rotation: 0,
material: material,
shape: {
type: POLYGON,
radius: 16,
width: 16,
height: 16,
sides: 5,
offset_y: 0,
}
});
world.add(body);

body = new Body({
x: 200,
y: 53,
rotation: 0,
material: material,
shape: {
type: POLYGON,
radius: 10,
width: 10,
height: 10,
sides: 5,
offset_y: 0,
}
});
world.add(body);

// Add a Physics body at the bottom of the screen for the other Physics Bodies to stack on top of
// This body has a mass of 0, so it acts as an immovable object
var floor = new Body({
mass: STATIC,
x: world.width / 5,
y: world.height - 40,
material: material,
rotation: 5,
shape: {
type: RECT,
width: world.width,
height: 20
}
});
world.add(floor);

// Create a listener for collisions between the Physics Bodies
world.listen();
}

override function step(world:World, dt:Float) {
// Reset any off-screen Bodies
world.for_each((member) -> {
if (offscreen(member, world)) {
member.velocity.set(0, 0);
member.set_position(Random.range(0, world.width), 0);
}
});
}
}
2 changes: 1 addition & 1 deletion sample/state/PolygonState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class PolygonState extends BaseState {
var b = new Body({
x: Random.range(60, world.width - 60),
y: Random.range(0, world.height / 2),
rotation: Random.range(0, 360),
rotation: 0,
material: material,
shape: {
type: POLYGON,
Expand Down
7 changes: 5 additions & 2 deletions sample/state/StaticState.hx
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,11 @@ class StaticState extends BaseState {
y: (world.height * 0.5) * Math.sin(i) + world.height * 0.5,
material: static_material,
shape: {
type: CIRCLE,
radius: Random.range(2, 4),
// type: CIRCLE,
// radius: Random.range(2, 4),
type: RECT,
width: Random.range(2, 4),
height: Random.range(2, 4)
}
});
world.add(b);
Expand Down

0 comments on commit bdf99d8

Please sign in to comment.