diff --git a/jme3-effects/src/main/java/com/jme3/vectoreffect/EaseVectorEffect.java b/jme3-effects/src/main/java/com/jme3/vectoreffect/EaseVectorEffect.java new file mode 100644 index 0000000000..bb7d71d41b --- /dev/null +++ b/jme3-effects/src/main/java/com/jme3/vectoreffect/EaseVectorEffect.java @@ -0,0 +1,148 @@ +/* + * 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 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; + + public EaseVectorEffect(Object vectorToModify) { + super(vectorToModify); + } + + public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration) { + this(vectorToModify); + setEaseToValueOverDuration(duration, targetVector); + } + + public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration, float delay) { + this(vectorToModify); + setEaseToValueOverDuration(duration, targetVector); + setDelayTime(delay); + } + + public EaseVectorEffect(Object vectorToModify, Object targetVector, float duration, EaseFunction easeFunction) { + this(vectorToModify, targetVector, duration); + setEaseFunction(easeFunction); + } + + public EaseVectorEffect(Object vectorToModify, Object 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 = new VectorGroup(); + + for(int v = 0; v < vectorsToModify.getSize(); v++){ + Vector4f startVector = vectorsToModify.getAsVector4(v).clone(); + startVectors.addVectorToGroup(startVector); + } + } + + easeTimer += tpf; + float t = Math.min(easeTimer / duration, 1f); + + float easedT = easeFunction.apply(t); + + for(int v = 0; v < vectorsToModify.getSize(); v++){ + + Vector4f targetVector = targetVectors.getAsVector4(v); + Vector4f startVector = startVectors.getAsVector4(v); + Vector4f difference = targetVector.subtract(startVector); + + Vector4f currentValue = startVector.add(difference.mult(easedT)); + vectorsToModify.updateVectorObject(currentValue, v); + } + + if (t >= 1f) { + super.setIsFinished(true); + } + } + + public EaseVectorEffect setEaseToValueOverDuration(float dur, Object targetVector) { + if(targetVector instanceof VectorGroup){ + targetVectors = (VectorGroup) targetVector; + } + else{ + targetVectors = new VectorGroup(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(); + } +} \ No newline at end of file diff --git a/jme3-effects/src/main/java/com/jme3/vectoreffect/SequencedVectorEffect.java b/jme3-effects/src/main/java/com/jme3/vectoreffect/SequencedVectorEffect.java new file mode 100644 index 0000000000..85e6521777 --- /dev/null +++ b/jme3-effects/src/main/java/com/jme3/vectoreffect/SequencedVectorEffect.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 java.util.ArrayList; +import java.util.Collections; + +/** + * + * @author yaRnMcDonuts + */ +public class SequencedVectorEffect extends VectorEffect { + private final ArrayList 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(); + } + } +} diff --git a/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffect.java b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffect.java new file mode 100644 index 0000000000..959d5c7662 --- /dev/null +++ b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffect.java @@ -0,0 +1,104 @@ +/* + * 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; + +/** + * Base class for vector/color effects. * + * Supports Vector2f, Vector3f, Vector4f, and ColorRGBA. + * + * @author yaRnMcDonuts + */ + +public abstract class VectorEffect { + + protected VectorGroup vectorsToModify; + private final ArrayList onFinishedCallbacks = new ArrayList<>(); + protected boolean isFinished = false; + + public VectorEffect(){ + + } + + public VectorEffect(Object vectorObj) { + + if(vectorObj instanceof VectorGroup){ + vectorsToModify = (VectorGroup) vectorObj; + }else{ + vectorsToModify = new VectorGroup(vectorObj); + } + } + + public void setIsFinished(boolean isFinished) { + this.isFinished = isFinished; + if (isFinished) { + for(Runnable r : onFinishedCallbacks) { + r.run(); + } + onFinishedCallbacks.clear(); + } + } + + public boolean isFinished() { + return isFinished; + } + + + public void reset() { + isFinished = false; + } + + + public void registerRunnableOnFinish(Runnable runnable) { + onFinishedCallbacks.add(runnable); + } + + 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); + } + } + } + + +} + diff --git a/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffectManagerState.java b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffectManagerState.java new file mode 100644 index 0000000000..e4bcc7ac1c --- /dev/null +++ b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorEffectManagerState.java @@ -0,0 +1,94 @@ +/* + * 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; + +/** + * + * @author yaRnMcDonuts + */ +public class VectorEffectManagerState extends BaseAppState { + + private final ArrayList 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 != null){ + if(!activeVectorEffects.contains(vectorEffect)){ + activeVectorEffects.add(vectorEffect); + } + } + } + + @Override + public void update(float tpf) { + super.update(tpf); + + for(VectorEffect vectorEffect : activeVectorEffects){ + + + + if(vectorEffect.isFinished()){ + getApplication().enqueue(() ->{ + activeVectorEffects.remove(vectorEffect); + }); + } + else{ + vectorEffect.update(tpf); + } + } + + } +} diff --git a/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorGroup.java b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorGroup.java new file mode 100644 index 0000000000..65bd3d4a4e --- /dev/null +++ b/jme3-effects/src/main/java/com/jme3/vectoreffect/VectorGroup.java @@ -0,0 +1,115 @@ +/* + * 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 { + + private final ArrayList vectorList = new ArrayList(); + + public int getSize(){ + return vectorList.size(); + } + + public VectorGroup(Object... vectorObjects) { + for(int v = 0; v < vectorObjects.length; v++){ + addVectorToGroup(vectorObjects[v]); + } + } + + public final void addVectorToGroup(Object vectorObj){ + if(isValidVectorObject(vectorObj)){ + vectorList.add(vectorObj); + } else{ + throw new IllegalArgumentException( "VectorGroup must contain valid vector-type objects. This includes: Vector2f, Vector3f, Vector4f, and ColorRGBA"); + } + } + + + //regardless of type, all vectors in a VectorGroup are converted to and from Vector4f when being operated on internally by a VectorEffect. + protected Vector4f getAsVector4(int index) { + Object vectorObj = vectorList.get(index); + if (vectorObj instanceof Vector4f) { + Vector4f vec4 = (Vector4f) vectorObj; + return vec4.clone(); + } + else if (vectorObj instanceof Vector3f) { + Vector3f vec3 = (Vector3f) vectorObj; + return new Vector4f(vec3.x, vec3.y, vec3.z, 1f); + } + else if (vectorObj instanceof Vector2f) { + Vector2f vec2 = (Vector2f) vectorObj; + return new Vector4f(vec2.x, vec2.y, 1f, 1f); + } + else if (vectorObj instanceof ColorRGBA) { + ColorRGBA color = (ColorRGBA) vectorObj; + return color.toVector4f(); + } + else { + throw new IllegalStateException("VectorEffect supports only Vector2f, Vector3f, Vector4f, or ColorRGBA"); + } + } + + protected void updateVectorObject(Vector4f newVal, int index) { + Object store = vectorList.get(index); + if (store instanceof Vector4f) { + ((Vector4f)store).set(newVal); // set vec4 + } + else if (store instanceof Vector3f) { + ((Vector3f)store).set(newVal.x, newVal.y, newVal.z); + } + else if (store instanceof Vector2f) { + ((Vector2f)store).set(newVal.x, newVal.y); // drop z,w + } + else if (store instanceof ColorRGBA) { + ((ColorRGBA)store).set(newVal.x, newVal.y, newVal.z, newVal.w); // map xyzw -> rgba + } + else { + throw new IllegalStateException("VectorEffect supports only Vector2f, Vector3f, Vector4f, or ColorRGBA"); + } + } + + private boolean isValidVectorObject(Object vectorObj){ + return (vectorObj instanceof Vector2f || vectorObj instanceof Vector3f || vectorObj instanceof Vector4f || vectorObj instanceof ColorRGBA || vectorObj instanceof VectorGroup); + } + +} diff --git a/jme3-examples/src/main/java/jme3test/effect/VectorEffectSimpleTest.java b/jme3-examples/src/main/java/jme3test/effect/VectorEffectSimpleTest.java new file mode 100644 index 0000000000..fc70b3777b --- /dev/null +++ b/jme3-examples/src/main/java/jme3test/effect/VectorEffectSimpleTest.java @@ -0,0 +1,211 @@ +/* + * 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 jme3test.effect; + +import com.jme3.vectoreffect.EaseVectorEffect; +import com.jme3.vectoreffect.VectorEffectManagerState; +import com.jme3.vectoreffect.SequencedVectorEffect; +import com.jme3.app.SimpleApplication; +import com.jme3.light.PointLight; +import com.jme3.material.Material; +import com.jme3.math.ColorRGBA; +import com.jme3.math.Easing; +import com.jme3.math.FastMath; +import com.jme3.post.FilterPostProcessor; +import com.jme3.post.filters.BloomFilter; +import com.jme3.scene.Geometry; +import com.jme3.scene.shape.Quad; +import com.jme3.scene.shape.Sphere; +import com.jme3.system.AppSettings; +import java.awt.DisplayMode; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; + +/** + * + * @author yaRnMcDonuts + */ +public class VectorEffectSimpleTest extends SimpleApplication { + + private ColorRGBA colorToShift = new ColorRGBA(0.0f, 0.0f, 1.0f, 1.0f); + + private VectorEffectManagerState vectorEffectManagerState; + + public static void main(String[] args) { + VectorEffectSimpleTest app = new VectorEffectSimpleTest(); + AppSettings settings = new AppSettings(true); + app.setSettings(settings); + app.start(); + } + + + @Override + public void simpleInitApp() { + restart(); + flyCam.setMoveSpeed(10f); + + vectorEffectManagerState = new VectorEffectManagerState(); + stateManager.attach(vectorEffectManagerState); + + initBloom(); + initPbrRoom(13); + + initLightAndEmissiveSphere(); + + //initiate VectorEffectManagerState + vectorEffectManagerState = new VectorEffectManagerState(); + stateManager.attach(vectorEffectManagerState); + vectorEffectManagerState.setEnabled(true); + + //create gradient effect : + SequencedVectorEffect colorGradientEffect = new SequencedVectorEffect( + new EaseVectorEffect(colorToShift, ColorRGBA.Cyan, 0.75f), + new EaseVectorEffect(colorToShift, ColorRGBA.Yellow, 0.75f), + new EaseVectorEffect(colorToShift, ColorRGBA.Blue, 0.75f ), + new EaseVectorEffect(colorToShift, ColorRGBA.Magenta, 0.75f), + new EaseVectorEffect(colorToShift, ColorRGBA.Green, 0.75f), + new EaseVectorEffect(colorToShift, ColorRGBA.Red, 0.75f) + ); + + //create red flashing effect : + SequencedVectorEffect blinkEffect = new SequencedVectorEffect( + new EaseVectorEffect(colorToShift, ColorRGBA.Black, 0.25f, Easing.inOutQuad), + new EaseVectorEffect(colorToShift, ColorRGBA.Red, 0.175f, Easing.outQuart) + ); + blinkEffect.setRepeatNumberOfTimes(10); + + + //put both effects into a looping SequencedVectorEffect + SequencedVectorEffect finalLoopingEffect = new SequencedVectorEffect(colorGradientEffect, blinkEffect); + finalLoopingEffect.setLooping(true); + + //register the effect: + vectorEffectManagerState.registerVectorEffect(finalLoopingEffect); + + } + + private void initBloom() { + + FilterPostProcessor fpp = new FilterPostProcessor(assetManager); + BloomFilter bloom = new BloomFilter(BloomFilter.GlowMode.Scene); + bloom.setBloomIntensity(5f); + bloom.setExposurePower(4.5f); + bloom.setExposureCutOff(0.2f); + bloom.setBlurScale(2); + fpp.addFilter(bloom); + viewPort.addProcessor(fpp); + } + + private void initLightAndEmissiveSphere(){ + + + //make point light + PointLight light = new PointLight(); + light.setRadius(10); + colorToShift = light.getColor(); + + //make sphere with Emissive color + Sphere sphereMesh = new Sphere(32, 32, 0.5f); + Geometry glowingSphere = new Geometry("ShakingSphere", sphereMesh); + + Material sphereMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md"); + sphereMat.setColor("BaseColor", ColorRGBA.DarkGray); + sphereMat.setFloat("Roughness", 0.04f); + sphereMat.setFloat("Metallic", 0.98f); + sphereMat.setBoolean("UseVertexColor", false); + glowingSphere.setMaterial(sphereMat); + + + //assign the same colorToShift vector to both the light and emissive value (important not to clone) + light.setColor(colorToShift); + sphereMat.setColor("Emissive", colorToShift); + + + rootNode.attachChild(glowingSphere); + rootNode.addLight(light); + + + } + + public void initPbrRoom(float size) { + + + float half = size * 0.5f; + + + Material wallMat = new Material(assetManager, "Common/MatDefs/Light/PBRLighting.j3md"); + + wallMat.setColor("BaseColor", new ColorRGBA(1,1,1, 1f)); + wallMat.setFloat("Roughness", 0.12f); + wallMat.setFloat("Metallic", 0.02f); + + // Floor + Geometry floor = new Geometry("Floor", + new Quad(size, size)); + floor.setMaterial(wallMat); + floor.rotate(-FastMath.HALF_PI, 0, 0); + floor.setLocalTranslation(-half, -half, half); + rootNode.attachChild(floor); + + // Ceiling + Geometry ceiling = new Geometry("Ceiling", + new Quad(size, size)); + ceiling.setMaterial(wallMat); + ceiling.rotate(FastMath.HALF_PI, 0, 0); + ceiling.setLocalTranslation(-half, size-half, -half); + rootNode.attachChild(ceiling); + + // Back wall + Geometry backWall = new Geometry("BackWall", + new Quad(size, size)); + backWall.setMaterial(wallMat); + backWall.setLocalTranslation(-half, -half, -half); + rootNode.attachChild(backWall); + + // Left wall + Geometry leftWall = new Geometry("LeftWall", + new Quad(size, size)); + leftWall.setMaterial(wallMat); + leftWall.rotate(0, FastMath.HALF_PI, 0); + leftWall.setLocalTranslation(-half, -half, half); + rootNode.attachChild(leftWall); + + // Right wall + Geometry rightWall = new Geometry("RightWall", + new Quad(size, size)); + rightWall.setMaterial(wallMat); + rightWall.rotate(0, -FastMath.HALF_PI, 0); + rightWall.setLocalTranslation(half, -half, -half); + rootNode.attachChild(rightWall); + + } +} \ No newline at end of file