Ryan McDonough 9 часов назад
Родитель
Сommit
d92151ca2c

+ 105 - 0
vectoreffect/AbstractVectorEffect.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.vectoreffect;
+
+import com.jme3.app.state.AppStateManager;
+import java.util.ArrayList;
+
+/**
+ * @author yaRnMcDonuts
+ */
+
+public abstract class AbstractVectorEffect implements VectorEffect {
+    
+    protected VectorGroup vectorsToModify;    
+    private final ArrayList<Runnable> onFinishedCallbacks = new ArrayList<>();    
+    protected boolean isFinished = false;       
+   
+    public AbstractVectorEffect(){
+        
+    }
+    
+    public AbstractVectorEffect(VectorGroup vectorsToModify) {
+        this.vectorsToModify = vectorsToModify;
+    }        
+    
+    @Override
+    public void setIsFinished(boolean isFinished) {        
+        this.isFinished = isFinished;
+        if (isFinished) {
+            for(Runnable r : onFinishedCallbacks) {
+                r.run();
+            }
+            onFinishedCallbacks.clear();
+        }
+    }
+    
+    @Override
+    public VectorGroup getVectorsToModify(){
+        return vectorsToModify;
+    }
+    
+    @Override
+    public boolean isFinished() {        
+        return isFinished;  
+    }    
+    
+
+    @Override
+    public void reset() {
+        isFinished = false;
+    }
+    
+    
+    public void registerRunnableOnFinish(Runnable runnable) {
+        onFinishedCallbacks.add(runnable);
+    }  
+    
+    @Override
+    public void update(float tpf){
+       
+    }    
+        
+    // convenience registration method so users can avoid repeatedly writing this AppState fetching code
+    public void convenienceRegister(AppStateManager stateManager) {
+        if(stateManager != null){
+            VectorEffectManagerState vectorEffectManagerState = stateManager.getState(VectorEffectManagerState.class);
+            if(vectorEffectManagerState != null){
+                vectorEffectManagerState.registerVectorEffect(this);
+            }
+        }
+    }
+
+
+}
+

+ 146 - 0
vectoreffect/EaseVectorEffect.java

@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.vectoreffect;
+
+import com.jme3.math.EaseFunction;
+import com.jme3.math.Easing;
+import com.jme3.math.Vector4f;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public final class EaseVectorEffect extends AbstractVectorEffect implements VectorEffect {
+
+    private VectorGroup targetVectors;
+    private VectorGroup startVectors;    
+  
+    private float duration = 0f;
+    private float easeTimer = 0f;
+    private float delay = 0f;
+    private float delayTimer = 0f;
+
+    private EaseFunction easeFunction = Easing.linear; 
+    
+    private final Vector4f tempTargetVec = new Vector4f();
+    private final Vector4f tempStartVec = new Vector4f();
+
+
+    public EaseVectorEffect(VectorGroup vectorToModify) {
+        super(vectorToModify);
+    }
+    
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration) {
+        this(vectorToModify);
+        setEaseToValueOverDuration(duration, targetVector);
+    }
+    
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            float delay) {
+        this(vectorToModify);
+        setEaseToValueOverDuration(duration, targetVector);
+        setDelayTime(delay);
+    }
+    
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            EaseFunction easeFunction) {
+        this(vectorToModify, targetVector, duration);
+        setEaseFunction(easeFunction);
+    }
+    
+    public EaseVectorEffect(VectorGroup vectorToModify, VectorGroup targetVector, float duration,
+            EaseFunction easeFunction, float delay) {
+        this(vectorToModify, targetVector, duration);
+        setEaseFunction(easeFunction);
+        setDelayTime(delay);
+    }
+    
+
+    @Override
+    public void update(float tpf) {
+        super.update(tpf);
+        
+        if (delayTimer <= delay) {
+            delayTimer += tpf;
+            return;
+        }
+        
+        if (startVectors == null) {
+            startVectors = vectorsToModify.clone();    
+        }        
+
+        easeTimer += tpf;
+        float t = Math.min(easeTimer / duration, 1f);
+
+        float easedT = easeFunction.apply(t);
+
+        for(int v = 0; v < vectorsToModify.getSize(); v++){
+            
+            int targetIndex = Math.min(v, targetVectors.getSize() - 1); //allows multiple vectors to share a lesser number of targets if desired
+            targetVectors.getAsVector4(targetIndex, tempTargetVec);
+            startVectors.getAsVector4(v, tempStartVec);
+            tempTargetVec.subtractLocal(tempStartVec);
+            tempTargetVec.multLocal(easedT);
+
+            vectorsToModify.updateVectorObject(tempStartVec.addLocal(tempTargetVec), v);            
+        }        
+
+        if (t >= 1f) {
+            super.setIsFinished(true);
+        }
+    }
+
+    public EaseVectorEffect setEaseToValueOverDuration(float dur, VectorGroup targetVector) {
+        this.targetVectors = targetVector;
+        duration = dur;
+        startVectors = null;
+        return this;
+    }
+
+    public void setDelayTime(float delay) {
+        this.delay = delay;
+    }
+
+    public void setEaseFunction(EaseFunction func) {
+        this.easeFunction = func;
+    }
+    
+    @Override
+    public void reset() {
+        delayTimer = 0;
+        easeTimer = 0;
+        startVectors = null;           
+        super.reset(); 
+    }
+    
+}

