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 {
public:

	// ATTRIBUTES
	float v_coord[3];

	// ACCESSORS
	float* get_coord();
	  
	// MANIPULATORS
	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.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.