Collision filtering in Box2D: running out of bits

When I first used box2d I quickly reached the 16 bits limit 🙂

Then I found a solution: you don’t need to use all 16 bits, you need to categorize your objects.

For example, you have some grounds and solid platforms, you put them in the SOLID category.

You have many enemies, you put them in the ENEMY category.

An enemy is an enemy regardless of its abilities like size, speed… You will define those abilities upon created them. For example:

if g_currentlevel == 1 then
    Nme_Flyer.new(xworld, {
        posx=xobject.x, posy=xobject.y,
        texpath="gfx/playable/Bob.png",
        animspeed=14, movespeed=8*0.6, jumpspeed=8*0.5, maxnumjump=2,
        density=1, restitution=0.5, friction=0,
        BIT=G_BITENEMY, COLBIT=nmecollisions, NAME=G_ENEMY,
        lives=1, nrg=1,
    })
elseif g_currentlevel == 2 then
    Nme_Flyer.new(xworld, {
        ...
        density=2, restitution=1, friction=0,
        BIT=G_BITENEMY, COLBIT=nmecollisions, NAME=G_ENEMY,
        lives=1, nrg=4,
    })
end

My complete set up looks something like this (please note I am using Gideros framework, code is in Lua):

-- here we store all possible objects name -- NO LIMIT
G_GROUND = 2^0
G_MVPLATFORM = 2^1
G_PTPLATFORM = 2^2
G_PLAYER = 2^3
G_PLAYER_BULLET = 2^4
G_ENEMY = 2^5
G_ENEMY_BULLET = 2^6
...
G_LADDER = 2^56 -- ;-)

-- here we define some category BITS (that is those objects can collide) -- 2^15 = MAX
G_BITSOLID = 2^0
G_BITPTPF = 2^1
G_BITPLAYER = 2^2
G_BITPLAYERBULLET = 2^3
G_BITENEMY = 2^4
G_BITENEMYBULLET = 2^5
G_BITSENSOR = 2^6

-- here is another trick (what can collide with what)
solidcollisions = G_BITPLAYER + G_BITPLAYERBULLET + G_BITENEMY + G_BITENEMYBULLET
playercollisions = G_BITSOLID + G_BITPTPF + G_BITENEMY + G_BITENEMYBULLET + G_BITSENSOR
playerbulletcollisions = G_BITSOLID + G_BITENEMY + G_BITENEMYBULLET
nmecollisions = G_BITSOLID + G_BITPTPF + G_BITPLAYER + G_BITPLAYERBULLET + G_BITENEMY
nmebulletcollisions = G_BITSOLID + G_BITPLAYER + G_BITPLAYERBULLET

This way you won’t run out of bits 🙂

physics – Simulating a rocket out of control in Box2D

In the void of space, a spaceship releases a rectangle shaped space-torpedo. In half a second, it starts its rocket engine and goes straight until something get in its way, and then boom!
The code looks something like this on update():

if (Game::gameplay_timer_.milliseconds() - launch_time_ > thrust_time_) {
  body_->ApplyLinearImpulseToCenter(0.006f * body_->GetLinearVelocity(), true);
}

But, what if something disturbs the projectile before igniting the rocket, giving it some rotation? It should enter in an uncontrolled spiral (think KSP or tethered gas canisters in Just Cause 2).

How can I achieve this effect (spiraling uncontrollably)? I tried to apply the impulse in places other than the center using ApplyLinearImpulse(), but I can only make the projectile rotate on itself keeping the direction perfectly straight.

Creating “realistic” pixel perfect physcics rendering – C++ – Box2D and SDL2

Whats the best way to be rendering the locations of objects in box2D in such a way that there no stuttering on movement beyond 8-directions. I’m looking to have object strictly snap to the pixels but still keep objects moving smoothly without jittering.

every game loop iteration calls an Update() method on all GameObjects which rounds the objects position in the Physics world to a corresponding pixel coordinate and scaled up.

destRect.x = std::floor(getX() * scale);
destRect.y = std::floor(getY() * scale);

drawn to the screen afterward in GameObject::Draw()

SDL_RenderCopy(targetRenderer, objectTexture, &srcRect, &destRect);

this works fine and positions the object perfectly on the screen–too perfectly.

Moving straight in any direction is smooth and doesn’t stutter. I quickly wrote the following code to fix jittering on diagonals (45 degrees) by ensuring that each row/column has only one pixel drawn on it. This makes 8-way movement smooth.