+ 105 - 0
vectoreffect/NoiseVectorEffect.java

@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.vectoreffect;
+
+import com.jme3.math.Vector4f;
+import com.jme3.math.FastNoiseLite;
+import com.jme3.math.FastNoiseLite.NoiseType;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public class NoiseVectorEffect extends AbstractVectorEffect implements VectorEffect {
+    
+    private FastNoiseLite noiseGenerator;        
+
+    private VectorGroup noiseMagnitudes;    
+    private VectorGroup originalVectorValues;
+    
+    private final Vector4f tempNoiseVariationVec = new Vector4f();
+    private final Vector4f tempOriginalVec = new Vector4f();
+    
+    public float speed = 1;
+    private float timeAccrued = 0;
+    
+    public NoiseVectorEffect(VectorGroup vectorObject, VectorGroup noiseMagnitude) {
+        this(vectorObject, noiseMagnitude, NoiseType.OpenSimplex2, 0.5f);       
+    }
+    
+    public NoiseVectorEffect(VectorGroup vectorObject, VectorGroup noiseMagnitude, NoiseType noiseType,
+            float frequency) {
+        super(vectorObject);
+        
+        this.noiseMagnitudes = noiseMagnitude;
+        noiseGenerator = new FastNoiseLite();
+        noiseGenerator.SetFrequency(frequency);
+        noiseGenerator.SetNoiseType(noiseType);       
+      
+    }
+
+    @Override
+    public void update(float tpf) {
+        super.update(tpf);
+        
+        if(originalVectorValues == null){
+            originalVectorValues = vectorsToModify.clone();
+        }
+        
+        timeAccrued += tpf;             
+        float noiseReturnVal = noiseGenerator.GetNoise(timeAccrued * speed, 12.671f + timeAccrued * speed * 0.92173f, 19.54f + timeAccrued * speed * 0.68913f);
+        
+        for(int v = 0; v < vectorsToModify.getSize(); v++){
+            int magnitudeIndex = Math.min(v, noiseMagnitudes.getSize() - 1); //allows multiple vectors to share the same magnitude if desired
+            noiseMagnitudes.getAsVector4(magnitudeIndex, tempNoiseVariationVec);
+
+            tempNoiseVariationVec.multLocal(noiseReturnVal);        
+            originalVectorValues.getAsVector4(v, tempOriginalVec);
+        
+            vectorsToModify.updateVectorObject(tempOriginalVec.addLocal(tempNoiseVariationVec), v);
+        }             
+    }    
+    
+    public FastNoiseLite getNoiseGenerator() {
+        return noiseGenerator;
+    }
+
+    public void setSpeed(float speed) {
+        this.speed = speed;
+    }
+    
+    @Override
+    public void reset() {
+        super.reset(); 
+        originalVectorValues = null;       
+    }
+}

+ 93 - 0
vectoreffect/SequencedVectorEffect.java

