well, unfortunately i dont see much room for optimization except hardware skinning with shaders. and i dont have any plan to implement hardware skinning at least for now
Well...this is Android. Even with 2.3, the VM is still crappy to a degree, so you can always do some micro. It did this to the formerly more readable applySkeletonPose()-method in Animated3D:
public void applySkeletonPose() {
SimpleVector[] destMesh = this.destMesh;
SimpleVector[] destNormals = this.destNormals;
// if pose animation is applied, destination vertices are already initialized based on source and offseted, so use them
SimpleVector[] sourceMesh = !destMeshDirty ? destMesh : this.sourceMesh;
//SimpleVector[] sourceNormals = !destMeshDirty ? destNormals : this.sourceNormals;
SimpleVector[] sourceNormals = this.sourceNormals;
SimpleVector vertexTemp = this.vertexTemp;
SimpleVector vertexSum = this.vertexSum;
SimpleVector normalTemp = this.normalTemp;
SimpleVector normalSum = this.normalSum;
// Cycle through each vertex
int end=sourceMesh.length;
float[][] skinweights=skin.weights;
short[][] skinjointIndices=skin.jointIndices;
for (int i = 0; i < end; i++) {
// zero out our sum var
vertexSum.x=0f;
vertexSum.y=0f;
vertexSum.z=0f;
normalSum.x=0f;
normalSum.y=0f;
normalSum.z=0f;
// pull in joint data
final float[] weights = skinweights[i];
final short[] jointIndices = skinjointIndices[i];
SimpleVector sourceMeshi=sourceMesh[i];
SimpleVector sourceNormalsi=sourceNormals[i];
Matrix[] currentPosepalette=currentPose.palette;
for (int j = 0; j < Skeleton.MAX_JOINTS_PER_VERTEX; j++) {
final float weightsj=weights[j];
if (weightsj == 0) {
continue;
}
Matrix mat=currentPosepalette[jointIndices[j]];
// -- vertices --
vertexTemp.x=sourceMeshi.x;
vertexTemp.y=sourceMeshi.y;
vertexTemp.z=sourceMeshi.z;
// Multiply our vertex by the matrix pallete entry
vertexTemp.matMul(mat);
// Sum, weighted.
vertexTemp.x*=weightsj;
vertexTemp.y*=weightsj;
vertexTemp.z*=weightsj;
vertexSum.x+=vertexTemp.x;
vertexSum.y+=vertexTemp.y;
vertexSum.z+=vertexTemp.z;
// -- normals --
normalTemp.x=sourceNormalsi.x;
normalTemp.y=sourceNormalsi.y;
normalTemp.z=sourceNormalsi.z;
// Multiply our vertex by the matrix pallete entry
normalTemp.rotate(mat);
// Sum, weighted.
normalTemp.x*=weightsj;
normalTemp.y*=weightsj;
normalTemp.z*=weightsj;
normalSum.x+=normalTemp.x;
normalSum.y+=normalTemp.y;
normalSum.z+=normalTemp.z;
}
// Store sum into _meshData
destMesh[i].set(vertexSum);
destNormals[i].set(normalSum);
} // for vertices
destMeshDirty = true;
}
For testing purposes, i changed your demo apk to apply the same animation 10times to the ninja in each frame. With my uglification of the method, the frame rate went up from 21 fps to 26 fps on my Nexus S. But then again, the method looks like crap now (reminds me of jPCT-AE's inner loops somehow...
). Keep in mind that Android doesn't like method calls as i can't inline simple methods and it doesn't like array access either, i.e. instead of doing a sourceMesh[ i ] for each j, do it once before entering the j-loop.