Aether.Physics2D - Release v 1.0

Hi @holyfuzz.

That’s true. It’s not deterministic which contact will get processed first. The multi-threading solvers locks the two bodies in a contact during processing.
Multi-threading is off by default. To turn it on you specify a threshold which is the number of active contacts. It’s unnecessary to set up threads when you have a small number contacts. You can set thresholds for PositionConstrainsSolver, VelocityConstrainsSolver and Contacts, individually.
It’s possible that the contacts does not update the bodies (It doesn’t alter position/velocity/etc), but that’s something I have to double check, I can’t say for sure right now. Although callback events like OnCollision/OnSeperation will fire from different threads. You have to buffer and change object states on the next update.

Farseer has a couple of triangulation tools, maybe you can find an algorithm that reduces the number of fixtures from what you have now.

In most engines you use a simplified approximation for collisions.

You can setup a body with a few fixtures that cover your sprite and subscribe to Body.OnCollision where you can perform a per-pixel collision. If you return false from OnCollision() the collision is ignored. For a generic solution you can listen to World.ContactManager.BeginContact and implement a IPixelPerfectCollision interface or something similar on some of your bodies.

Another idea:
Have you tried to add a reference to the body in FixtureProxy?
You could then quickly discard the pair inside .AddPair() without having to get the bodies through fixture, which probably cause a cache-miss.

Hey guys!

I tried to port my game from the good old FarseerPhysics to this engine. Unfortunately I have some problems with it.
First, where is the IgnoreCollisionWith-method? Is there any replacement for it? Same goes for the ConvertUnits-class.
An other issue is that the collision not working any more. If my player collides with a edge, it bounced back ~50px and sometimes he walk through it. I have attached a sample clip: https://www.dropbox.com/s/66eypwcat3uljpz/collisionbug.mp4?dl=0
But the strangest issue is, that I can not work right any more. left, up and down works well…
I have nothing changed to the code, just only replaced FarseerPhysics-parts with Aether. So why ist that?

The ConvertUnits was removed. An orthographic camera (View&Projection) is preferred for rendering your Physics world.
You can find ConvertUnits here and copy it in your project if you find it useful.

IgnoreCollisionWith was removed as well.
Depending on your scenario you can use some other collision mechanism like Fixture.BeforeCollision, ContactManager.ContactFilter, Fixture.OnCollision or ContactManager.BeginContact.

Maybe your step time is to long and/or the force is too big (tunneling). Try to set your sprite as a Bullet.

That’s strange. You have to narrow it down to a short simulation/test to reproduce it.
What version of Farseer were you using?

EDIT
In the last second of the video you break into the code and I see that you have a newPosition variable.
Did you update the position of the sprite directly on each frame? By forcing a position it’s like teleporting a body into another one. If that’s the case then the simulation sees two bodies overlapping and tries to break the collision by throwing them apart, that’s why your sprite is jumping away from either side of the edge.
You need to move the sprite by applying a force, where then the simulation has knowledge about the sprite position/movement and can correctly resolve collision and move the body to the new position.
Read on http://www.iforce2d.net/b2dtut/forces about force, impulse and ‘teleporting’.

Hi,

you brought me the right idea. The jump comes from my dynamic-body which have an kinematic-body as his hull.
The code you see is for the inital position I set to my characters.
I’m only sync the two bodies after the world step. I use that two bodies to prevent to shove the other characters if they collide. And that is the issue here to. In FarseerPhysics I use the IgnoreCollisionWith method on both bodies, but now its gone and the collision works again… I think its a dirty work around, but I dont have any idea how to fix it either. If you know how I could prevent shoving, without that, let me hear :smiley:

You mean something like restitution/inelastic collision?
http://www.iforce2d.net/b2dtut/fixtures
“Restitution measures how ‘bouncy’ a fixture is. Like friction, it is given a value between 0 and 1, where zero means that the fixture will not bounce at all, and one means that all the energy of the bounce will be conserved. When two fixtures collide with each other, the resulting restitution tends toward the higher of their restitution values.”

Hi,

I have set it already to 0. Here 2 clips to show what I mean (shove/push):
No-Shove https://www.dropbox.com/s/rxyhehvvnaknu1i/noshove.mp4?dl=0
Shove: https://www.dropbox.com/s/voencbmzx7d75fe/shove.mp4?dl=0

Oh, I see. Your workaround sounds about right. I don’t see a simpler way to do that.

No way :smiley: I hoped you say something like “Hey you did it all wrong, use … instead”

2 Likes

Is it possible to rotate a body relative to its LocalCenter? I want the player to look towards the mouse so I have set FixedRotation = true and I’m setting Body.Rotation but its rotating around the corner.

