Home | History | Annotate | Download | only in influencers
      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