package rajawali.animation.mesh;
import android.opengl.GLES20;
import android.os.SystemClock;
import rajawali.Camera;
import rajawali.Geometry3D;
import rajawali.SerializedObject3D;
public class VertexAnimationObject3D extends AAnimationObject3D {
public VertexAnimationObject3D() {
super();
}
public VertexAnimationObject3D(SerializedObject3D ser) {
super(ser);
float[][] v = ser.getFrameVertices();
float[][] n = ser.getFrameNormals();
String[] frameNames = ser.getFrameNames();
mNumFrames = v.length;
for (int i = 0; i < mNumFrames; ++i) {
VertexAnimationFrame frame = new VertexAnimationFrame();
frame.getGeometry().setVertices(v[i]);
frame.getGeometry().setNormals(n[i]);
frame.getGeometry().createVertexAndNormalBuffersOnly();
frame.setName(frameNames[i]);
mFrames.add(frame);
}
}
public void setShaderParams(Camera camera) {
super.setShaderParams(camera);
long now = SystemClock.uptimeMillis();
// Calculate interpolation and frame delta (if playing)
if (isPlaying()) {
mInterpolation += (float) (now - mStartTime) * mFps / 1000;
mCurrentFrameIndex += (int) mInterpolation; // advance frame if interpolation >= 1
if (mCurrentFrameIndex > mEndFrameIndex) {
if (mLoop) {
mCurrentFrameIndex -= mStartFrameIndex;
mCurrentFrameIndex %= mEndFrameIndex - mStartFrameIndex;
mCurrentFrameIndex += mStartFrameIndex;
} else {
mCurrentFrameIndex = mEndFrameIndex;
pause();
}
}
mInterpolation -= (int) mInterpolation; // clamp to [0, 1)
}
// Update geometry (if current frame is different from before)
Geometry3D currentGeometry = ((VertexAnimationFrame) mFrames.get(mCurrentFrameIndex)).getGeometry();
if (mGeometry.getVertexBufferInfo() != currentGeometry.getVertexBufferInfo()) {
mGeometry.setVertexBufferInfo(currentGeometry.getVertexBufferInfo());
mGeometry.setNormalBufferInfo(currentGeometry.getNormalBufferInfo());
}
// Find geometry for next frame in sequence
Geometry3D nextGeometry = currentGeometry;
int nextFrame = mCurrentFrameIndex + 1;
if (nextFrame > mEndFrameIndex) {
if (mLoop) {
nextFrame = mStartFrameIndex;
} else {
nextFrame = mEndFrameIndex;
}
}
if (nextFrame >= 0 && nextFrame < mNumFrames) {
nextGeometry = ((VertexAnimationFrame) mFrames.get(nextFrame)).getGeometry();
}
// Set shader parameters
mMaterial.setInterpolation(mInterpolation);
mMaterial.setNextFrameVertices(nextGeometry.getVertexBufferInfo().bufferHandle);
mMaterial.setNextFrameNormals(nextGeometry.getNormalBufferInfo().bufferHandle);
mStartTime = now;
}
public void reload() {
for (int i = 0; i < mNumFrames; i++) {
mFrames.get(i).getGeometry().reload();
}
super.reload();
}
public VertexAnimationObject3D clone(boolean copyMaterial) {
VertexAnimationObject3D clone = new VertexAnimationObject3D();
clone.getGeometry().copyFromGeometry3D(mGeometry);
clone.isContainer(mIsContainerOnly);
if (copyMaterial)
clone.setMaterial(mMaterial, false);
for (int i = 0; i < mNumFrames; ++i) {
clone.addFrame(getFrame(i));
}
clone.setRotation(getRotation());
clone.setScale(getScale());
clone.setFps(mFps);
clone.mElementsBufferType = mGeometry.areOnlyShortBuffersSupported() ? GLES20.GL_UNSIGNED_SHORT : GLES20.GL_UNSIGNED_INT;
return clone;
}
public VertexAnimationObject3D clone() {
return clone(true);
}
}