/**
* Copyright (C) 2013 Gundog Studios LLC.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.gundogstudios.gl.custom;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.Random;
import com.gundogstudios.gl.Actions;
import com.gundogstudios.gl.BaseModel;
import com.gundogstudios.gl.ModelUtils;
import com.gundogstudios.modules.GLES11Module;
import com.gundogstudios.modules.Modules;
import com.gundogstudios.util.FastMath;
public class Spray extends BaseModel {
public static final String NAME = "spray";
private final static int FLOAT_SIZE = 4;
private final static int VERTEX_SIZE = 3 * FLOAT_SIZE;
private int currentFrame;
private int[] vertexBufferIds;
private int totalParticles;
private float pointSize;
public Spray(Spray system) {
super(system);
this.currentFrame = system.currentFrame;
this.vertexBufferIds = system.vertexBufferIds;
this.totalParticles = system.totalParticles;
this.pointSize = system.pointSize;
}
public Spray() {
super(Actions.ATTACK);
super.setRotates(true);
this.pointSize = ModelUtils.getParticleScaleSize();
this.totalParticles = 800 / ModelUtils.getBitmapScaleSize();
int maxFrames = ModelUtils.getMeshFrameRate();
Particle[] particles = new Particle[totalParticles];
float tileSize = 1f;
float x = tileSize * .15f;
float y = 0f;
float z = tileSize * .9f;
float speed = tileSize / 25f;
int count = totalParticles / 4;
initSpray(particles, 0, count, maxFrames, speed, x, y, z, true, 1f);
initSpray(particles, count, count, maxFrames, speed, x, y, z, true, -1f);
initSpray(particles, count * 2, count, maxFrames, speed, x, y, z, false, 1f);
initSpray(particles, count * 3, count, maxFrames, speed, x, y, z, false, -1f);
this.vertexBufferIds = new int[maxFrames];
generateAnimation(particles);
}
private void initSpray(Particle[] particles, int offset, int count, int maxFrames, float speed, float x, float y,
float z, boolean xMove, float direction) {
Random gen = new Random(System.currentTimeMillis());
float speedTwo = speed / 4f;
int frameModifier = 20 / maxFrames;
for (int i = offset; i < offset + count; i++) {
particles[i] = new Particle();
float dx = (gen.nextFloat() * speed + speed) * frameModifier;
float dy = (gen.nextFloat() * speedTwo) * (gen.nextBoolean() ? -1 : 1) * frameModifier;
float dz = (gen.nextFloat() * speedTwo) * (gen.nextBoolean() ? -1 : 1) * frameModifier;
if (xMove) {
particles[i].x = x * direction;
particles[i].y = y;
particles[i].dx = dx * direction;
particles[i].dy = dy;
particles[i].ax = 1f;
particles[i].ay = gen.nextFloat();
} else {
particles[i].x = y;
particles[i].y = x * direction;
particles[i].dx = dy;
particles[i].dy = dx * direction;
particles[i].ax = gen.nextFloat();
particles[i].ay = 1f;
}
particles[i].z = z;
particles[i].dz = dz;
particles[i].az = gen.nextFloat();
}
}
private void generateAnimation(Particle[] particles) {
GLES11Module gl = Modules.GL;
gl.glGenBuffers(vertexBufferIds.length, vertexBufferIds, 0);
ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(totalParticles * VERTEX_SIZE).order(
ByteOrder.nativeOrder());
FloatBuffer vertexBuffer = vertexByteBuffer.asFloatBuffer();
for (int j = 0; j < vertexBufferIds.length; j++) {
vertexBuffer.position(0);
for (int i = 0; i < totalParticles; i++) {
particles[i].dx = particles[i].dx * particles[i].ax;
particles[i].dy = particles[i].dy * particles[i].ay;
particles[i].dz = particles[i].dz * particles[i].az;
particles[i].x = particles[i].x + (particles[i].dx);
particles[i].y = particles[i].y + (particles[i].dy);
particles[i].z = particles[i].z + (particles[i].dz);
vertexBuffer.put(particles[i].x);
vertexBuffer.put(particles[i].y);
vertexBuffer.put(particles[i].z);
}
vertexBuffer.position(0);
vertexByteBuffer.position(0);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, vertexBufferIds[j]);
gl.glBufferData(GLES11Module.GL_ARRAY_BUFFER, vertexByteBuffer.capacity(), vertexByteBuffer,
GLES11Module.GL_STATIC_DRAW);
}
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, 0);
}
@Override
protected void drawModel(int timePassed) {
int currentFrame = FastMath.floor((((float) totalTime) / 1000f) * vertexBufferIds.length);
GLES11Module gl = Modules.GL;
// gl.glPointSize(pointSize);
gl.glEnableClientState(GLES11Module.GL_VERTEX_ARRAY);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, vertexBufferIds[currentFrame]);
gl.glVertexPointer(3, GLES11Module.GL_FLOAT, VERTEX_SIZE, 0);
gl.glDrawArrays(GLES11Module.GL_POINTS, 0, totalParticles);
gl.glDisableClientState(GLES11Module.GL_VERTEX_ARRAY);
// gl.glPointSize(1f);
gl.glBindBuffer(GLES11Module.GL_ARRAY_BUFFER, 0);
super.totalTime = (totalTime + timePassed) % 1000;
}
@Override
public void reset() {
totalTime = 0;
}
private class Particle {
public float x, y, z;
public float dx, dy, dz;
public float ax, ay, az;
public Particle() {
}
}
}