private void update(List<Entity> moved, ComponentMapper<Mass> mm, ComponentMapper<Position> pm) { if (hasEntity()) { if (entity.isActive()) { VectorD2 p = pm.get(entity).vec; if (!contains(p)) { moved.add(entity); --size; this.mass = 0f; this.massVector.set(0f, 0f); entity = null; } else { mass = mm.get(entity).mass; massVector.set(p).mul(mass); } } } else if (hasChildren()) { bl.update(moved, mm, pm); br.update(moved, mm, pm); tl.update(moved, mm, pm); tr.update(moved, mm, pm); size = bl.size + br.size + tl.size + tr.size; mass = bl.mass + br.mass + tl.mass + tr.mass; massVector.set(0f, 0f); massVector.add(bl.massVector).add(br.massVector); massVector.add(tl.massVector).add(tr.massVector); } }
/** Doesn't update mass and massVector. */ public boolean dirtyRemove( Entity entity, ComponentMapper<Mass> mm, ComponentMapper<Position> pm) { if (hasEntity()) { if (this.entity == entity) { this.entity = null; --size; return true; } } else if (hasChildren()) { GravQuadTree sub = quadrantOf(entity, mm, pm); if (sub.remove(entity, mm, pm)) { --size; } } return false; }
public void updateAcceleration( Entity e, float theta, float G, ComponentMapper<Mass> mm, ComponentMapper<Position> pm, ComponentMapper<Acceleration> am, float delta) { if (isEmpty()) { // TODO also check if M is to small? return; } double M = this.mass; VectorD2 p = pm.get(e).vec; VectorD2 diff; // if (contains(p)) { // TODO this is only necessary if theta>=1 // float m = mm.get(e).mass; // diff = this.massVector.cpy().sub(p.cpy().mul(m)).div(M-m).sub(p); // } else diff = this.massVector.cpy().div(M).sub(p); double d2 = diff.len2(); // s/d < theta if (this.entity != null || side * side < theta * theta * d2) { // TODO weight with mass. if (this.entity == e) { // TODO temporary hack return; } // F = G*m*M/d^2 // F = m*a // a = G*M/d^2 double a = G * M / d2; double k = (float) (a * FastMath.inverseSqrt(d2)); // normalizes diff if (!Double.isNaN(k)) { VectorD2 accVec = am.get(e).vec; accVec.add(diff.mul(k).mul(delta)); } } else { bl.updateAcceleration(e, theta, G, mm, pm, am, delta); br.updateAcceleration(e, theta, G, mm, pm, am, delta); tl.updateAcceleration(e, theta, G, mm, pm, am, delta); tr.updateAcceleration(e, theta, G, mm, pm, am, delta); } }
public boolean remove(Entity entity, ComponentMapper<Mass> mm, ComponentMapper<Position> pm) { if (hasEntity()) { if (this.entity == entity) { this.entity = null; mass = 0f; massVector.set(0f, 0f); --size; return true; } } else if (hasChildren()) { GravQuadTree sub = quadrantOf(entity, mm, pm); double oldMass = sub.mass; VectorD2 oldVector = sub.massVector.cpy(); if (sub.remove(entity, mm, pm)) { --size; mass -= oldMass - sub.mass; massVector.sub(oldVector).add(sub.massVector); } } return false; }