@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.vectoreffect;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public class SequencedVectorEffect extends AbstractVectorEffect implements VectorEffect {
+    private final ArrayList<VectorEffect> effects = new ArrayList<>();
+    private int currentIndex = 0;
+    private boolean isRepeatingInfinitely = false;
+    private float numTimesToRepeat = -1;
+    private float currentCycle = 0;
+
+    public void setLooping(boolean repeat) {        this.isRepeatingInfinitely = repeat;    }
+    public void setRepeatNumberOfTimes(float repititionCount){ this.numTimesToRepeat = repititionCount; }
+    public void addEffect(VectorEffect effect) {        effects.add(effect);    }
+
+    public SequencedVectorEffect(VectorEffect... effects) {
+        super();
+        Collections.addAll(this.effects, effects);
+    }
+
+    @Override
+    public void update(float tpf) {
+        super.update(tpf);
+        if (effects.isEmpty()) {
+            setIsFinished(true);
+            return;
+        }
+
+        VectorEffect current = effects.get(currentIndex);
+        current.update(tpf);
+
+        if (current.isFinished()) {
+            currentIndex++;
+
+            if (currentIndex >= effects.size()) {
+                currentCycle++;
+                reset();
+                
+                if (!isRepeatingInfinitely && currentCycle >= numTimesToRepeat) {
+                    setIsFinished(true);
+                    currentCycle = 0;
+                }               
+            }
+        }
+    }    
+    
+    @Override
+    public void reset() {
+        super.reset(); 
+        isFinished = false;
+        currentIndex = 0;
+        for (VectorEffect e : effects) {
+            e.reset();
+        }
+    }
+}

+ 47 - 0
vectoreffect/VectorEffect.java

@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.vectoreffect;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public interface VectorEffect {
+
+    public boolean isFinished();
+    public void update(float tpf);
+    public void setIsFinished(boolean b);
+    public VectorGroup getVectorsToModify();
+    public void reset();
+        
+    
+}

+ 95 - 0
vectoreffect/VectorEffectManagerState.java

@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.vectoreffect;
+
+import com.jme3.app.Application;
+import com.jme3.app.state.BaseAppState;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public class VectorEffectManagerState extends BaseAppState {
+    
+    private final ArrayList<VectorEffect> activeVectorEffects = new ArrayList();
+
+    @Override
+    protected void initialize(Application aplctn) {
+    
+    }
+
+    @Override
+    protected void cleanup(Application aplctn) {
+    
+    }
+
+    @Override
+    protected void onEnable() {
+    
+    }
+
+    @Override
+    protected void onDisable() {
+    
+    }
+    
+    public void registerVectorEffect(VectorEffect vectorEffect){
+        if(!activeVectorEffects.contains(vectorEffect)){
+            activeVectorEffects.add(vectorEffect);
+        }     
+    }
+    
+    @Override
+    public void update(float tpf) {
+        super.update(tpf);
+        for (Iterator<VectorEffect> it = activeVectorEffects.iterator(); it.hasNext(); ) {
+            VectorEffect vectorEffect = it.next();
+
+            if (vectorEffect.isFinished()) {
+                it.remove(); 
+            } else {
+                vectorEffect.update(tpf);
+            }
+        }
+    }
+
+    public void cancelEffects(VectorGroup vectorObject) {
+        for(VectorEffect vectorEffect : activeVectorEffects){
+            if(vectorEffect.getVectorsToModify().equals(vectorObject)){
+                vectorEffect.setIsFinished(true);
+            }
+        }
+    }
+}

+ 101 - 0
vectoreffect/VectorGroup.java

@@ -0,0 +1,101 @@
+/*
+ * Copyright (c) 2009-2026 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.jme3.vectoreffect;
+
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.math.Vector4f;
+import java.util.ArrayList;
+
+/**
+ *
+ * @author yaRnMcDonuts
+ */
+public class VectorGroup implements Cloneable {
+    
+    protected final ArrayList<VectorSupplier> vectorSupplier = new ArrayList<>();
+        
+    public int getSize(){
+        return vectorSupplier.size();
+    }
+    
+    public VectorGroup(VectorSupplier... vectorSuppliers) {
+        for (VectorSupplier vs : vectorSuppliers) {
+            vectorSupplier.add(vs);
+        }
+    }
+
+    public VectorGroup(ColorRGBA... color) {
+        for (ColorRGBA c : color) {
+            this.vectorSupplier.add(VectorSupplier.of(c));
+        }
+    }
+
+    public VectorGroup(Vector4f... vectors) {
+        for (Vector4f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
+        }
+    }
+
+    public VectorGroup(Vector3f... vectors) {
+        for (Vector3f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
+        }
+    }
+
+    public VectorGroup(Vector2f... vectors) {
+        for (Vector2f v : vectors) {
+            this.vectorSupplier.add(VectorSupplier.of(v));
+        }
+    }
+
+    protected Vector4f getAsVector4(int index, Vector4f store) {
+        return store.set(vectorSupplier.get(index).get());
+    }
+
+    protected void updateVectorObject(Vector4f newVal, int index) {
+        VectorSupplier store = vectorSupplier.get(index);
+        store.set(newVal);
+    }
+
+    @Override
+    public VectorGroup clone() {
+        VectorGroup clonedGroup = new VectorGroup(new VectorSupplier[0]);
+        for (VectorSupplier supplier : this.vectorSupplier) {
+            clonedGroup.vectorSupplier.add(supplier.clone());
+        }
+        return clonedGroup;
+    }
+}
+

