1package com.badlogic.gdx.graphics.g3d.particles;
2
3import java.util.Arrays;
4
5import com.badlogic.gdx.graphics.g3d.ModelInstance;
6import com.badlogic.gdx.graphics.g3d.particles.ParallelArray.ChannelDescriptor;
7import com.badlogic.gdx.graphics.g3d.particles.ParallelArray.ChannelInitializer;
8import com.badlogic.gdx.graphics.g3d.particles.ParallelArray.FloatChannel;
9
10/** This contains all the definitions of particle related channels and channel initializers.
11 * It is also used by the {@link ParticleController} to handle temporary channels allocated by influencers.
12 * @author inferno */
13public class ParticleChannels {
14	private static int currentGlobalId;
15	public static int newGlobalId(){
16		return currentGlobalId++;
17	}
18
19	//Initializers
20	public static class TextureRegionInitializer implements ChannelInitializer<FloatChannel>{
21		private static TextureRegionInitializer instance;
22		public static TextureRegionInitializer get(){
23				if(instance == null)
24					instance = new TextureRegionInitializer();
25				return instance;
26		}
27
28		@Override
29		public void init (FloatChannel channel) {
30			for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){
31				channel.data[i + ParticleChannels.UOffset] = 0;
32				channel.data[i + ParticleChannels.VOffset] = 0;
33				channel.data[i + ParticleChannels.U2Offset] = 1;
34				channel.data[i + ParticleChannels.V2Offset] = 1;
35				channel.data[i + ParticleChannels.HalfWidthOffset] = 0.5f;
36				channel.data[i + ParticleChannels.HalfHeightOffset] = 0.5f;
37			}
38		}
39	}
40
41	public static class ColorInitializer implements ChannelInitializer<FloatChannel>{
42		private static ColorInitializer instance;
43		public static ColorInitializer get(){
44			if(instance == null)
45				instance = new ColorInitializer();
46			return instance;
47		}
48		@Override
49		public void init (FloatChannel channel) {
50			Arrays.fill(channel.data, 0, channel.data.length, 1);
51		}
52	}
53
54	public static class ScaleInitializer implements ChannelInitializer<FloatChannel>{
55		private static ScaleInitializer instance;
56		public static ScaleInitializer get(){
57			if(instance == null)
58				instance = new ScaleInitializer();
59			return instance;
60		}
61		@Override
62		public void init (FloatChannel channel) {
63			Arrays.fill(channel.data, 0, channel.data.length, 1);
64		}
65	}
66
67	public static class Rotation2dInitializer implements ChannelInitializer<FloatChannel>{
68		private static Rotation2dInitializer instance;
69		public static Rotation2dInitializer get(){
70			if(instance == null)
71				instance = new Rotation2dInitializer();
72			return instance;
73		}
74		@Override
75		public void init (FloatChannel channel) {
76			for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){
77				channel.data[i + ParticleChannels.CosineOffset] = 1;
78				channel.data[i + ParticleChannels.SineOffset] = 0;
79			}
80		}
81	}
82
83	public static class Rotation3dInitializer implements ChannelInitializer<FloatChannel>{
84		private static Rotation3dInitializer instance;
85		public static Rotation3dInitializer get(){
86			if(instance == null)
87				instance = new Rotation3dInitializer();
88			return instance;
89		}
90		@Override
91		public void init (FloatChannel channel) {
92			for(int i=0, c = channel.data.length; i < c; i+= channel.strideSize){
93				channel.data[i + ParticleChannels.XOffset] =
94				channel.data[i + ParticleChannels.YOffset] =
95				channel.data[i + ParticleChannels.ZOffset] = 0;
96				channel.data[i + ParticleChannels.WOffset] = 1;
97			}
98		}
99	}
100
101	//Channels
102	/** Channels of common use like position, life, color, etc...*/
103	public static final ChannelDescriptor Life = new ChannelDescriptor(newGlobalId(), float.class, 3);
104	public static final ChannelDescriptor Position = new ChannelDescriptor(newGlobalId(), float.class, 3); //gl units
105	public static final ChannelDescriptor PreviousPosition = new ChannelDescriptor(newGlobalId(), float.class, 3);
106	public static final ChannelDescriptor Color = new ChannelDescriptor(newGlobalId(), float.class, 4);
107	public static final ChannelDescriptor TextureRegion = new ChannelDescriptor(newGlobalId(), float.class, 6);
108	public static final ChannelDescriptor Rotation2D = new ChannelDescriptor(newGlobalId(), float.class, 2);
109	public static final ChannelDescriptor Rotation3D = new ChannelDescriptor(newGlobalId(), float.class, 4);
110	public static final ChannelDescriptor Scale = new ChannelDescriptor(newGlobalId(), float.class, 1);
111	public static final ChannelDescriptor ModelInstance = new ChannelDescriptor(newGlobalId(), ModelInstance.class, 1);
112	public static final ChannelDescriptor ParticleController = new ChannelDescriptor(newGlobalId(), ParticleController.class, 1);
113	public static final ChannelDescriptor Acceleration = new ChannelDescriptor(newGlobalId(), float.class, 3); //gl units/s2
114	public static final ChannelDescriptor AngularVelocity2D = new ChannelDescriptor(newGlobalId(), float.class, 1);
115	public static final ChannelDescriptor AngularVelocity3D = new ChannelDescriptor(newGlobalId(), float.class, 3);
116	public static final ChannelDescriptor Interpolation = new ChannelDescriptor(-1, float.class, 2);
117	public static final ChannelDescriptor Interpolation4 = new ChannelDescriptor(-1, float.class, 4);
118	public static final ChannelDescriptor Interpolation6 = new ChannelDescriptor(-1, float.class, 6);
119
120	//Offsets
121	/** Offsets to acess a particular value inside a stride of a given channel */
122	public static final int CurrentLifeOffset = 0, TotalLifeOffset = 1, LifePercentOffset =2;
123	public static final int RedOffset = 0, GreenOffset =1, BlueOffset = 2, AlphaOffset =3;
124	public static final int InterpolationStartOffset = 0, InterpolationDiffOffset =1;
125	public static final int VelocityStrengthStartOffset = 0, VelocityStrengthDiffOffset =1,
126												VelocityThetaStartOffset = 0, VelocityThetaDiffOffset =1,
127												VelocityPhiStartOffset = 2, VelocityPhiDiffOffset =3;
128	public static final int XOffset = 0, YOffset = 1, ZOffset = 2, WOffset = 3;
129	public static final int UOffset = 0, VOffset= 1, U2Offset = 2, V2Offset = 3,
130												HalfWidthOffset = 4, HalfHeightOffset= 5;
131	public static final int CosineOffset = 0, SineOffset= 1;
132
133	private int currentId;
134
135	public ParticleChannels(){
136		resetIds();
137	}
138
139	public int newId(){
140		return currentId++;
141	}
142
143	protected void resetIds(){
144		currentId = currentGlobalId;
145	}
146
147}
148