1 package com.badlogic.gdx.graphics.g3d.particles.influencers; 2 3 import com.badlogic.gdx.graphics.g3d.particles.ParallelArray.FloatChannel; 4 import com.badlogic.gdx.graphics.g3d.particles.ParticleChannels; 5 import com.badlogic.gdx.graphics.g3d.particles.values.GradientColorValue; 6 import com.badlogic.gdx.graphics.g3d.particles.values.ScaledNumericValue; 7 import com.badlogic.gdx.math.MathUtils; 8 import com.badlogic.gdx.utils.Json; 9 import com.badlogic.gdx.utils.JsonValue; 10 11 /** It's an {@link Influencer} which controls particles color and transparency. 12 * @author Inferno */ 13 public abstract class ColorInfluencer extends Influencer{ 14 15 /** It's an {@link Influencer} which assigns a random color when a particle is activated. */ 16 public static class Random extends ColorInfluencer{ 17 FloatChannel colorChannel; 18 19 @Override 20 public void allocateChannels() { 21 colorChannel = controller.particles.addChannel(ParticleChannels.Color); 22 } 23 24 @Override 25 public void activateParticles (int startIndex, int count) { 26 for(int i=startIndex*colorChannel.strideSize, c = i +count*colorChannel.strideSize; 27 i < c; 28 i +=colorChannel.strideSize){ 29 colorChannel.data[i+ParticleChannels.RedOffset] = MathUtils.random(); 30 colorChannel.data[i+ParticleChannels.GreenOffset] = MathUtils.random(); 31 colorChannel.data[i+ParticleChannels.BlueOffset] = MathUtils.random(); 32 colorChannel.data[i+ParticleChannels.AlphaOffset] = MathUtils.random(); 33 } 34 } 35 36 @Override 37 public Random copy () { 38 return new Random(); 39 } 40 } 41 42 /** It's an {@link Influencer} which manages the particle color during its life time. */ 43 public static class Single extends ColorInfluencer { 44 FloatChannel alphaInterpolationChannel; 45 FloatChannel lifeChannel; 46 public ScaledNumericValue alphaValue; 47 public GradientColorValue colorValue; 48 49 public Single(){ 50 colorValue = new GradientColorValue(); 51 alphaValue = new ScaledNumericValue(); 52 alphaValue.setHigh(1); 53 } 54 55 public Single (Single billboardColorInfluencer) { 56 this(); 57 set(billboardColorInfluencer); 58 } 59 60 public void set(Single colorInfluencer){ 61 this.colorValue.load(colorInfluencer.colorValue); 62 this.alphaValue.load(colorInfluencer.alphaValue); 63 } 64 65 @Override 66 public void allocateChannels () { 67 super.allocateChannels(); 68 //Hack this allows to share the channel descriptor structure but using a different id temporary 69 ParticleChannels.Interpolation.id = controller.particleChannels.newId(); 70 alphaInterpolationChannel = controller.particles.addChannel(ParticleChannels.Interpolation); 71 lifeChannel = controller.particles.addChannel(ParticleChannels.Life); 72 } 73 74 @Override 75 public void activateParticles (int startIndex, int count) { 76 for(int i=startIndex*colorChannel.strideSize, 77 a = startIndex*alphaInterpolationChannel.strideSize, 78 l = startIndex*lifeChannel.strideSize + ParticleChannels.LifePercentOffset, 79 c = i +count*colorChannel.strideSize; 80 i < c; 81 i +=colorChannel.strideSize, 82 a +=alphaInterpolationChannel.strideSize, 83 l +=lifeChannel.strideSize){ 84 float alphaStart = alphaValue.newLowValue(); 85 float alphaDiff = alphaValue.newHighValue() - alphaStart; 86 colorValue.getColor(0, colorChannel.data, i); 87 colorChannel.data[i+ParticleChannels.AlphaOffset] = alphaStart + alphaDiff*alphaValue.getScale(lifeChannel.data[l]); 88 alphaInterpolationChannel.data[a+ParticleChannels.InterpolationStartOffset] = alphaStart; 89 alphaInterpolationChannel.data[a+ParticleChannels.InterpolationDiffOffset] = alphaDiff; 90 } 91 } 92 93 @Override 94 public void update () { 95 for(int i=0, a = 0, l = ParticleChannels.LifePercentOffset, 96 c = i +controller.particles.size*colorChannel.strideSize; 97 i < c; 98 i +=colorChannel.strideSize, a +=alphaInterpolationChannel.strideSize, l +=lifeChannel.strideSize){ 99 100 float lifePercent = lifeChannel.data[l]; 101 colorValue.getColor(lifePercent, colorChannel.data, i); 102 colorChannel.data[i+ParticleChannels.AlphaOffset] = alphaInterpolationChannel.data[a+ParticleChannels.InterpolationStartOffset] 103 + alphaInterpolationChannel.data[a+ParticleChannels.InterpolationDiffOffset] *alphaValue.getScale(lifePercent); 104 } 105 } 106 107 @Override 108 public Single copy () { 109 return new Single(this); 110 } 111 112 @Override 113 public void write (Json json) { 114 json.writeValue("alpha", alphaValue); 115 json.writeValue("color", colorValue); 116 } 117 118 @Override 119 public void read (Json json, JsonValue jsonData) { 120 alphaValue = json.readValue("alpha", ScaledNumericValue.class, jsonData); 121 colorValue = json.readValue("color", GradientColorValue.class, jsonData); 122 } 123 } 124 125 FloatChannel colorChannel; 126 127 @Override 128 public void allocateChannels() { 129 colorChannel = controller.particles.addChannel(ParticleChannels.Color); 130 } 131 } 132