+ 162 - 0
vectoreffect/VectorSupplier.java

@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2009-2021 jMonkeyEngine
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ *   notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ *   notice, this list of conditions and the following disclaimer in the
+ *   documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
+ *   may be used to endorse or promote products derived from this software
+ *   without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+package com.jme3.vectoreffect;
+
+import com.jme3.math.ColorRGBA;
+import com.jme3.math.Vector2f;
+import com.jme3.math.Vector3f;
+import com.jme3.math.Vector4f;
+
+public interface VectorSupplier extends Cloneable {
+    Vector4f get();
+    void set(Vector4f newVal);
+    VectorSupplier clone();
+
+    static class Vector4fSupplier implements VectorSupplier {
+        private final Vector4f vector;
+
+        Vector4fSupplier(Vector4f vector) {
+            this.vector = vector;
+        }
+
+        @Override
+        public Vector4f get() {
+            return vector;
+        }
+
+        @Override
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal);
+        }
+
+        @Override
+        public Vector4fSupplier clone() {
+            return new Vector4fSupplier(vector.clone());
+        }      
+    }
+
+    static class Vector3fSupplier implements VectorSupplier {
+        private final Vector3f vector;
+        private final Vector4f store = new Vector4f();
+        Vector3fSupplier(Vector3f vector) {
+            this.vector = vector;
+        }
+
+        @Override
+        public Vector4f get() {
+            store.set(vector.x, vector.y, vector.z, 0);
+            return store;
+        }
+
+        @Override
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal.x, newVal.y, newVal.z);
+            get(); //update store
+        }
+
+        @Override
+        public Vector3fSupplier clone() {
+            return new Vector3fSupplier(vector.clone());
+        }
+    }
+
+    static class ColorRGBASupplier implements VectorSupplier {
+        private ColorRGBA color;
+        private final Vector4f store = new Vector4f();
+
+        ColorRGBASupplier(ColorRGBA color) {
+            this.color = color;
+        }
+
+        @Override
+        public Vector4f get() {
+            store.set(color.r, color.g, color.b, color.a);
+            return store;
+        }
+
+        @Override
+        public void set(Vector4f newVal) {
+            this.color.set(newVal.x, newVal.y, newVal.z, newVal.w);
+            get(); //update store
+        }
+
+        @Override
+        public ColorRGBASupplier clone() {
+            return new ColorRGBASupplier(color.clone());
+        }
+    }
+
+    static class Vector2fSupplier implements VectorSupplier {
+        private final Vector2f vector;
+        private final Vector4f store = new Vector4f();
+
+        Vector2fSupplier(Vector2f vector) {
+            this.vector = vector;
+        }
+
+        @Override
+        public Vector4f get() {
+            store.set(vector.x, vector.y, 0, 0);
+            return store;
+        }
+
+        @Override
+        public void set(Vector4f newVal) {
+            this.vector.set(newVal.x, newVal.y);
+            get(); //update store
+        }
+
+        @Override
+        public Vector2fSupplier clone() {
+            return new Vector2fSupplier(vector.clone());
+        }
+    }   
+
+
+    public static VectorSupplier of(Vector4f vector) {
+        return new Vector4fSupplier(vector);
+    }
+
+    public static VectorSupplier of(Vector3f vector) {
+        return new Vector3fSupplier(vector);
+    }
+
+    public static VectorSupplier of(Vector2f vector) {
+        return new Vector2fSupplier(vector);
+    }
+
+    public static VectorSupplier of(ColorRGBA color) {
+        return new ColorRGBASupplier(color);
+    }
+
+
+}