if (IsMoving())
    {
        // Which direction is the object traveling
        float angleAbs = std::abs(GetAngleDegrees());
        if (angleAbs <= 135 && angleAbs >= 45)
        {
            CurrentCol = CurrentColY = NULL;
    
            // set y to floored object->x in scaled pixels
            destRect.y = std::floor(getY() * scale);
    
            // has this row been rendered to yet?
            if (CurrentRow == std::floor(getY()))
            {
                destRect.x = CurrentRowX;
            }
            else
            {
                CurrentRow = std::floor(getY());
                destRect.x = CurrentRowX = std::floor(getX() * scale);
            }
        }
        else
        {
            CurrentRow = CurrentRowX = NULL;
    
            // set y to floored object->x in scaled pixels
            destRect.x = std::floor(getX() * scale);
    
            // has this column been rendered to yet?
            if (CurrentCol == std::floor(getX()))
            {
                destRect.y = CurrentColY;
            }
            else
            {
                CurrentCol = std::floor(getX());
                destRect.y = CurrentColY = std::floor(getY() * scale);
            }
        }
    }
    else 
    {    
        // update any changes made to the coordinates
        destRect.x = std::floor(getX() * scale);
        destRect.y = std::floor(getY() * scale);
    }

This code tries to smooths out other angles that objects might move in (jumping forward, for, example, forms a parabola like shape) but doesn’t look smooth when speed up to normal frame rates. The motion doesn’t render seamlessly.

I think I’m rendering the locations of the objects almost too precisely, making the objects movement (ironically) pixelated and mechanical, but I’m lost on how to make pixel perfect motion on varied angles seem–or at lease give the illusion of–smooth “realistic” motion.

I’m looking for advice on how to approach this problem and find a working solution rather than make it work with my engine directly–all the same, the code for my game engine can be found on GitHub here if it helps.

box2d – testPoint not working – libgdx

The problem I see is you are dividing the screenX and screenY values by 100 here:

