[SOLVED] Zay-ES - combine filters on two fields

Hey

Any way to combine two filters?

I have a container with static bodies, by default filtered on the physics mass type. I’d like to also start filtering on position. Is this possible?

See my static body container below:

/**
 * Maps the appropriate entities to physics bodies.
 */
private class StaticContainer extends EntityContainer<SimpleBody> {
    
    //Filter for only static objects
    public StaticContainer(EntityData ed) {
        super(ed, staticFilter,
                Position.class, PhysicsMassType.class, PhysicsShape.class);
    }

    @Override
    protected SimpleBody[] getArray() {
        return super.getArray();
    }

    @Override
    protected SimpleBody addObject(Entity e) {
        /**
         * TODO: A Body flagged as a Bullet will be checked for tunneling
         * depending on the CCD setting in the world's Settings. Use this if
         * the body is a fast moving body, but be careful as this will incur
         * a performance hit.
         */

        //TODO: Have gravity state and warpstate listen for body creations instead of relying on same info that SimplePhysics relies on in their containers
        PhysicsShape ps = e.get(PhysicsShape.class);
        PhysicsMassType pmt = e.get(PhysicsMassType.class);
        Position pos = e.get(Position.class);

        // Right now only works for CoG-centered shapes                   
        SimpleBody newBody = createStatic(e.getId(), pmt.getTypeName(ed), ps.getFixture(), true);

        newBody.setPosition(pos);   //ES position: Not used anymore, since Dyn4j controls movement

        newBody.getTransform().setTranslation(pos.getLocation().x, pos.getLocation().y); //Dyn4j position
        newBody.getTransform().setRotation(pos.getRotation());

        newBody.setUserData(e.getId());

        newBody.setLinearDamping(0.3);
        //newBody.setAngularDamping(0);

        return newBody;
    }

    @Override
    protected void updateObject(SimpleBody object, Entity e) {
        // We don't support live-updating mass or shape right now
    }

    @Override
    protected void removeObject(SimpleBody object, Entity e) {
        removeBody(e.getId());
        world.removeBody(object);
    }
    
    private void updateFilter(OrFilter zoneFilter) {
        //This is where I want to dynamically update the filter
        this.setFilter(zoneFilter);
    }
}

The incoming filter is based solely on the Position field - but the static filter is based on the masstype-field.

Anyway to do this ?

And I can already see this heading in the “why dont you tell us what you are trying to achieve”, so heres my situation:

In my game, I add lots of static entities (“small”) - positioned up against each other, I want to filter these (they are entities, much like the SiO2 bullet integration) based on the players positions - it should still make sense given that players in this game will stick together (to fight) and physics updates outside of the immediate play area is probably not interesting.

The view is already filtered (on the client side). So I was thinking to alleviate the physics engine, i’d do the same on the server-side in the physics where I can see the cpu time being spent. Im guessing its because the broadphase still needs to be run.

Another step I also have in mind to alleviate the computations, is the combine the tiles into bigger ‘chunks’ of physics bodies. But it still makes sense to filter physics if possible.

Kind regards

The reason im digging into this is that my game (server side) is slowing down. Client runs at 60 fps, but server slows down the more entities I add - so I profiled and saw that cpu time is being spent in the physics (the more I add, the more it slows down)

I guess you use bullet for physics? Native or jbullet? I’m surprised if the broadphase is not trivially skipping your static objects, really.

For a variety of reasons, zay-es only allows you to filter on one component type at a time… that being said, every time so far that I’ve felt the need to filter on more than one component type, it was a sign of a design problem somewhere and I eventually cleaned it up and didn’t need the double-type filters.

For example, in this case it sounds like you are trying to expose something to the game objects that is really an optimization in the physics layer/system. Or at least use the game objects when you already have all of the data you need in your real physical objects.

…after all, I guess your physics system already knows about all of the static objects and how the map to entities (ie: what their additional attributes are). No reason to ask the ES for this information. If it were me, and I understand your question correctly, this is entirely an optimization thing inside the physics system. You probably don’t have to query the entities at all.

I’m using Dyn4j in an almost identical manner to the bullet integration in the SiO2 lib you made. Then I use those entities in entitycontainers (finding the right physics-information) in the Physics state, adding/removing to the Dyn4j world and running world.update() in the state-update method.

I’m not trying to expose anything really. I’m simply trying to limit the amount of objects in the physics-world to those surrounding the players. Much like how the cellId-filter (Sim-Eth-Es reference) based on the zone surrounding the player works on the view-side to limit how much data is transferred and viewed.

So I thought, why not use the Position filter on the already static object entity container, to limit which objects are in the physics engine (just like I did on the view-side)

I’d love to find some work around :slight_smile:

Which is only needed because you are trying to optimize something specific to your physics engine… which is already managing some interface to all of the objects and so could choose to add/remove them as needed based on focus, whatever. It’s not really a game state problem. It’s something specific to the management of the physics engine.

Keep two separate sets. Find the intersection between them all the time.

…that’s what Zay-ES would have to do internally anyway. Each component type is in its own ‘table’. The algebra necessary to do random AND and OR across multiple separate hashmaps is super complex. It would probably double the Zay-ES codebase just to support an “almost never used” requirement.

You get nothing for free here… so again I caution you to make sure this is really what need and not just “it felt convenient”. Because again, this is not a game state problem. It’s a “very super-specific optimization that is super specific to this very specific physics engine you happen to be using”. Some other physics engine might manage its space better already.

As far I know in Dyn4j you can deactivate objects. Why not have a system which does deactivate objects which are “outside” your playground? Or maybe a system which temporarily removes object from the physic, maybe you have a system which holds all your player, then you make a radius around them all and everything outside you deactivate for physics. I think that could work.
I’m not sure if I did understand your problem correctly.

You both understood it correctly. And the solution is obvious now that you point it out. This is what I come to the forums for - glaringly obvious solutions to problems I create myself

Thanks :slight_smile:

1 Like