diff --git a/src/main/java/tonegod/emitter/ParticleEmitterNode.java b/src/main/java/tonegod/emitter/ParticleEmitterNode.java index 6e1d758..51ba0b7 100644 --- a/src/main/java/tonegod/emitter/ParticleEmitterNode.java +++ b/src/main/java/tonegod/emitter/ParticleEmitterNode.java @@ -1,8 +1,5 @@ package tonegod.emitter; -import static java.lang.Class.forName; -import static java.util.Objects.requireNonNull; -import static tonegod.emitter.material.ParticlesMaterial.PROP_TEXTURE; import com.jme3.animation.AnimChannel; import com.jme3.animation.AnimControl; import com.jme3.animation.LoopMode; @@ -36,6 +33,7 @@ import tonegod.emitter.EmitterMesh.DirectionType; import tonegod.emitter.geometry.EmitterShapeGeometry; import tonegod.emitter.geometry.ParticleGeometry; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.interpolation.Interpolation; import tonegod.emitter.material.ParticlesMaterial; @@ -45,6 +43,14 @@ import tonegod.emitter.shapes.TriangleEmitterShape; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; + +import static java.lang.Class.forName; +import static java.util.Objects.requireNonNull; +import static tonegod.emitter.material.ParticlesMaterial.PROP_TEXTURE; /** * The implementation of a {@link Node} to emit particles. @@ -54,6 +60,77 @@ @SuppressWarnings("WeakerAccess") public class ParticleEmitterNode extends Node implements JmeCloneable, Cloneable { + + public class InfluencerInstance implements JmeCloneable { + private int id = -1; + private InfluencerData dataSample; + private ParticleInfluencer influencer; + + private InfluencerInstance() { } + + public InfluencerInstance(ParticleInfluencer influencer, Class dataClass) { + if(dataClass != null) { + this.id = reservations++; + + try { + Constructor constructor = dataClass.getDeclaredConstructor(); + constructor.setAccessible(true); + this.dataSample = constructor.newInstance(); + } catch (IllegalAccessException | InstantiationException | NoSuchMethodException | InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + this.influencer = influencer; + } + + public int getId() { + return id; + } + + public ParticleInfluencer getInfluencer() { + return influencer; + } + + public boolean hasData() { + return id >= 0; + } + + public InfluencerData createData() { + return dataSample.create(); + } + + @Override + public boolean equals(Object o) { + if(o instanceof ParticleInfluencer) { + return o.equals(influencer); + } + + if (this == o) return true; + + if (o == null || getClass() != o.getClass()) return false; + + InfluencerInstance other = (InfluencerInstance) o; + + return this.influencer.equals(other.influencer); + } + + @Override + public int hashCode() { + return influencer.hashCode(); + } + + @Override + public Object jmeClone() { + try { return super.clone(); } catch (CloneNotSupportedException ex) { throw new RuntimeException(ex); } + } + + @Override + public void cloneFields(Cloner cloner, Object original) { + influencer = cloner.clone(influencer); + } + } + @NotNull private static final ParticleInfluencer[] EMPTY_INFLUENCERS = new ParticleInfluencer[0]; @@ -64,7 +141,8 @@ public class ParticleEmitterNode extends Node implements JmeCloneable, Cloneable * The Influencers. */ @NotNull - protected SafeArrayList influencers; + protected SafeArrayList influencerInstances; + private int reservations; /** * The flags of this emitter. @@ -449,7 +527,7 @@ public ParticleEmitterNode() { this.emissionPoint = EmissionPoint.CENTER; this.directionType = DirectionType.RANDOM; this.interpolation = Interpolation.LINEAR; - this.influencers = new SafeArrayList<>(ParticleInfluencer.class); + this.influencerInstances = new SafeArrayList<>(InfluencerInstance.class); this.particleDataMeshType = ParticleDataTriMesh.class; this.emitterShape = new EmitterMesh(); this.particleGeometry = new ParticleGeometry("Particle Geometry"); @@ -1337,13 +1415,10 @@ public int getMaxParticles() { */ public void addInfluencers(@NotNull final ParticleInfluencer... newInfluencers) { - final SafeArrayList influencers = getInfluencers(); - for (final ParticleInfluencer influencer : newInfluencers) { - influencers.add(influencer); + addInfluencer(influencer); } - requiresUpdate = true; } /** @@ -1352,7 +1427,26 @@ public void addInfluencers(@NotNull final ParticleInfluencer... newInfluencers) * @param influencer The particle influencer to add to the chain */ public void addInfluencer(@NotNull final ParticleInfluencer influencer) { - influencers.add(influencer); + Type type = influencer.getClass().getGenericSuperclass(); + + Class generic = null; + if(type instanceof ParameterizedType) { + generic = (Class) ((ParameterizedType) type).getActualTypeArguments()[0]; + } + +// Class generic = (Class) ((ParameterizedType)influencer.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; + + InfluencerInstance influencerInstance = new InfluencerInstance(influencer, generic); + influencerInstances.add(influencerInstance); + + if(isEmitterInitialized()) { + for(ParticleData particleData : particles) { + if(particleData.isActive()) { + particleData.initializeInfluencer(influencerInstance); + } + } + } + requiresUpdate = true; } @@ -1364,23 +1458,27 @@ public void addInfluencer(@NotNull final ParticleInfluencer influencer) { */ public void addInfluencer(@NotNull final ParticleInfluencer influencer, final int index) { - final SafeArrayList temp = new SafeArrayList<>(ParticleInfluencer.class); - final SafeArrayList influencers = getInfluencers(); + final SafeArrayList aux = new SafeArrayList<>(InfluencerInstance.class); + final SafeArrayList influencerInstances = getInfluencerInstances(); + + aux.addAll(influencerInstances); + + influencerInstances.clear(); for (int i = 0; i < index; i++) { - temp.add(influencers.get(i)); + influencerInstances.add(aux.get(i)); } - temp.add(influencer); + addInfluencer(influencer); - for (int i = index, length = this.influencers.size(); i < length; i++) { - temp.add(influencers.get(i)); + for (int i = index, length = this.influencerInstances.size(); i < length; i++) { + influencerInstances.add(aux.get(i)); } - influencers.clear(); - influencers.addAll(temp); +// influencers.clear(); +// influencers.addAll(temp); - requiresUpdate = true; +// requiresUpdate = true; } /** @@ -1389,7 +1487,7 @@ public void addInfluencer(@NotNull final ParticleInfluencer influencer, final in * @param influencer the influencer to remove. */ public void removeInfluencer(@NotNull final ParticleInfluencer influencer) { - influencers.remove(influencer); + influencerInstances.remove(influencer); requiresUpdate = true; } @@ -1398,10 +1496,22 @@ public void removeInfluencer(@NotNull final ParticleInfluencer influencer) { * * @return The Collection of particle influencers */ + @Deprecated public @NotNull SafeArrayList getInfluencers() { + + SafeArrayList influencers = new SafeArrayList<>(ParticleInfluencer.class); + + for(InfluencerInstance influencerInstance : influencerInstances.getArray()) { + influencers.add(influencerInstance.getInfluencer()); + } + return influencers; } + public @NotNull SafeArrayList getInfluencerInstances() { + return influencerInstances; + } + /** * Returns the first instance of a specified ParticleData Influencer type * @@ -1411,11 +1521,11 @@ public void removeInfluencer(@NotNull final ParticleInfluencer influencer) { */ public @Nullable T getInfluencer(@NotNull final Class type) { - final SafeArrayList influencers = getInfluencers(); + final SafeArrayList influencerInstances = getInfluencerInstances(); - for (final ParticleInfluencer influencer : influencers.getArray()) { - if (type.isInstance(influencer)) { - return type.cast(influencer); + for (final InfluencerInstance influencerInstance : influencerInstances.getArray()) { + if (type.isInstance(influencerInstance.influencer)) { + return type.cast(influencerInstance.influencer); } } @@ -1431,7 +1541,8 @@ public void removeInfluencer(@NotNull final ParticleInfluencer influencer) { public void removeInfluencer(@NotNull final Class type) { final T influencer = getInfluencer(type); if (influencer == null) return; - influencers.remove(influencer); + + influencerInstances.remove(influencer); requiresUpdate = true; } @@ -1439,7 +1550,7 @@ public void removeInfluencer(@NotNull final Class * Removes all influencers */ public void removeAllInfluencers() { - influencers.clear(); + influencerInstances.clear(); requiresUpdate = true; } @@ -1895,7 +2006,9 @@ public void updateLogicalState(final float tpf) { emittedTime += tpf; for (final ParticleData particleData : particles) { - if (particleData.isActive()) particleData.update(tpf); + if (particleData.isActive()) { + particleData.update(tpf); + } } currentInterval += (tpf <= targetInterval) ? tpf : targetInterval; @@ -2108,7 +2221,8 @@ public void write(@NotNull final JmeExporter exporter) throws IOException { final OutputCapsule capsule = exporter.getCapsule(this); - capsule.write(influencers.toArray(new ParticleInfluencer[influencers.size()]), "influencers", EMPTY_INFLUENCERS); + SafeArrayList influencers = getInfluencers(); + capsule.write(influencers.getArray(), "influencers", EMPTY_INFLUENCERS); capsule.write(enabled, "enabled", true); // EMITTER @@ -2168,9 +2282,9 @@ public void read(@NotNull final JmeImporter importer) throws IOException { attachChildAt(particleNode, particleIndex); final InputCapsule capsule = importer.getCapsule(this); - final Savable[] influencerses = capsule.readSavableArray("influencers", EMPTY_INFLUENCERS); + final Savable[] influencers = capsule.readSavableArray("influencers", EMPTY_INFLUENCERS); - for (final Savable influencer : influencerses) { + for (final Savable influencer : influencers) { addInfluencer((ParticleInfluencer) influencer); } @@ -2248,11 +2362,7 @@ public void read(@NotNull final JmeImporter importer) throws IOException { public void cloneFields(@NotNull final Cloner cloner, @NotNull final Object original) { super.cloneFields(cloner, original); - influencers = cloner.clone(influencers); - - for (int i = 0; i < influencers.size(); i++) { - influencers.set(i, cloner.clone(influencers.get(i))); - } + influencerInstances = cloner.clone(influencerInstances); emitterShape = cloner.clone(emitterShape); emitterShapeTestGeometry = null; diff --git a/src/main/java/tonegod/emitter/influencers/InfluencerData.java b/src/main/java/tonegod/emitter/influencers/InfluencerData.java new file mode 100644 index 0000000..50228f1 --- /dev/null +++ b/src/main/java/tonegod/emitter/influencers/InfluencerData.java @@ -0,0 +1,7 @@ +package tonegod.emitter.influencers; + +public interface InfluencerData { + + T create(); + +} diff --git a/src/main/java/tonegod/emitter/influencers/InterpolatedParticleInfluencer.java b/src/main/java/tonegod/emitter/influencers/InterpolatedParticleInfluencer.java index be26942..91b525d 100644 --- a/src/main/java/tonegod/emitter/influencers/InterpolatedParticleInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/InterpolatedParticleInfluencer.java @@ -9,7 +9,7 @@ * * @author JavaSaBr */ -public interface InterpolatedParticleInfluencer extends ParticleInfluencer { +public interface InterpolatedParticleInfluencer extends ParticleInfluencer { /** * Get the count of interpolation steps. diff --git a/src/main/java/tonegod/emitter/influencers/ParticleInfluencer.java b/src/main/java/tonegod/emitter/influencers/ParticleInfluencer.java index 60e9767..37705e9 100644 --- a/src/main/java/tonegod/emitter/influencers/ParticleInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/ParticleInfluencer.java @@ -11,7 +11,7 @@ * * @author t0neg0d, JavaSaBr */ -public interface ParticleInfluencer extends Savable, Cloneable { +public interface ParticleInfluencer extends Savable, Cloneable { /** * Gets name. @@ -33,14 +33,14 @@ public interface ParticleInfluencer extends Savable, Cloneable { * @param particleData The particle to update * @param tpf The time since last frame */ - void update(@NotNull ParticleData particleData, float tpf); + void update(@NotNull ParticleData particleData, T influencerData, float tpf); /** * Called when a particle is emitted. * * @param particleData The particle being emitted */ - void initialize(@NotNull ParticleData particleData); + void initialize(@NotNull ParticleData particleData, T influencerData); /** * Called once the life span of the particle has been reached. diff --git a/src/main/java/tonegod/emitter/influencers/impl/AbstractInterpolatedParticleInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/AbstractInterpolatedParticleInfluencer.java index 9bb264a..7991455 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/AbstractInterpolatedParticleInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/AbstractInterpolatedParticleInfluencer.java @@ -6,6 +6,7 @@ import com.jme3.export.OutputCapsule; import com.jme3.util.SafeArrayList; import org.jetbrains.annotations.NotNull; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.InterpolatedParticleInfluencer; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.interpolation.Interpolation; @@ -13,51 +14,13 @@ import java.io.IOException; import java.util.List; -import java.util.concurrent.Callable; /** * The base implementation of the {@link InterpolatedParticleInfluencer}. * * @author JavaSaBr */ -public abstract class AbstractInterpolatedParticleInfluencer extends AbstractParticleInfluencer implements InterpolatedParticleInfluencer { - - @NotNull - protected static final Callable DATA_FACTORY = new Callable() { - @Override - public BaseInterpolationData call() throws Exception { - return new BaseInterpolationData(); - } - }; - - protected static class BaseInterpolationData { - - /** - * The interpolation. - */ - @NotNull - Interpolation interpolation; - - /** - * The index. - */ - int index; - - /** - * The interval. - */ - float interval; - - /** - * The duration. - */ - float duration; - - protected BaseInterpolationData() { - this.duration = 1f; - this.interpolation = Interpolation.LINEAR; - } - } +public abstract class AbstractInterpolatedParticleInfluencer extends AbstractParticleInfluencer implements InterpolatedParticleInfluencer { /** * The list of interpolations. diff --git a/src/main/java/tonegod/emitter/influencers/impl/AbstractParticleInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/AbstractParticleInfluencer.java index 2b9d5ed..93e62de 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/AbstractParticleInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/AbstractParticleInfluencer.java @@ -5,6 +5,7 @@ import com.jme3.export.JmeImporter; import com.jme3.export.OutputCapsule; import org.jetbrains.annotations.NotNull; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.particle.ParticleData; @@ -15,7 +16,7 @@ * * @author JavaSaBr */ -public abstract class AbstractParticleInfluencer implements ParticleInfluencer { +public abstract class AbstractParticleInfluencer implements ParticleInfluencer { /** * The flag of enabling this influencer. @@ -36,14 +37,14 @@ public void reset(@NotNull final ParticleData particleData) { } @Override - public void initialize(@NotNull final ParticleData particleData) { + public void initialize(@NotNull final ParticleData particleData, final T influencerData) { if (!isInitialized()) { firstInitializeImpl(particleData); setInitialized(true); } - initializeImpl(particleData); + initializeImpl(particleData, influencerData); } /** @@ -58,14 +59,15 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { * Handle initializing this influencer. * * @param particleData the particle data + * @param influencerData */ - protected void initializeImpl(@NotNull final ParticleData particleData) { + protected void initializeImpl(@NotNull final ParticleData particleData, T influencerData) { } @Override - public void update(@NotNull final ParticleData particleData, final float tpf) { + public void update(@NotNull final ParticleData particleData, final T influencerData, final float tpf) { if (!isEnabled()) return; - updateImpl(particleData, tpf); + updateImpl(particleData, influencerData, tpf); } /** @@ -74,7 +76,7 @@ public void update(@NotNull final ParticleData particleData, final float tpf) { * @param particleData the particle data * @param tpf the tpf */ - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, final T influencerData, final float tpf) { } diff --git a/src/main/java/tonegod/emitter/influencers/impl/AlphaInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/AlphaInfluencer.java index 8c35677..c400f5b 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/AlphaInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/AlphaInfluencer.java @@ -1,6 +1,5 @@ package tonegod.emitter.influencers.impl; -import static com.jme3.math.FastMath.interpolateLinear; import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; @@ -15,14 +14,14 @@ import java.io.IOException; +import static com.jme3.math.FastMath.interpolateLinear; + /** * The implementation of the {@link ParticleInfluencer} to change alpha of particles. * * @author t0neg0d, JavaSaBr */ -public final class AlphaInfluencer extends AbstractInterpolatedParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public final class AlphaInfluencer extends AbstractInterpolatedParticleInfluencer { /** * The list of alphas. @@ -51,9 +50,7 @@ public AlphaInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { - - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); + protected void updateImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data, final float tpf) { data.interval += tpf; if (data.index >= alphas.size()) { @@ -82,7 +79,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float particleData.alpha = interpolateLinear(blend, startAlpha, endAlpha); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } @Override @@ -101,10 +98,7 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); - - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); + protected void initializeImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data) { final SafeArrayList interpolations = getInterpolations(); if (isRandomStartAlpha()) { @@ -120,7 +114,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { data.interpolation = interpolations.get(data.index); - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/BaseInterpolationData.java b/src/main/java/tonegod/emitter/influencers/impl/BaseInterpolationData.java new file mode 100644 index 0000000..a89ea3a --- /dev/null +++ b/src/main/java/tonegod/emitter/influencers/impl/BaseInterpolationData.java @@ -0,0 +1,37 @@ +package tonegod.emitter.influencers.impl; + +import org.jetbrains.annotations.NotNull; +import tonegod.emitter.influencers.InfluencerData; +import tonegod.emitter.interpolation.Interpolation; + +public class BaseInterpolationData implements InfluencerData { + /** + * The interpolation. + */ + @NotNull Interpolation interpolation; + + /** + * The index. + */ + int index; + + /** + * The interval. + */ + float interval; + + /** + * The duration. + */ + float duration; + + protected BaseInterpolationData() { + this.duration = 1f; + this.interpolation = Interpolation.LINEAR; + } + + @Override + public BaseInterpolationData create() { + return new BaseInterpolationData(); + } +} \ No newline at end of file diff --git a/src/main/java/tonegod/emitter/influencers/impl/ColorInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/ColorInfluencer.java index b408c6e..f1873b7 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/ColorInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/ColorInfluencer.java @@ -1,6 +1,5 @@ package tonegod.emitter.influencers.impl; -import static com.jme3.math.FastMath.nextRandomInt; import com.jme3.export.*; import com.jme3.math.ColorRGBA; import com.jme3.util.SafeArrayList; @@ -12,14 +11,14 @@ import java.io.IOException; +import static com.jme3.math.FastMath.nextRandomInt; + /** * The implementation of the {@link ParticleInfluencer} to change color of particles. * * @author t0neg0d, JavaSaBr */ -public final class ColorInfluencer extends AbstractInterpolatedParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public final class ColorInfluencer extends AbstractInterpolatedParticleInfluencer { /** * The list of colors. @@ -63,9 +62,7 @@ public ColorInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { - - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); + protected void updateImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data, final float tpf) { data.interval += tpf; if (data.index >= colors.size()) { @@ -91,7 +88,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float particleData.color.interpolateLocal(startColor, endColor, blend); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } @Override @@ -110,11 +107,8 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); - + protected void initializeImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data) { final SafeArrayList interpolations = getInterpolations(); - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); if (isRandomStartColor()) { data.index = nextRandomInt(0, colors.size() - 1); @@ -128,7 +122,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { particleData.color.set(colors.get(data.index)); - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } @Override diff --git a/src/main/java/tonegod/emitter/influencers/impl/ConditionInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/ConditionInfluencer.java new file mode 100644 index 0000000..1a19757 --- /dev/null +++ b/src/main/java/tonegod/emitter/influencers/impl/ConditionInfluencer.java @@ -0,0 +1,74 @@ +package tonegod.emitter.influencers.impl; + +import org.jetbrains.annotations.NotNull; +import tonegod.emitter.influencers.InfluencerData; +import tonegod.emitter.influencers.ParticleInfluencer; +import tonegod.emitter.particle.ParticleData; + +public class ConditionInfluencer extends DelegatorInfluencer { + + public static class ConditionData implements InfluencerData> { + public T data; + + @Override + public ConditionData create() { + return new ConditionData<>(); + } + } + + public interface InfluencerCondition { + + void initialize(ParticleData particleData, ConditionData influencerData); + + /** + * + * @return true if the condition is met + */ + boolean update(ParticleData particleData, ConditionData influencerData, float tpf); + } + + + private InfluencerCondition condition; + + public ConditionInfluencer() { + } + + public ConditionInfluencer(ParticleInfluencer particleInfluencer, InfluencerCondition condition) { + super(particleInfluencer); + + this.condition = condition; + } + + public InfluencerCondition getCondition() { + return condition; + } + + public void setCondition(InfluencerCondition condition) { + this.condition = condition; + } + + @Override + protected void firstInitializeImpl(@NotNull ParticleData particleData) { + super.firstInitializeImpl(particleData); + + particleInfluencer.setEnabled(false); + } + + @Override + protected void initializeImpl(@NotNull ParticleData particleData, ConditionData influencerData) { + super.initializeImpl(particleData, influencerData); + + condition.initialize(particleData, influencerData); + } + + @Override + protected void updateImpl(@NotNull ParticleData particleData, final ConditionData influencerData, float tpf) { + // This is relying in the fact that influencers are being called in order for every particle. + particleInfluencer.setEnabled(condition.update(particleData, influencerData, tpf)); + } + + @Override + public @NotNull String getName() { + return ConditionInfluencer.class.getSimpleName(); + } +} diff --git a/src/main/java/tonegod/emitter/influencers/impl/DelegatorInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/DelegatorInfluencer.java new file mode 100644 index 0000000..149bba2 --- /dev/null +++ b/src/main/java/tonegod/emitter/influencers/impl/DelegatorInfluencer.java @@ -0,0 +1,33 @@ +package tonegod.emitter.influencers.impl; + +import org.jetbrains.annotations.NotNull; +import tonegod.emitter.influencers.InfluencerData; +import tonegod.emitter.influencers.ParticleInfluencer; +import tonegod.emitter.particle.ParticleData; + +public abstract class DelegatorInfluencer extends AbstractParticleInfluencer { + + protected ParticleInfluencer particleInfluencer; + + public DelegatorInfluencer() { + } + + public DelegatorInfluencer(ParticleInfluencer particleInfluencer) { + this.particleInfluencer = particleInfluencer; + } + + public ParticleInfluencer getParticleInfluencer() { + return particleInfluencer; + } + + public void setParticleInfluencer(ParticleInfluencer particleInfluencer) { + this.particleInfluencer = particleInfluencer; + } + + @Override + protected void firstInitializeImpl(@NotNull ParticleData particleData) { + super.firstInitializeImpl(particleData); + + particleData.getEmitterNode().addInfluencer(particleInfluencer); + } +} diff --git a/src/main/java/tonegod/emitter/influencers/impl/DestinationInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/DestinationInfluencer.java index 4b657c1..066e65c 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/DestinationInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/DestinationInfluencer.java @@ -1,7 +1,5 @@ package tonegod.emitter.influencers.impl; -import static tonegod.emitter.util.RandomUtils.getRandom; -import static tonegod.emitter.util.RandomUtils.nextRandomInt; import com.jme3.export.*; import com.jme3.math.Vector3f; import com.jme3.util.SafeArrayList; @@ -13,14 +11,15 @@ import java.io.IOException; +import static tonegod.emitter.util.RandomUtils.getRandom; +import static tonegod.emitter.util.RandomUtils.nextRandomInt; + /** * The implementation of the {@link ParticleInfluencer} to change destinations of particles. * * @author t0neg0d, JavaSaBr */ -public class DestinationInfluencer extends AbstractInterpolatedParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public class DestinationInfluencer extends AbstractInterpolatedParticleInfluencer { /** * The list of destinations. @@ -63,9 +62,7 @@ public DestinationInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { - - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); + protected void updateImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data, final float tpf) { data.interval += tpf; if (data.index >= destinations.size()) { @@ -107,11 +104,7 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); - - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); - + protected void initializeImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data) { if (isRandomStartDestination()) { data.index = nextRandomInt(getRandom(), 0, destinations.size() - 1); } else { diff --git a/src/main/java/tonegod/emitter/influencers/impl/GravityInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/GravityInfluencer.java index 9c6f9f2..cb0d3c8 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/GravityInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/GravityInfluencer.java @@ -9,6 +9,7 @@ import tonegod.emitter.EmitterMesh; import tonegod.emitter.Messages; import tonegod.emitter.ParticleEmitterNode; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.particle.ParticleData; @@ -108,18 +109,18 @@ public GravityInfluencer() { } @Override - public void update(@NotNull final ParticleData particleData, final float tpf) { + public void update(@NotNull final ParticleData particleData, final InfluencerData data, final float tpf) { final ParticleEmitterNode emitterNode = particleData.getEmitterNode(); if (emitterNode.isStaticParticles()) { return; } - super.update(particleData, tpf); + super.update(particleData, data, tpf); } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, final InfluencerData data, final float tpf) { final Vector3f velocity = particleData.getVelocity(); final Vector3f store = getStore(); @@ -169,11 +170,11 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float } } - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { + protected void initializeImpl(@NotNull final ParticleData particleData, final InfluencerData data) { store.set(particleData.getVelocity()) .negateLocal() @@ -181,7 +182,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { particleData.reverseVelocity.set(store); - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/ImpulseInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/ImpulseInfluencer.java index bb0e57e..affcea3 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/ImpulseInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/ImpulseInfluencer.java @@ -7,6 +7,7 @@ import com.jme3.math.Vector3f; import org.jetbrains.annotations.NotNull; import tonegod.emitter.Messages; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.particle.ParticleData; import tonegod.emitter.util.RandomUtils; @@ -62,7 +63,7 @@ public ImpulseInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, final InfluencerData data, final float tpf) { final Random random = RandomUtils.getRandom(); if (random.nextFloat() <= 1 - (chance + tpf)) { @@ -84,7 +85,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float particleData.velocity.interpolateLocal(velocityStore, magnitude); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/PhysicsInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/PhysicsInfluencer.java index d942f23..f5ea45e 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/PhysicsInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/PhysicsInfluencer.java @@ -18,6 +18,7 @@ import org.jetbrains.annotations.Nullable; import tonegod.emitter.Messages; import tonegod.emitter.ParticleEmitterNode; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.particle.ParticleData; @@ -29,9 +30,7 @@ * * @author t0neg0d, JavaSaBr */ -public class PhysicsInfluencer extends AbstractParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public class PhysicsInfluencer extends AbstractParticleInfluencer { @NotNull protected static final Callable DATA_FACTORY = new Callable() { @@ -41,7 +40,7 @@ public PhysicsInfluencerData call() throws Exception { } }; - protected static class PhysicsInfluencerData { + protected static class PhysicsInfluencerData implements InfluencerData { /** * The flag. @@ -55,6 +54,11 @@ protected static class PhysicsInfluencerData { private PhysicsInfluencerData() { } + + @Override + public PhysicsInfluencerData create() { + return new PhysicsInfluencerData(); + } } /** @@ -230,12 +234,10 @@ public PhysicsInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { - - final PhysicsInfluencerData data = particleData.getObjectData(DATA_ID); + protected void updateImpl(@NotNull final ParticleData particleData, final PhysicsInfluencerData data, final float tpf) { if (!data.collision) { - findCollisions(particleData, tpf); + findCollisions(particleData, data, tpf); } else { data.interval += tpf; if (data.interval >= collisionThreshold) { @@ -244,7 +246,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float } } - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** @@ -262,9 +264,8 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float * @param particleData the particle data. * @param tpf the tpf. */ - private void findCollisions(final @NotNull ParticleData particleData, final float tpf) { + private void findCollisions(final @NotNull ParticleData particleData, final PhysicsInfluencerData data, final float tpf) { - final PhysicsInfluencerData data = particleData.getObjectData(DATA_ID); final CollisionReaction collisionReaction = getCollisionReaction(); final ParticleEmitterNode emitterNode = particleData.getEmitterNode(); final GeometryList geometries = getGeometries(); @@ -325,14 +326,11 @@ private void findCollisions(final @NotNull ParticleData particleData, final floa } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); - - final PhysicsInfluencerData data = particleData.getObjectData(DATA_ID); + protected void initializeImpl(@NotNull final ParticleData particleData, final PhysicsInfluencerData data) { data.collision = false; data.interval = 0; - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/RadialVelocityInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/RadialVelocityInfluencer.java index 69a6cc1..e3f5149 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/RadialVelocityInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/RadialVelocityInfluencer.java @@ -10,6 +10,7 @@ import tonegod.emitter.EmitterMesh; import tonegod.emitter.Messages; import tonegod.emitter.ParticleEmitterNode; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.influencers.ParticleInfluencer; import tonegod.emitter.particle.ParticleData; import tonegod.emitter.util.RandomUtils; @@ -22,9 +23,16 @@ * * @author t0neg0d, JavaSaBr */ -public class RadialVelocityInfluencer extends AbstractParticleInfluencer { +public class RadialVelocityInfluencer extends AbstractParticleInfluencer { - private static final int TANGENT_FORCE_ID = ParticleData.reserveFloatDataId(); + protected static class RadialInfluencerData implements InfluencerData { + float tangentForce; + + @Override + public RadialInfluencerData create() { + return new RadialInfluencerData(); + } + } /** * The list of radial pull alignments. @@ -252,7 +260,7 @@ public RadialVelocityInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, final RadialInfluencerData data, final float tpf) { final ParticleEmitterNode emitterNode = particleData.getEmitterNode(); final EmitterMesh emitterShape = emitterNode.getEmitterShape(); @@ -278,13 +286,13 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float tangent.set(store) .crossLocal(left) .normalizeLocal() - .multLocal(particleData.getFloatData(TANGENT_FORCE_ID)) + .multLocal(data.tangentForce) .multLocal(tpf); particleData.velocity.subtractLocal(tangent); particleData.velocity.addLocal(store.mult(radialPull, tempStore)); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** @@ -366,22 +374,18 @@ private void processPullAlignment(@NotNull final ParticleData particleData, } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { + protected void initializeImpl(@NotNull final ParticleData particleData, final RadialInfluencerData data) { if (!isRandomDirection()) { - particleData.initializeFloatData(TANGENT_FORCE_ID, tangentForce); + data.tangentForce = tangentForce; return; } final Random random = RandomUtils.getRandom(); - if (random.nextBoolean()) { - particleData.initializeFloatData(TANGENT_FORCE_ID, tangentForce); - } else { - particleData.initializeFloatData(TANGENT_FORCE_ID, -tangentForce); - } + data.tangentForce = random.nextBoolean() ? tangentForce : -tangentForce; - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/RotationInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/RotationInfluencer.java index 3165cb1..151fa71 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/RotationInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/RotationInfluencer.java @@ -20,9 +20,7 @@ * * @author t0neg0d, JavaSaBr */ -public final class RotationInfluencer extends AbstractInterpolatedParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public final class RotationInfluencer extends AbstractInterpolatedParticleInfluencer { @NotNull protected static final Callable DATA_FACTORY = new Callable() { @@ -73,6 +71,11 @@ private RotationInfluencerData() { this.rotateDirectionY = true; this.rotateDirectionZ = true; } + + @Override + public RotationInfluencerData create() { + return new RotationInfluencerData(); + } } /** @@ -138,9 +141,7 @@ public RotationInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { - - final RotationInfluencerData data = particleData.getObjectData(DATA_ID); + protected void updateImpl(@NotNull final ParticleData particleData, final RotationInfluencerData data, final float tpf) { final Vector3f rotationSpeed = data.speed; if (speeds.size() > 1) { @@ -167,7 +168,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float particleData.angles.addLocal(rotationSpeed.mult(tpf, store)); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** @@ -214,10 +215,7 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); - - final RotationInfluencerData data = particleData.getObjectData(DATA_ID); + protected void initializeImpl(@NotNull final ParticleData particleData, final RotationInfluencerData data) { data.index = 0; data.interval = 0f; data.duration = isCycle() ? getFixedDuration() : particleData.startLife / ((float) speeds.size() - 1); @@ -246,7 +244,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { particleData.angles.set(0, 0, 0); } - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/SizeInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/SizeInfluencer.java index 2210d6d..7785014 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/SizeInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/SizeInfluencer.java @@ -12,24 +12,13 @@ import java.io.IOException; import java.util.Random; -import java.util.concurrent.Callable; /** * The implementation of the {@link ParticleInfluencer} to change size of particles. * * @author t0neg0d, JavaSaBr */ -public final class SizeInfluencer extends AbstractInterpolatedParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); - - @NotNull - protected static final Callable DATA_FACTORY = new Callable() { - @Override - public SizeInfluencerData call() throws Exception { - return new SizeInfluencerData(); - } - }; +public final class SizeInfluencer extends AbstractInterpolatedParticleInfluencer { protected static class SizeInfluencerData extends BaseInterpolationData { @@ -49,6 +38,11 @@ private SizeInfluencerData() { this.startSize = new Vector3f(1, 1, 1); this.endSize = new Vector3f(0, 0, 0); } + + @Override + public SizeInfluencerData create() { + return new SizeInfluencerData(); + } } /** @@ -88,9 +82,8 @@ public SizeInfluencer() { } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, SizeInfluencerData data, final float tpf) { - final SizeInfluencerData data = particleData.getObjectData(DATA_ID); data.interval += tpf; if (data.index >= sizes.size()) { @@ -106,7 +99,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float blend = interpolation.apply(data.interval / data.duration); particleData.size.interpolateLocal(data.startSize, data.endSize, blend); - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** @@ -145,11 +138,9 @@ protected void firstInitializeImpl(@NotNull final ParticleData particleData) { } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); + protected void initializeImpl(@NotNull final ParticleData particleData, SizeInfluencerData data) { final SafeArrayList interpolations = getInterpolations(); - final SizeInfluencerData data = particleData.getObjectData(DATA_ID); data.index = 0; data.interval = 0F; data.duration = isCycle() ? getFixedDuration() : @@ -159,7 +150,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { data.interpolation = interpolations.get(data.index); - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/SpriteInfluencer.java b/src/main/java/tonegod/emitter/influencers/impl/SpriteInfluencer.java index 42e1f45..6a333fe 100644 --- a/src/main/java/tonegod/emitter/influencers/impl/SpriteInfluencer.java +++ b/src/main/java/tonegod/emitter/influencers/impl/SpriteInfluencer.java @@ -1,6 +1,5 @@ package tonegod.emitter.influencers.impl; -import static tonegod.emitter.influencers.impl.AbstractInterpolatedParticleInfluencer.DATA_FACTORY; import com.jme3.export.InputCapsule; import com.jme3.export.JmeExporter; import com.jme3.export.JmeImporter; @@ -11,7 +10,6 @@ import tonegod.emitter.Messages; import tonegod.emitter.ParticleEmitterNode; import tonegod.emitter.influencers.ParticleInfluencer; -import tonegod.emitter.influencers.impl.AbstractInterpolatedParticleInfluencer.BaseInterpolationData; import tonegod.emitter.particle.ParticleData; import java.io.IOException; @@ -21,9 +19,7 @@ * * @author t0neg0d, JavaSaBr */ -public class SpriteInfluencer extends AbstractParticleInfluencer { - - private static final int DATA_ID = ParticleData.reserveObjectDataId(); +public class SpriteInfluencer extends AbstractParticleInfluencer { private transient float targetInterval; @@ -70,19 +66,18 @@ public SpriteInfluencer() { } @Override - public void update(@NotNull final ParticleData particleData, final float tpf) { + public void update(@NotNull final ParticleData particleData, final BaseInterpolationData data, final float tpf) { if (!isAnimate()) { return; } - super.update(particleData, tpf); + super.update(particleData, data, tpf); } @Override - protected void updateImpl(@NotNull final ParticleData particleData, final float tpf) { + protected void updateImpl(@NotNull final ParticleData particleData, final BaseInterpolationData data, final float tpf) { - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); data.interval += tpf; targetInterval = isCycle() ? (fixedDuration / 100F) : data.duration; @@ -91,7 +86,7 @@ protected void updateImpl(@NotNull final ParticleData particleData, final float updateFrame(data, particleData); } - super.updateImpl(particleData, tpf); + super.updateImpl(particleData, data, tpf); } /** @@ -135,11 +130,9 @@ private void updateFrame(@NotNull final BaseInterpolationData data, @NotNull fin } @Override - protected void initializeImpl(@NotNull final ParticleData particleData) { - particleData.initializeObjectData(DATA_ID, DATA_FACTORY); + protected void initializeImpl(@NotNull final ParticleData particleData, BaseInterpolationData data) { final ParticleEmitterNode emitterNode = particleData.getEmitterNode(); - final BaseInterpolationData data = particleData.getObjectData(DATA_ID); final int spriteRowCount = emitterNode.getSpriteRowCount(); final int spriteColCount = emitterNode.getSpriteColCount(); @@ -189,7 +182,7 @@ protected void initializeImpl(@NotNull final ParticleData particleData) { data.duration = particleData.startLife / (float) frameSequence.length; } - super.initializeImpl(particleData); + super.initializeImpl(particleData, data); } /** diff --git a/src/main/java/tonegod/emitter/influencers/impl/condition/TimeCondition.java b/src/main/java/tonegod/emitter/influencers/impl/condition/TimeCondition.java new file mode 100644 index 0000000..bf484fa --- /dev/null +++ b/src/main/java/tonegod/emitter/influencers/impl/condition/TimeCondition.java @@ -0,0 +1,34 @@ +package tonegod.emitter.influencers.impl.condition; + +import tonegod.emitter.influencers.impl.ConditionInfluencer; +import tonegod.emitter.influencers.impl.ConditionInfluencer.ConditionData; +import tonegod.emitter.particle.ParticleData; + +public class TimeCondition implements ConditionInfluencer.InfluencerCondition { + + private float time; + + public TimeCondition() { } + + public TimeCondition(float time) { + this.time = time; + } + + public float getTime() { + return time; + } + + public void setTime(float time) { + this.time = time; + } + + @Override + public void initialize(ParticleData particleData, ConditionData influencerData) { + influencerData.data = 0f; + } + + @Override + public boolean update(ParticleData particleData, ConditionData influencerData, float tpf) { + return (influencerData.data += tpf) >= time; + } +} diff --git a/src/main/java/tonegod/emitter/particle/ParticleData.java b/src/main/java/tonegod/emitter/particle/ParticleData.java index 95d64a8..838a5ad 100644 --- a/src/main/java/tonegod/emitter/particle/ParticleData.java +++ b/src/main/java/tonegod/emitter/particle/ParticleData.java @@ -1,6 +1,5 @@ package tonegod.emitter.particle; -import static java.util.Objects.requireNonNull; import com.jme3.math.ColorRGBA; import com.jme3.math.FastMath; import com.jme3.math.Vector3f; @@ -11,13 +10,15 @@ import org.jetbrains.annotations.Nullable; import tonegod.emitter.EmitterMesh; import tonegod.emitter.ParticleEmitterNode; -import tonegod.emitter.influencers.ParticleInfluencer; +import tonegod.emitter.influencers.InfluencerData; import tonegod.emitter.interpolation.Interpolation; import java.util.Arrays; import java.util.concurrent.Callable; import java.util.concurrent.atomic.AtomicInteger; +import static java.util.Objects.requireNonNull; + /** * The particle objectData class. * @@ -94,6 +95,25 @@ public static int reserveFloatDataId() { return FLOAT_DATA_ID_FACTORY.incrementAndGet(); } + + private InfluencerData[] values = new InfluencerData[0]; + + public void setData(int dataId, InfluencerData dataValue) { + if(dataId <= values.length) { + values = Arrays.copyOf(values, dataId + 1); + } + + values[dataId] = dataValue; + } + + public T getData(int dataId) { + if(dataId < 0) { + return null; + } + + return (T) values[dataId]; + } + /** * Get the current max object objectData id. * @@ -505,9 +525,8 @@ public void update(final float tpf) { interpBlend = interpolation.apply(blend); } - final SafeArrayList influencers = emitterNode.getInfluencers(); - for (final ParticleInfluencer influencer : influencers.getArray()) { - influencer.update(this, tpf); + for (final ParticleEmitterNode.InfluencerInstance influencerInstance : emitterNode.getInfluencerInstances()) { + influencerInstance.getInfluencer().update(this, getData(influencerInstance.getId()), tpf); } tempV3.set(velocity).multLocal(tpf); @@ -587,9 +606,13 @@ public void initialize() { initialLength = velocity.length(); initialPosition.set(emitterNode.getWorldTranslation()); - final SafeArrayList influencers = emitterNode.getInfluencers(); - for (final ParticleInfluencer influencer : influencers.getArray()) { - influencer.initialize(this); +// final SafeArrayList influencers = emitterNode.getInfluencers(); +// for (final ParticleInfluencer influencer : influencers.getArray()) { +// influencer.initialize(this); +// } + + for (final ParticleEmitterNode.InfluencerInstance influencerInstance : emitterNode.getInfluencerInstances()) { + initializeInfluencer(influencerInstance); } switch (emitterNode.getEmissionPoint()) { @@ -608,6 +631,17 @@ public void initialize() { } } + /** + * Do not call. Only for internal use. + */ + public void initializeInfluencer(ParticleEmitterNode.InfluencerInstance influencerInstance) { + if(influencerInstance.hasData()) { + setData(influencerInstance.getId(), influencerInstance.createData()); + } + + influencerInstance.getInfluencer().initialize(this, getData(influencerInstance.getId())); + } + /** * Get the size. * @@ -674,9 +708,9 @@ public void reset() { emitterNode.decActiveParticleCount(); } - final SafeArrayList influencers = emitterNode.getInfluencers(); - for (final ParticleInfluencer influencer : influencers.getArray()) { - influencer.reset(this); + final SafeArrayList influencerInstances = emitterNode.getInfluencerInstances(); + for (final ParticleEmitterNode.InfluencerInstance influencerInstance : influencerInstances.getArray()) { + influencerInstance.getInfluencer().reset(this); } emitterNode.setNextIndex(index);