package com.igorcrevar.rolloverchuck.objects;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Mesh;
import com.badlogic.gdx.graphics.VertexAttribute;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector3;
import com.igorcrevar.rolloverchuck.GameData;
import com.igorcrevar.rolloverchuck.GameManager;
public class TrailObject {
private static final int MAX_QUADS = 80;
private static final int QUAD_SIZE = 6 * 3;
private static final int FRAME_SKIP = 4;
private Mesh mesh = new Mesh(false, MAX_QUADS * 6, 0, VertexAttribute.Position());
private ShaderProgram shader;
private int currentQuads;
private float[] vertices = new float[MAX_QUADS * QUAD_SIZE];
private Color colorFactor = new Color(1.0f, 1.0f, 1.0f, 0.5f);
private Vector3 tmp = new Vector3();
private Vector3 tmp2 = new Vector3();
private int frameSkipper = 0;
public TrailObject(GameManager gameManager) {
shader = gameManager.getShader("simple");
}
public void init() {
currentQuads = 0;
frameSkipper = 0;
}
public void update(ChuckObject co, float deltaTime) {
/*++frameSkipper;
if (frameSkipper < FRAME_SKIP) {
continue;
}*/
frameSkipper = 0;
Vector3 currPos = co.getCurrentPosition();
Vector3 prevPos = co.getPrevFramePosition();
if (!currPos.idt(prevPos)) {
float radius = co.getCurrentRadius();
// tmp will have direction of moving
tmp.set(prevPos).sub(currPos).nor();
tmp.scl(radius * 0.8f);
// vector tmp and tmp2 must be orthogonal (perpendicular)
// so their dot product equals to zero
// y coordinate doesn't matter set it to 0
// we have one "jednacina" with two variables
// but what is meter that tmp2 must be direction vector (normalized)
// so we guess some value for X and calculate Z component according to chosen X
// calculate "Left" orthogonal ("right" is -"left")
if (tmp.z != 0) {
tmp2.set(-1f, 0f, 0f);
tmp2.z = (-tmp2.x * tmp.x) / tmp.z;
}
else {
tmp2.set(0f, 0f, 1f);
}
// don't want trail to be equal width of chuck
tmp2.nor().scl(radius * 0.75f);
// move current vertices if needed;
if (currentQuads > 0) {
int len = Math.min(MAX_QUADS - 1, currentQuads);
System.arraycopy(vertices, 0, vertices, QUAD_SIZE, len * QUAD_SIZE);
}
Vector3 zeroPos = GameData.ObjectZero;
float defY = radius * 1.5f + zeroPos.y;
vertices[0] = currPos.x + zeroPos.x + tmp.x + tmp2.x;
vertices[1] = defY;
vertices[2] = currPos.z + zeroPos.z + tmp.z + tmp2.z;
vertices[3] = vertices[9] = currPos.x + zeroPos.x + tmp.x - tmp2.x;
vertices[4] = vertices[10] = defY;
vertices[5] = vertices[11] = currPos.z + zeroPos.z + tmp.z - tmp2.z;
vertices[6] = vertices[15] = vertices[QUAD_SIZE];
vertices[7] = vertices[16] = vertices[QUAD_SIZE + 1];
vertices[8] = vertices[17] = vertices[QUAD_SIZE + 2];
vertices[12] = vertices[QUAD_SIZE + 3];
vertices[13] = vertices[QUAD_SIZE + 4];
vertices[14] = vertices[QUAD_SIZE + 5];
// else {
// vertices[6] = vertices[15] = prevPos.x + zeroPos.x + tmp2.x;
// vertices[7] = vertices[16] = defY;
// vertices[8] = vertices[17] = prevPos.z + zeroPos.z + tmp2.z;
// vertices[12] = prevPos.x + zeroPos.x - tmp2.x;
// vertices[13] = defY;
// vertices[14] = prevPos.z + zeroPos.z - tmp2.z;
// }
// increment number of quads
currentQuads = Math.min(currentQuads + 1, MAX_QUADS);
// UPDATE MESH
mesh.setVertices(vertices);
// mesh.updateVertices(0, vertices);//
}
else {
currentQuads = Math.max(currentQuads - 1, 0);
}
}
public void draw(Matrix4 projViewMatrix) {
if (currentQuads > 1) {
shader.begin();
shader.setUniformMatrix("u_projectionViewMatrix", projViewMatrix);
shader.setUniformf("u_color_factor", colorFactor);
mesh.render(shader, GL20.GL_TRIANGLES, 0, (currentQuads - 1) * QUAD_SIZE);
shader.end();
}
}
public void dispose() {
mesh.dispose();
}
// tmp2 will have 0-th dot of quad
//float angle = (float) Math.atan2(currPos.z, currPos.x);
//tmp2.set(0.0f, 0.0f, -1.0f);
//tmp2.x = (float)(tmp2.x * Math.cos(angle) - tmp2.z * Math.sin(angle));
//tmp2.z = (float)(tmp2.z * Math.cos(angle) + tmp2.x * Math.sin(angle));
//tmp2.scl(radius);
}