if(fixture.testPoint(screenX/100, (mapHeight-screenY)/100)) { //100 is scaled parameter

screenX and screenY are the values indicating the X and Y coordinates of your touch and by sending a modified value to your testPoint method you’re not testing with the right values.

I suggest you send the original values to your testPoint method like so:

fixture.testPoint(screenX, mapHeight - screenY)

A couple of tips:

  • If you need a dragging behaviour check the onDragged method
    instead of the touchDown one.
  • If you are using an OrthographicCamera for your game (which is recommended) you don’t have to worry about wrong screen coordinates since you unproject the values to the correct ones and you don’t even have to worry about the Y axis being reversed, here’s an example:
OrthographicCamera camera = new OrthographicCamera(gameWidth, gameHeight); // gameWidth and gameHeight can be any float you want

public boolean touchDown(int screenX, int screenY, int pointer, int button) {
Vector3 unprojected = camera.unproject(new Vector3(screenX, screenY, 0f));
float x = unprojected.x;
float y = unprojected.y;
    for(Fixture fixture:bird.getBody().getFixtureList()) {
        if(fixture.testPoint(x, y) {
             draggedBird = true;
             return true;
         }
    }
    return false;
}

box2d – What could effectively affect the falling speed of a b2Body?

I tried to set up a test demo to see if Box2D physics are working. It works, but I have one small problem: I cannot seem to get the dynamic b2Body to fall faster.

I tried modifying and setting the gravity and its gravityScale, its fixture, the density. I also tried applyForce and setLinearVelocity in a constant loop. I tried passing different values for the b2World.Step() function, by giving it different dt, velocityIterations and positionIterations. I know it has nothing to do with it, but I also tried modifying the mass of the body. By changing the gravity, I only managed to decrease its falling speed.

This is currently the falling speed.

I managed to find a way to increase the falling speed of the dynamic body, but only because I performed a b2World.Step() function multiple times per loop. I do not want to use that method to increase the falling speed.

This is the falling speed with multiple b2World.Step()-calls.

Do you have any suggestions what I could use to increase the falling speed of the dynamic body?

box2d – Way to check overlaps of a collider2d that’s not set to “is trigger” in Unity

I have a system where physics2d objects are spawned and I need to know when they spawn outside of a region defined by a box collider set to “is Trigger”.

Using onTriggerEnter and onTriggerExit to know if an object exits / re-enters the bounds (with some other conditions determining whether to kill the object when it exits the bounds). That stuff works fine.

However I can’t detect when an object spawns outside of the collider (which I want to allow, but just know when it happens).

I tried the following in the Start method of the spawned object:

List<Collider2D> results = new List<Collider2D>();
_boundsCollider.OverlapCollider(new ContactFilter2D(), results);
bool spawned_outside = !results.Contains(_thisCollider);

However at the time that method runs, the booundsCollider doesn’t register it. Subsequent frames it will, but that’s too late.

OverlapCollder can’t be run on the collider for the spawned object since it isn’t set as a trigger.

Is there any way I can query the spawned object’s own collider to determine if it is in contact with the bounds collider?

Thanks!

PS I can’t trivially just reference the coords of the object and check if they’re out of bounds because the bounds collider will move, and I want to know with precision wether just a corner is overlapping or whatever so I’d need something that amounts to my own simple collision system

java – libGDX box2D not setting user data

I am working about box2D.

Even if I set userData, when I retrieve it via getUserData(), it returns null. Using debugger, I noticed that object passed to setUserData() is not null, but on the next istruction: fixtureDef.shape.dispose();

Body user data returns being null, such as setUserData() set on a copy of body. I read on other topics that setUserData() must be called before body creation…but it throws an exception

      @Override
public void setPhysic(@Null Shape shape, BodyDef.BodyType bodyType, FixtureDef fixtureDef) {

    if(shape == null) {
        PolygonShape polygonShape = new PolygonShape();
        BoundingBox boundingBox = this.model.calculateBoundingBox(new BoundingBox());
        polygonShape.setAsBox(boundingBox.getWidth(), boundingBox.getHeight());
        fixtureDef.shape = polygonShape;
        fixtureDef.density = 1f;
    }else{
        fixtureDef.shape = shape;
    }

    BodyDef bodyDef = new BodyDef();
    bodyDef.type = bodyType;
    bodyDef.position.set(this.getPosition().x, this.getPosition().y);

    this.body = Game.world.createBody(bodyDef);
    this.body.setUserData(this); //<-- Add this line to fix the problem
    this.body.createFixture(fixtureDef).setUserData(this);

    fixtureDef.shape.dispose();
}

Here I get userData:

  if(body(0).getUserData() instanceof Block){
            if(button == Input.Buttons.RIGHT){
                ((Block)body(0).getUserData()).onBlockClicked(player);
            }else if(button == Input.Buttons.LEFT){
                player.onPlayerBlockDestroying((Block)body(0).getUserData(), mouseCords);
            }
        }

graphics – Libgdx and Box2D with android studio: Why isn’t the ball responding to touch inputs?

        public boolean isPointOnPlayer(float x, float y){
            for(Fixture fixture : BallBody.getFixtureList())
                if(fixture.testPoint(x, y)) return true;
            return false;
        }
    



    



    
    public class PlayerControl extends InputAdapter {
        
        private Vector3 _touchPosition;

        public PlayerControl(Camera camera, Body ballBody) {
            
            _touchPosition = new Vector3();
        }

        @Override
        public boolean touchDown(int screenX, int screenY, int pointer, int button) {
            // don't forget to unproject screen coordinates to game world


            camera.unproject(_touchPosition.set(screenX, screenY, 0F));
            if (isPointOnPlayer(_touchPosition.x, _touchPosition.y)) {
                // touch on the player body. Do some stuff like player jumping
                BallBody.applyForce(new Vector2(0, 100f),new Vector2(0, 10f),true);


                return true;

            } else
                return super.touchDown(screenX, screenY, pointer, button);
        }


    }



}

android – Box2d: High screen resolution / frequency causes high friction?

I’m using Cocos Creator with (built-in) box2d for physics.

Recently our game behaves weirdly on our new device Galaxy S20 Ultra 5G – which has screen size = 1440 x 3200 – frequency = 120Hz.

After stop pushing, all our physical bodies almost stop immediately like they has very high friction. No other device react that way.

Anyone experienced this issue can give me an advice?

c++ – Predicting trajectory of Box2D physics body using both: linear dumping and gravity

I would like to calculate position of physics body after some time because of predicting shots trajectory in my game.

I found some great answer here where Iter Ator provides equation to calculate actual velocity of body after time, provided time, starting velocity and linear dumping but no gravity. I was able to integrate this solution to get distance traveled in time equation. Problem is that this doesnt take gravity into account.

There is also this tutorial that has many information about predicting physics body trajectory but doesnt take linear dumping into account at all.

What I would love to have is combined single equation that covers both linear dumping AND gravity to predict Box2d physics body actual velocity/position but math is too hard for me :(.

Problem seems to be that physics body velocity is both accelerated by gravity and dumped at the same time.