Hi guys,

I'm implementing a viewer for skinned character animation. Each frame of animation requires thousands of (4x4 matrix * vector) and (float * 4x4 matrix) calculations.

This is the section that is repeated thousands of times:

// For each vertex influenced by bone
for (int j=0; j<(int)Character::bones[i].get_vertices().size(); j++)
      static vector<float> matrix(16, 0.0f);
      index = Character::bones[i].get_vertices()[j];

      // Matrix is multiplication of final_matrix and weight
      multiply_matrices(Character::bones[i].get_weights()[j], final_matrix, matrix);
      // Transform pose vertex by matrix
      multiply_matrix_vertex(matrix, Character::mesh.get_vertices()[index].get_coord(), vers[index]);

index is a static int that is assigned an index value used to retrieve a vertex from a vector of vertices 'vers'.

.get_weights() returns a vector of floats by reference
final_matrix and t_matrix are static vector<float> that have a size of 16.

.get_coord() returns a pointer to an array of 3 floats, which are the xyz coordinates of the vertex.

'matrix' and 'vers[index]' are changed by the functions they are called with (hence no return values).

vers[index] is a Ver2, where Ver2 is:

class Ver2 {

	float v_coord[3];

	float* get_coord();
	void add(float&, float&, float&); 

Now for the matrix functions. I should note that I represent a matrix by a vector<float> with size 16. Where matrix[0]...matrix[3] is the first row, matrix[4]...matrix[7] is the second etc.:

Multiplying each element in the matrix by a float

void multiply_matrices(float& weight, vector<float>& matrix, vector<float>& ret)
	for (int i=0; i<(int)matrix.size(); i++)
		ret[i] = matrix[i] * weight;

This multiplies a matrix by an array of floats (coordinates), and then adds the results to the current coordinates in 'v'.

void multiply_matrix_vertex(vector<float>& matrix, float* pose_v, Ver2& v)
   static float x;
   static float y;
   static float z;

   x = ( (matrix[0] * pose_v[0]) +
           (matrix[1] * pose_v[1]) +
           (matrix[2] * pose_v[2]) +
           (matrix[3]) );

   y = ( (matrix[4] * pose_v[0]) +
           (matrix[5] * pose_v[1]) +
           (matrix[6] * pose_v[2]) +
           (matrix[7]) );

   z = ( (matrix[8] * pose_v[0]) +
           (matrix[9] * pose_v[1]) +
           (matrix[10] * pose_v[2]) +
           (matrix[11]) );

   v.add(x, y, z);

Now the issue I have is that these functions cause a massive fps hit. Without the multiply_matrices/multiply_matrix_vertex calls, I run at 110fps. With them, i'm on 14fps.

The model only has about 2000 polygons, and I'm running on a very good computer, so no 'get a better pc', or 'use simpler model' responses please =)

What can I do to increase the efficiency of these functions?

I doubt you can significantly speed these calculations up by "normal" means. Take a look at SIMD (aka SSE) capabilities of your very good computer.

This article has been dead for over six months. Start a new discussion instead.