Skip to content

Instantly share code, notes, and snippets.

@hiepnd
Created November 26, 2014 03:25
Show Gist options
  • Save hiepnd/5b36227fe45b74aa1108 to your computer and use it in GitHub Desktop.
Save hiepnd/5b36227fe45b74aa1108 to your computer and use it in GitHub Desktop.
Amazing Wire's tail, rewritten in libgdx
package com.badlogicgames.plane;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Camera;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.glutils.ImmediateModeRenderer20;
import com.badlogic.gdx.graphics.glutils.ShaderProgram;
import com.badlogic.gdx.math.Vector2;
public class Tail {
private static final int MaxTailBufferCapacity = 100;
private static final int TailVertexSize = 2;
private static final float SnakeLineWidth = 20;
private Color color;
private int bufferCount;
private Vector2 points[];
private FloatBuffer buffer;
private ShaderProgram shader;
public Tail() {
bufferCount = 0;
color = Color.RED;
ByteBuffer buf = ByteBuffer.allocateDirect(MaxTailBufferCapacity*2*TailVertexSize*4);
buf.order(ByteOrder.nativeOrder());
buffer = buf.asFloatBuffer();
points = new Vector2[MaxTailBufferCapacity];
shader = ImmediateModeRenderer20.createDefaultShader(false, true, 0);
}
public void push(Vector2 point, float dx) {
bufferCount = Math.min(bufferCount+1, MaxTailBufferCapacity);
// Shift
for (int i=bufferCount-1; i>0; i--) {
points[i] = new Vector2(points[i-1].x + dx, points[i-1].y);
}
points[0] = point;
this.generate();
}
private void generate() {
if (bufferCount <= 0) {
return;
}
Vector2 o1 = new Vector2();
Vector2 o2 = new Vector2();
for (int i=1; i<=bufferCount-2; i++) {
unnamed(points[i-1], points[i], points[i+1], SnakeLineWidth/2, o1, o2);
buffer.put(2*i*TailVertexSize, o1.x);
buffer.put(2*i*TailVertexSize+1, o1.y);
buffer.put((2*i+1)*TailVertexSize, o2.x);
buffer.put((2*i+1)*TailVertexSize+1, o2.y);
}
buffer.put(0, points[0].x);
buffer.put(1, points[0].y);
buffer.put(TailVertexSize, points[0].x);
buffer.put(TailVertexSize+1, points[0].y);
buffer.put(2*(bufferCount - 1)*TailVertexSize, points[bufferCount-1].x);
buffer.put(2*(bufferCount - 1)*TailVertexSize+1, points[bufferCount-1].y);
buffer.put((2*(bufferCount - 1)+1)*TailVertexSize, points[bufferCount-1].x);
buffer.put((2*(bufferCount - 1)+1)*TailVertexSize+1, points[bufferCount-1].y);
if (bufferCount > 1) {
unnamed2(points[1], points[0], SnakeLineWidth/2, o1, o2);
buffer.put(0, o2.x);
buffer.put(1, o2.y);
buffer.put(TailVertexSize, o1.x);
buffer.put(TailVertexSize+1, o1.y);
}
}
// Vertex 2, Color 4
public void draw(Camera camera) {
shader.begin();
shader.setUniformMatrix("u_projModelView", camera.combined);
int loc = shader.getAttributeLocation(ShaderProgram.POSITION_ATTRIBUTE);
Gdx.gl20.glEnableVertexAttribArray(loc);
buffer.position(0);
Gdx.gl20.glVertexAttribPointer(loc, 2, GL20.GL_FLOAT, false, TailVertexSize*4, buffer);
shader.setAttributef(ShaderProgram.COLOR_ATTRIBUTE, color.r, color.g, color.b, color.a);
Gdx.gl20.glDrawArrays(GL20.GL_TRIANGLE_STRIP, 0, bufferCount * 2);
shader.end();
}
private static void unnamed(final Vector2 p0, final Vector2 p1, final Vector2 p2, float d, Vector2 o1, Vector2 o2) {
Vector2 v0 = new Vector2(p0).sub(p1);
Vector2 v1 = new Vector2(p2).sub(p1);
float a = angle(v0, v1);
float x = d / (float)Math.sin(a/2);
float a2 = -a/2 + v0.getAngleRad();
Vector2 n = new Vector2(x * (float)Math.cos(a2), x * (float)Math.sin(a2));
o1.set(new Vector2(p1).add(n));
o2.set(new Vector2(p1).sub(n));
}
private static void unnamed2(final Vector2 p0, final Vector2 p1, float d, Vector2 o1, Vector2 o2) {
Vector2 v0 = new Vector2(p1).sub(p0);
Vector2 vp = new Vector2(-v0.y, v0.x);
vp.nor();
o1.set(new Vector2(p1).mulAdd(vp, d));
o2.set(new Vector2(p1).mulAdd(vp, -d));
}
private static float angle(Vector2 v1, Vector2 v2) {
Vector2 a2 = new Vector2(v1).nor();
Vector2 b2 = new Vector2(v2).nor();
return (float) Math.atan2(a2.crs(b2), a2.dot(b2));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment