package com.bulletphysics.util;
import javax.vecmath.Matrix3f;
import javax.vecmath.Quat4f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4f;
import com.bulletphysics.extras.gimpact.BoxCollision.AABB;
import com.bulletphysics.extras.gimpact.BoxCollision.BoxBoxTransformCache;
import com.bulletphysics.extras.gimpact.PrimitiveTriangle;
import com.bulletphysics.extras.gimpact.TriangleContact;
import com.bulletphysics.linearmath.Transform;
public class Stack {
private static final int TYPE_VECTOR3F = 0;
private static final int TYPE_VECTOR4F = 1;
private static final int TYPE_AABB = 2;
private static final int TYPE_TRANSFORM = 3;
private static final int TYPE_MATRIX3F = 4;
private static final int TYPE_QUAT4F = 5;
private static final int TYPE_BOX_BOX_TRANSFORM_CACHE = 6;
private static final int TYPE_PRIMITIVE_TRIANGLE = 7;
private static final int TYPE_TRIANGLE_CONTACT = 8;
private static ThreadLocal<Stack> stack = new ThreadLocal<Stack>();
private final int[] stackPositions = new int[9];
private final int[] types = new int[65536];
private int sp;
private final ObjectArrayList<Vector3f> vector3fStack = new ObjectArrayList<Vector3f>();
private final ObjectArrayList<Vector4f> vector4fStack = new ObjectArrayList<Vector4f>();
private final ObjectArrayList<AABB> aabbStack = new ObjectArrayList<AABB>();
private final ObjectArrayList<Transform> transformStack = new ObjectArrayList<Transform>();
private final ObjectArrayList<Matrix3f> matrix3fStack = new ObjectArrayList<Matrix3f>();
private final ObjectArrayList<Quat4f> quat4fStack = new ObjectArrayList<Quat4f>();
private final ObjectArrayList<BoxBoxTransformCache> boxBoxTransformCacheStack = new ObjectArrayList<BoxBoxTransformCache>();
private final ObjectArrayList<PrimitiveTriangle> primitiveTriangleStack = new ObjectArrayList<PrimitiveTriangle>();
private final ObjectArrayList<TriangleContact> triangleContactStack = new ObjectArrayList<TriangleContact>();
public static void libraryCleanCurrentThread() {
Stack stack = Stack.stack.get();
if (stack != null) {
stack.sp = 0;
for (int i = 0; i < stack.stackPositions.length; i++) {
stack.stackPositions[i] = 0;
}
}
}
public Vector3f alloc(Vector3f original) {
Vector3f v = allocVector3f();
v.set(original);
return v;
}
public Transform alloc(Transform original) {
Transform t = allocTransform();
t.set(original);
return t;
}
public Matrix3f alloc(Matrix3f original) {
Matrix3f m = allocMatrix3f();
m.set(original);
return m;
}
public AABB alloc(AABB box) {
AABB aabb = allocAABB();
aabb.set(box);
return aabb;
}
public Quat4f alloc(Quat4f rotation) {
Quat4f q = allocQuat4f();
q.set(rotation);
return q;
}
public Vector3f allocVector3f() {
types[sp++] = TYPE_VECTOR3F;
int pos = stackPositions[TYPE_VECTOR3F]++;
if (vector3fStack.size() <= pos) {
vector3fStack.add(new Vector3f());
}
return vector3fStack.get(pos);
}
public Matrix3f allocMatrix3f() {
types[sp++] = TYPE_MATRIX3F;
int pos = stackPositions[TYPE_MATRIX3F]++;
if (matrix3fStack.size() <= pos) {
matrix3fStack.add(new Matrix3f());
}
return matrix3fStack.get(pos);
}
public Quat4f allocQuat4f() {
types[sp++] = TYPE_QUAT4F;
int pos = stackPositions[TYPE_QUAT4F]++;
if (quat4fStack.size() <= pos) {
quat4fStack.add(new Quat4f());
}
return quat4fStack.get(pos);
}
public Transform allocTransform() {
types[sp++] = TYPE_TRANSFORM;
int pos = stackPositions[TYPE_TRANSFORM]++;
if (transformStack.size() <= pos) {
transformStack.add(new Transform());
}
return transformStack.get(pos);
}
public Vector4f allocVector4f() {
types[sp++] = TYPE_VECTOR4F;
int pos = stackPositions[TYPE_VECTOR4F]++;
if (vector4fStack.size() <= pos) {
vector4fStack.add(new Vector4f());
}
return vector4fStack.get(pos);
}
public AABB allocAABB() {
types[sp++] = TYPE_AABB;
int pos = stackPositions[TYPE_AABB]++;
if (aabbStack.size() <= pos) {
aabbStack.add(new AABB());
}
return aabbStack.get(pos);
}
public BoxBoxTransformCache allocBoxBoxTransformCache() {
types[sp++] = TYPE_BOX_BOX_TRANSFORM_CACHE;
int pos = stackPositions[TYPE_BOX_BOX_TRANSFORM_CACHE]++;
if (boxBoxTransformCacheStack.size() <= pos) {
boxBoxTransformCacheStack.add(new BoxBoxTransformCache());
}
return boxBoxTransformCacheStack.get(pos);
}
public PrimitiveTriangle allocPrimitiveTriangle() {
types[sp++] = TYPE_PRIMITIVE_TRIANGLE;
int pos = stackPositions[TYPE_PRIMITIVE_TRIANGLE]++;
if (primitiveTriangleStack.size() <= pos) {
primitiveTriangleStack.add(new PrimitiveTriangle());
}
return primitiveTriangleStack.get(pos);
}
public TriangleContact allocTriangleContact() {
types[sp++] = TYPE_TRIANGLE_CONTACT;
int pos = stackPositions[TYPE_TRIANGLE_CONTACT]++;
if (triangleContactStack.size() <= pos) {
triangleContactStack.add(new TriangleContact());
}
return triangleContactStack.get(pos);
}
public static Stack enter() {
Stack stack = Stack.stack.get();
if (stack == null) {
stack = new Stack();
Stack.stack.set(stack);
}
stack.types[stack.sp++] = -1;
return stack;
}
public int getSp() {
return sp;
}
public void leave() {
while(true) {
int type = types[--sp];
if (type == -1) {
break;
}
stackPositions[type]--;
}
}
public void leave(int savedSp) {
for (int i = savedSp; i < sp; i++) {
int type = types[i];
if (type != -1) {
stackPositions[type]--;
}
}
this.sp = savedSp - 1;
assert types[sp] == -1;
}
}