package rajawali.animation;
import java.util.Stack;
import rajawali.math.Number3D;
public class BezierPath3D implements ISpline {
protected static final float DELTA = .00001f;
private Stack<CubicBezier3D> mPoints;
private int mNumPoints;
private boolean mCalculateTangents;
private Number3D mCurrentTangent;
public BezierPath3D() {
mPoints = new Stack<CubicBezier3D>();
mCurrentTangent = new Number3D();
}
public void addPoint(CubicBezier3D point) {
mPoints.add(point);
mNumPoints++;
}
public void addPoint(Number3D p0, Number3D p1, Number3D p2, Number3D p3) {
addPoint(new CubicBezier3D(p0, p1, p2, p3));
}
public Number3D calculatePoint(float t) {
if(mCalculateTangents) {
float prevt = t == 0 ? t + DELTA : t - DELTA;
float nextt = t == 1 ? t - DELTA : t + DELTA;
mCurrentTangent = p(prevt);
Number3D nextp = p(nextt);
mCurrentTangent.subtract(nextp);
mCurrentTangent.multiply(.5f);
mCurrentTangent.normalize();
}
return p(t);
}
protected Number3D p(float t) {
int currentIndex = (int) Math.floor((t == 1 ? t - .000001f : t) * mNumPoints);
CubicBezier3D currentPoint = mPoints.get(currentIndex);
float tdivnum = (t * mNumPoints) - currentIndex;
float u = 1 - tdivnum;
float tt = tdivnum * tdivnum;
float uu = u * u;
float ttt = tt * tdivnum;
float uuu = uu * u;
Number3D p = Number3D.multiply(currentPoint.p0, uuu);
p.add(Number3D.multiply(currentPoint.p1, 3 * uu * tdivnum));
p.add(Number3D.multiply(currentPoint.p2, 3 * u * tt));
p.add(Number3D.multiply(currentPoint.p3, ttt));
return p;
}
public class CubicBezier3D {
public Number3D p0, p1, p2, p3;
public CubicBezier3D(Number3D p0, Number3D p1, Number3D p2, Number3D p3) {
this.p0 = p0;
this.p1 = p1;
this.p2 = p2;
this.p3 = p3;
}
}
public void calculateTangents() {
}
public Number3D getCurrentTangent() {
return mCurrentTangent;
}
public void setCalculateTangents(boolean calculateTangents) {
this.mCalculateTangents = calculateTangents;
}
}