/**
* 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 Explosion extends BaseModel {
public static final String NAME = "explosion";
private final static int FLOAT_SIZE = 4;
private final static int VERTEX_SIZE = 3 * FLOAT_SIZE;
private int[] vertexBufferIds;
private int totalParticles;
private float pointSize;
public Explosion(Explosion system) {
super(system);
this.vertexBufferIds = system.vertexBufferIds;
this.totalParticles = system.totalParticles;
this.pointSize = system.pointSize;
}
public Explosion() {
super(Actions.DEATH);
this.pointSize = ModelUtils.getParticleScaleSize();
this.totalParticles = 400 / ModelUtils.getBitmapScaleSize();
int maxFrames = ModelUtils.getMeshFrameRate();
Particle[] particles = new Particle[totalParticles];
initExplosion(particles, maxFrames, 1f);
this.vertexBufferIds = new int[maxFrames];
generateAnimation(particles);
}
private void initExplosion(Particle[] particles, int maxFrames, float tileSize) {
Random gen = new Random(System.currentTimeMillis());
for (int i = 0; i < totalParticles; i++) {
particles[i] = new Particle();
particles[i].x = 0f;
particles[i].y = 0f;
particles[i].z = 0f;
int frameModifier = 20 / maxFrames;
float speed = tileSize / 40f;
float totalMovement = speed * 1.75f;
float dx = gen.nextFloat() * speed;
particles[i].dx = dx * (gen.nextBoolean() ? -1 : 1) * frameModifier;
totalMovement -= dx;
float dy = FastMath.min(gen.nextFloat() * speed, totalMovement);
particles[i].dy = dy * (gen.nextBoolean() ? -1 : 1) * frameModifier;
totalMovement -= dy;
float dz = FastMath.min(gen.nextFloat() * speed, totalMovement);
particles[i].dz = dz * (gen.nextBoolean() ? -1 : 1) * frameModifier;
particles[i].ax = 1f;
particles[i].ay = 1f;
particles[i].az = 1f;
}
}
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) {
if (totalTime >= 1000f)
return;
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() {
}
}
}