+#define MAX_BONES 256
+ // vertex weighted skeletal
+ int i, k;
+ int blends;
+ float desiredscale[3];
+ float boneposerelative[MAX_BONES][12];
+ float *matrix, m[12], bonepose[MAX_BONES][12];
+
+ // interpolate matrices and concatenate them to their parents
+ for (i = 0;i < model->num_bones;i++)
+ {
+ for (k = 0;k < 12;k++)
+ m[k] = 0;
+ VectorClear(desiredscale);
+ for (blends = 0;blends < MAX_FRAMEBLENDS && frameblend[blends].lerp > 0;blends++)
+ {
+ matrix = model->data_poses + (frameblend[blends].subframe * model->num_bones + i) * 12;
+ for (k = 0;k < 12;k++)
+ m[k] += matrix[k] * frameblend[blends].lerp;
+ desiredscale[0] += frameblend[blends].lerp * VectorLength(matrix );
+ desiredscale[1] += frameblend[blends].lerp * VectorLength(matrix + 4);
+ desiredscale[2] += frameblend[blends].lerp * VectorLength(matrix + 8);
+ }
+ VectorNormalize(m );
+ VectorNormalize(m + 4);
+ VectorNormalize(m + 8);
+ VectorScale(m , desiredscale[0], m );
+ VectorScale(m + 4, desiredscale[1], m + 4);
+ VectorScale(m + 8, desiredscale[2], m + 8);
+ if (i == r_skeletal_debugbone.integer)
+ m[r_skeletal_debugbonecomponent.integer % 12] += r_skeletal_debugbonevalue.value;
+ m[3] *= r_skeletal_debugtranslatex.value;
+ m[7] *= r_skeletal_debugtranslatey.value;
+ m[11] *= r_skeletal_debugtranslatez.value;
+ if (model->data_bones[i].parent >= 0)
+ R_ConcatTransforms(bonepose[model->data_bones[i].parent], m, bonepose[i]);
+ else
+ for (k = 0;k < 12;k++)
+ bonepose[i][k] = m[k];
+ // create a relative deformation matrix to describe displacement
+ // from the base mesh, which is used by the actual weighting
+ R_ConcatTransforms(bonepose[i], model->data_baseboneposeinverse + i * 12, boneposerelative[i]);
+ }
+ // blend the vertex bone weights
+ // special case for the extremely common wf[0] == 1 because it saves 3 multiplies per array when compared to the other case (w[0] is always 1 if only one bone controls this vertex, artists only use multiple bones for certain special cases)
+ // special case for the first bone because it avoids the need to memset the arrays before filling
+ if (vertex3f)