[Solved] "Update" Component fires change


#1

Hi,

first I want to say that I’m reading this forum for many years and I’m very excited to see all the great projects. I have made the mistake to start to ‘big’ (minecraft clone) so there is not really any progress to show…

Also I want to thank the community for their help and the devs for their great work on this engine. All questions so far were answered with this forum…

My Question:
I’m using the zay-es to implement a very basic physic engine.

I have read through all the docs and examples I found so far but I have still a conceptional question regarding zay-es.

For example. I have a system to set the new position of an object. Therefore I take the old position, the current velocity -> add the new calculated delta and set it to the entity.
(p1 = p0 + v * dT)

If the entity does not move in the next frame (velocity is 0) it will be marked as changed because the position has changed.

EntitySet set = entityData.getEntities(Position.class, Velocity.class);

Do I have to use two EntitySet sets to ‘listen’ only to velocity updates?


#2

What is it that you actually need to know for your game?

So what if position hasn’t moved? Why is this an issue?


#3

I want to keep my systems small. So I have one to apply forces, one to calculate an velocity vector and one for positions and so on.
The position system for example needs the velocity and the current position to calculate the new position. After the calculation the system will update the position component of the entity. The position system should only ‘listen’ to velocity updates because nobody else will change the position.
But it will recognize the position change because the position component is in my entity set.


#4

So it isn’t that the position hasn’t changed… it’s that you don’t care about the change because you already know it.

Basically, I would never do physics this way. (Most of the time, I don’t even have velocity as a component…)

But yeah, in your case you will have two entity sets I guess. One for objects with position (and whatever else makes them physical objects) and another one for velocities (and whatever else makes them physical objects).

I’m thinking they can’t just be position and velocity on their own… they must collide with something, etc… So it sounds like maybe you have a bunch of systems doing the job of one. Hard to tell from here.


#5

Thank you. It was a question on the concept by the example of the physics engine I’m implementing.

So maybe I’ve missed somthing but I want to get it right, sorry :sweat_smile:

After calling

changes = this.entitySet.applyChanges();

I use

Set<Entity> set = this.entitySet.getChangedEntities();

The set of changed entities always contains the entity because the position system will change the component of it. But when I use two sets I can only ‘listen’ to velocity changes.

I will go with this solution. Thank you again!

PositionSystem

public class PositionSystem extends DispatchedEntitySystem {

private final EntitySet entitySet2;

public PositionSystem(final EntityData entityData) {
	this.entitySet = entityData.getEntities(Velocity.class);
	this.entitySet2 = entityData.getEntities(Position.class);
}

@Override
public void addedEntites(final Set<Entity> set) {
	changedEntites(set);
}

@Override
public void changedEntites(final Set<Entity> set) {
    if (hasChanges()) {
		this.entitySet2.applyChanges();
	}
	for (Entity entity : set) {
		Vector3f v = entity.get(Velocity.class).getVelocity();
		if (epsilon(v)) {
			Entity e = this.entitySet2.getEntity(entity.getId());
			e.set(new Position(e.get(Position.class).getPosition().add(v.mult(Constants.dT))));
		}
	}
}

@Override
public void removedEntites(final Set<Entity> set) {
	// not used
}
}

DispatchedEntitySystem

public abstract class DispatchedEntitySystem extends EntitySystem {

public abstract void addedEntites(Set<Entity> set);

public abstract void changedEntites(Set<Entity> set);

public abstract void removedEntites(Set<Entity> set);

@Override
final void update(final float tpf) {
	addedEntites(this.entitySet.getAddedEntities());
	changedEntites(this.entitySet.getChangedEntities());
	removedEntites(this.entitySet.getRemovedEntities());
}
}

EntitySystem

public abstract class EntitySystem {
protected EntitySet entitySet;
private boolean hasChanges;

protected static final boolean epsilon(Vector3f vector) {
	return vector.lengthSquared() > 0.01f; // must be tested
}

public final void applyChanges(float tpf) {
	this.hasChanges = this.entitySet.applyChanges();
	update(tpf);
}

public EntitySet getEntitySet() {
	return this.entitySet;
}

public boolean hasChanges() {
	return this.hasChanges;
}

abstract void update(float tpf);
}

#6

Usually, a physics system will iterate over all entities with position and velocity every frame… regardless of if they’ve changed. That’s the part I find strange.

You will need to know when they come and go but otherwise all objects get updated every frame if that have position and velocity. You don’t need to worry about getChangedEntities().

My EntityContainer utility class can even provide direct array access to iterate so you don’t create extra garbage.