You have a couple of options here,

  1. offset all your fixtures so that the center of mass is at the center of the body. you will now have body.LocalCenter = [0,0] and body.WorldCenter = body.Position. This will throw off other code like drawing, etc.

  2. Update both body.Rotation and body.Position in respect of body.WorldCenter. You need to rotate body.Position from the point of referent of body.WorldCenter.
    I think you need to do something like that,

var rotDiff = targetRot - body.Rotation;
var posFromCenter = body.WorldCenter - body.Position;
var newPosFromCenter = Complex.Multiply(posFromCenter, Complex.FromAngle(rotDiff));
body.Position =  body.WorldCenter - newPosFromCenter;
body.Rotation = body.Rotation + rotDiff;

  1. Remove FixedRotation and use one of ApplyAngularForce(),ApplyTorque(), use a MotorJoint or a custom Joint to correct the rotation on each step. Or use the code from 2) but set body velocities instead. This might cause your sprite to occasionally oscillate around targetRotation when colliding with other objects. Increasing the mass or inertia to reduce the influence of other bodies. Keep in mind that if you explicitly set rotation/position (aka “Transporting”) the engine doesn’t know which way to resolve collisions and can cause overshoot or unexpected behavior.

Thanks alot,

I have used Solution 1) since it was pretty easy to shift the drawn picture as well.

I’m curious if anyone has used this engine for commercial games? Has it worked out well? Seems like a great tool.

Hi @holyfuzz, what you’re describing sounds very similar to some performance issues I’ve found in my testing. Would you be willing to share your modified BroadPhase code? I’m very interested in testing it out and seeing if it optimizes my game as you’re saying it did yours. You can check out my thread on the matter here: https://github.com/tainicom/Aether.Physics2D/issues/61

Thank you!

Andrew

Happy to share! (With the caveat that my fork of Farseer has a bunch of other changes to it as well that I’ve made over many years and don’t remember very well, so isolating the broad-phase changes may or may not be easy.)

Send me an email and I’ll send you a zip of my Farseer code. (Unfortunately my Farseer code is part of my closed-source engine, so I don’t have a Git repo I can easily share with you.)

It was definitely tricky to get the broad-phase changes working, what with all the coordinate system conversions that need to happen with all the collisions and raycasts, but I think it’s working very well now. I’ve had this code live in my game for about half a year now with no reported issues, and the performance improvements for my particular game were enormous.

Hi,

is it possible to configure gravity dynamically? So that you have more gravity further down, for example, or that the bodies are not pulled in one direction, but to a point?

You can implement whatever effect you want by applying a force on bodies on each frame/step.
First you need to disable the build-in gravity. Set World.Gravity to [0;0] or Body.IgnoreGravity = true for individual bodies. Then iterate all bodies in World.BodyList and apply your own force.

See the SensorTest, GravityControllerTest, BuoyancyController and SimpleWindForce in TestBed app.

Aether.Physics2D v1.4

In this Release:

  • Clean up and document HelloWorld sample.
  • Two new tests, SparseBodiesTest and SparseBodiesWithManyFixturesTest.
  • Improved memory management.
  • Performance improvements.

Github:

Nuget:


4 Likes

Is it possible to add more collision categories to Aether Physics2D? 31 categories are not enough if you have more than 31 different types of objects/bodies in a game.

Rectangle.SetCollisionCategories(Category.Cat31);

If categories are not sufficient then you have to use the more flexible callbacks (like ContactManager.ContactFilter for example) and disable the new contacts.

Example:
At the beginning, the ball cannot collide with the ground and it can move through the ground, but when the two bodies are separating, then the ball can collide with the ground and the ball cannot move again through the ground.

How can I use AfterCollision?
I get this error message:

No overload for ‘Ball_AfterCollision’ matches delegate ‘AfterCollisionEventHandler’

        Body Ball, ground;

        ground = world.CreateEdge(new Vector2(-4.0f, 5.0f), new Vector2(20.0f, 5.0f));

        Ball = world.CreateCircle(0.25f, 1.0f);
        Ball.BodyType = BodyType.Dynamic;
        Ball.Position = new Vector2(10.4f, -1.0f);
        Ball.SetRestitution(0.3f);
        Ball.SetCollisionCategories(Category.Cat2);
        Ball.FixtureList[0].BeforeCollision = Ball_BeforeCollision;
        Ball.FixtureList[0].AfterCollision = Ball_AfterCollision;
    
    bool Ball_BeforeCollision(Fixture sender, Fixture other)
    {
        if (other == ground.FixtureList[0])
            return false;

        return true;
    }

    bool Ball_AfterCollision(Fixture sender, Fixture other)
    {
        if (other == ground.FixtureList[0])
            return true;

        return true;
    }