From 5c8407198d873a4a26c20a1c957fea83dea9c530 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 28 Mar 2016 13:38:40 +0200 Subject: [PATCH 1/2] Enhanced Engine to make "fixing the physics step" and interpolating afterwards easier --- .../src/com/badlogic/ashley/core/Engine.java | 16 +++++++++ .../badlogic/ashley/core/SystemManager.java | 33 ++++++++++++++++--- .../ashley/systems/InterpolatingSystem.java | 6 ++++ .../ashley/systems/PhysicsSystem.java | 6 ++++ 4 files changed, 57 insertions(+), 4 deletions(-) create mode 100644 ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java create mode 100644 ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java diff --git a/ashley/src/com/badlogic/ashley/core/Engine.java b/ashley/src/com/badlogic/ashley/core/Engine.java index c195706e..80075691 100644 --- a/ashley/src/com/badlogic/ashley/core/Engine.java +++ b/ashley/src/com/badlogic/ashley/core/Engine.java @@ -20,6 +20,8 @@ import com.badlogic.ashley.core.SystemManager.SystemListener; import com.badlogic.ashley.signals.Listener; import com.badlogic.ashley.signals.Signal; +import com.badlogic.ashley.systems.InterpolatingSystem; +import com.badlogic.ashley.systems.PhysicsSystem; import com.badlogic.ashley.utils.ImmutableArray; /** @@ -189,6 +191,20 @@ public void update(float deltaTime){ updating = false; } } + + public void updatePhysics(float physicsStep) { + ImmutableArray systems = systemManager.getPhysicsSystems(); + for (PhysicsSystem system : systems) { + system.updatePhysics(physicsStep); + } + } + + public void interpolate(float delta, float physicsStep, float inAccumulator) { + ImmutableArray systems = systemManager.getInterpolatingSystems(); + for (InterpolatingSystem system : systems) { + system.interpolate(delta, physicsStep, inAccumulator); + } + } protected void addEntityInternal(Entity entity) { entity.componentAdded.add(componentAdded); diff --git a/ashley/src/com/badlogic/ashley/core/SystemManager.java b/ashley/src/com/badlogic/ashley/core/SystemManager.java index a41f514b..9f31339c 100644 --- a/ashley/src/com/badlogic/ashley/core/SystemManager.java +++ b/ashley/src/com/badlogic/ashley/core/SystemManager.java @@ -1,17 +1,21 @@ package com.badlogic.ashley.core; -import java.util.Comparator; - -import com.badlogic.ashley.signals.Listener; -import com.badlogic.ashley.signals.Signal; +import com.badlogic.ashley.systems.InterpolatingSystem; +import com.badlogic.ashley.systems.PhysicsSystem; import com.badlogic.ashley.utils.ImmutableArray; import com.badlogic.gdx.utils.Array; import com.badlogic.gdx.utils.ObjectMap; +import java.util.Comparator; + class SystemManager { private SystemComparator systemComparator = new SystemComparator(); private Array systems = new Array(false, 16); + private Array physicsSystems = new Array(false, 16); + private Array interpolatingSystems = new Array(false, 16); private ImmutableArray immutableSystems = new ImmutableArray(systems); + private ImmutableArray immutablePhysicsSystems = new ImmutableArray(physicsSystems); + private ImmutableArray immutableInterpolatingSystems = new ImmutableArray(interpolatingSystems); private ObjectMap, EntitySystem> systemsByClass = new ObjectMap, EntitySystem>(); private SystemListener listener; @@ -31,6 +35,13 @@ public void addSystem(EntitySystem system){ systemsByClass.put(systemType, system); systems.sort(systemComparator); listener.systemAdded(system); + + if (system instanceof PhysicsSystem) { + physicsSystems.add((PhysicsSystem) system); + } + if (system instanceof InterpolatingSystem) { + interpolatingSystems.add((InterpolatingSystem) system); + } } public void removeSystem(EntitySystem system){ @@ -38,6 +49,12 @@ public void removeSystem(EntitySystem system){ systemsByClass.remove(system.getClass()); listener.systemRemoved(system); } + if (system instanceof PhysicsSystem) { + physicsSystems.removeValue((PhysicsSystem) system, true); + } + if (system instanceof InterpolatingSystem) { + interpolatingSystems.removeValue((InterpolatingSystem) system, true); + } } @SuppressWarnings("unchecked") @@ -48,6 +65,14 @@ public T getSystem(Class systemType) { public ImmutableArray getSystems() { return immutableSystems; } + + public ImmutableArray getPhysicsSystems() { + return immutablePhysicsSystems; + } + + public ImmutableArray getInterpolatingSystems() { + return immutableInterpolatingSystems; + } private static class SystemComparator implements Comparator{ @Override diff --git a/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java new file mode 100644 index 00000000..672a2563 --- /dev/null +++ b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java @@ -0,0 +1,6 @@ +package com.badlogic.ashley.systems; + +public interface InterpolatingSystem { + + void interpolate(float delta, float physicsStep, float inAccumulator); +} diff --git a/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java new file mode 100644 index 00000000..0d39c5de --- /dev/null +++ b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java @@ -0,0 +1,6 @@ +package com.badlogic.ashley.systems; + +public interface PhysicsSystem { + + void updatePhysics(float physicsStep); +} From e6ad17c998e0ab4ec2440c58c14f2da32687f771 Mon Sep 17 00:00:00 2001 From: BuildTools Date: Mon, 28 Mar 2016 16:02:32 +0200 Subject: [PATCH 2/2] Added documentation to public methods --- ashley/src/com/badlogic/ashley/core/Engine.java | 11 +++++++++++ .../ashley/systems/InterpolatingSystem.java | 13 +++++++++++++ .../com/badlogic/ashley/systems/PhysicsSystem.java | 11 +++++++++++ 3 files changed, 35 insertions(+) diff --git a/ashley/src/com/badlogic/ashley/core/Engine.java b/ashley/src/com/badlogic/ashley/core/Engine.java index 80075691..af93a506 100644 --- a/ashley/src/com/badlogic/ashley/core/Engine.java +++ b/ashley/src/com/badlogic/ashley/core/Engine.java @@ -192,6 +192,10 @@ public void update(float deltaTime){ } } + /** + * Updates all registered {@link PhysicsSystem}s. Should be used according to http://gafferongames.com/game-physics/fix-your-timestep/ + * @param physicsStep the physics step to use in the simulation, not the delta time, should be constant + */ public void updatePhysics(float physicsStep) { ImmutableArray systems = systemManager.getPhysicsSystems(); for (PhysicsSystem system : systems) { @@ -199,6 +203,13 @@ public void updatePhysics(float physicsStep) { } } + /** + * Updates all registered {@link InterpolatingSystem}s. Should be used after a physics simulation with a fixed timestep, + * see http://gafferongames.com/game-physics/fix-your-timestep/ + * @param delta current delta time, sometimes necessary for some rendering + * @param physicsStep the physics step used in the simulation, should be constant + * @param inAccumulator what is left in the accumulator after performing possible physics step, should be < physicsStep + */ public void interpolate(float delta, float physicsStep, float inAccumulator) { ImmutableArray systems = systemManager.getInterpolatingSystems(); for (InterpolatingSystem system : systems) { diff --git a/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java index 672a2563..50933891 100644 --- a/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java +++ b/ashley/src/com/badlogic/ashley/systems/InterpolatingSystem.java @@ -1,6 +1,19 @@ package com.badlogic.ashley.systems; +import com.badlogic.ashley.core.Engine; +import com.badlogic.ashley.core.EntitySystem; + +/** + * An {@link EntitySystem} that is meant to reduce temporal aliasing when using a fixed timestep for physics + * See http://gafferongames.com/game-physics/fix-your-timestep/ for explanation. + */ public interface InterpolatingSystem { + /** + * Will be called when {@link Engine#interpolate(float, float, float)} is called. + * @param delta current delta time, sometimes necessary for some rendering + * @param physicsStep the physics step used in the simulation, should be constant + * @param inAccumulator what is left in the accumulator after performing possible physics step, should be < physicsStep + */ void interpolate(float delta, float physicsStep, float inAccumulator); } diff --git a/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java index 0d39c5de..296204bb 100644 --- a/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java +++ b/ashley/src/com/badlogic/ashley/systems/PhysicsSystem.java @@ -1,6 +1,17 @@ package com.badlogic.ashley.systems; +import com.badlogic.ashley.core.Engine; +import com.badlogic.ashley.core.EntitySystem; + +/** + * An {@link EntitySystem} that is meant for operations with a fixed timestep, like physics. + * See http://gafferongames.com/game-physics/fix-your-timestep/ for explanation. + */ public interface PhysicsSystem { + /** + * Will be called when {@link Engine#updatePhysics(float)} is called. + * @param physicsStep the physics step to use in the simulation, not the delta time, should be constant + */ void updatePhysics(float physicsStep); }