+static void Mod_BuildBaseBonePoses(void)
+{
+ int i, k;
+ double scale;
+ float *basebonepose = Mem_Alloc(tempmempool, loadmodel->num_bones * sizeof(float[12]));
+ float *in12f = loadmodel->data_poses;
+ float *out12f = basebonepose;
+ float *outinv12f = loadmodel->data_baseboneposeinverse;
+ for (i = 0;i < loadmodel->num_bones;i++, in12f += 12, out12f += 12, outinv12f += 12)
+ {
+ if (loadmodel->data_bones[i].parent >= 0)
+ R_ConcatTransforms(basebonepose + 12 * loadmodel->data_bones[i].parent, in12f, out12f);
+ else
+ for (k = 0;k < 12;k++)
+ out12f[k] = in12f[k];
+
+ // invert The Matrix
+
+ // we only support uniform scaling, so assume the first row is enough
+ // (note the lack of sqrt here, because we're trying to undo the scaling,
+ // this means multiplying by the inverse scale twice - squaring it, which
+ // makes the sqrt a waste of time)
+ scale = 1.0 / (out12f[ 0] * out12f[ 0] + out12f[ 1] * out12f[ 1] + out12f[ 2] * out12f[ 2]);
+
+ // invert the rotation by transposing and multiplying by the squared
+ // recipricol of the input matrix scale as described above
+ outinv12f[ 0] = (float)(out12f[ 0] * scale);
+ outinv12f[ 1] = (float)(out12f[ 4] * scale);
+ outinv12f[ 2] = (float)(out12f[ 8] * scale);
+ outinv12f[ 4] = (float)(out12f[ 1] * scale);
+ outinv12f[ 5] = (float)(out12f[ 5] * scale);
+ outinv12f[ 6] = (float)(out12f[ 9] * scale);
+ outinv12f[ 8] = (float)(out12f[ 2] * scale);
+ outinv12f[ 9] = (float)(out12f[ 6] * scale);
+ outinv12f[10] = (float)(out12f[10] * scale);
+
+ // invert the translate
+ outinv12f[ 3] = -(out12f[ 3] * outinv12f[ 0] + out12f[ 7] * outinv12f[ 1] + out12f[11] * outinv12f[ 2]);
+ outinv12f[ 7] = -(out12f[ 3] * outinv12f[ 4] + out12f[ 7] * outinv12f[ 5] + out12f[11] * outinv12f[ 6]);
+ outinv12f[11] = -(out12f[ 3] * outinv12f[ 8] + out12f[ 7] * outinv12f[ 9] + out12f[11] * outinv12f[10]);
+ }
+ Mem_Free(basebonepose);
+}
+
+static void Mod_Alias_CalculateBoundingBox(void)
+{
+ int i, j;
+ int vnum;
+ qboolean firstvertex = true;
+ float dist, yawradius, radius;
+ float *v;
+ float *vertex3f;
+ frameblend_t frameblend[4];
+ memset(frameblend, 0, sizeof(frameblend));
+ frameblend[0].lerp = 1;
+ vertex3f = Mem_Alloc(loadmodel->mempool, loadmodel->surfmesh.num_vertices * sizeof(float[3]));
+ VectorClear(loadmodel->normalmins);
+ VectorClear(loadmodel->normalmaxs);
+ yawradius = 0;
+ radius = 0;
+ for (i = 0;i < loadmodel->numframes;i++)
+ {
+ for (j = 0, frameblend[0].frame = loadmodel->animscenes[i].firstframe;j < loadmodel->animscenes[i].framecount;j++, frameblend[0].frame++)
+ {
+ Mod_Alias_GetMesh_Vertices(loadmodel, frameblend, vertex3f, NULL, NULL, NULL);
+ for (vnum = 0, v = vertex3f;vnum < loadmodel->surfmesh.num_vertices;vnum++, v += 3)
+ {
+ if (firstvertex)
+ {
+ firstvertex = false;
+ VectorCopy(v, loadmodel->normalmins);
+ VectorCopy(v, loadmodel->normalmaxs);
+ }
+ else
+ {
+ if (loadmodel->normalmins[0] > v[0]) loadmodel->normalmins[0] = v[0];
+ if (loadmodel->normalmins[1] > v[1]) loadmodel->normalmins[1] = v[1];
+ if (loadmodel->normalmins[2] > v[2]) loadmodel->normalmins[2] = v[2];
+ if (loadmodel->normalmaxs[0] < v[0]) loadmodel->normalmaxs[0] = v[0];
+ if (loadmodel->normalmaxs[1] < v[1]) loadmodel->normalmaxs[1] = v[1];
+ if (loadmodel->normalmaxs[2] < v[2]) loadmodel->normalmaxs[2] = v[2];
+ }
+ dist = v[0] * v[0] + v[1] * v[1];
+ if (yawradius < dist)
+ yawradius = dist;
+ dist += v[2] * v[2];
+ if (radius < dist)
+ radius = dist;
+ }
+ }
+ }
+ Mem_Free(vertex3f);
+ radius = sqrt(radius);
+ yawradius = sqrt(yawradius);
+ loadmodel->yawmins[0] = loadmodel->yawmins[1] = -yawradius;
+ loadmodel->yawmaxs[0] = loadmodel->yawmaxs[1] = yawradius;
+ loadmodel->yawmins[2] = loadmodel->normalmins[2];
+ loadmodel->yawmaxs[2] = loadmodel->normalmaxs[2];
+ loadmodel->rotatedmins[0] = loadmodel->rotatedmins[1] = loadmodel->rotatedmins[2] = -radius;
+ loadmodel->rotatedmaxs[0] = loadmodel->rotatedmaxs[1] = loadmodel->rotatedmaxs[2] = radius;
+ loadmodel->radius = radius;
+ loadmodel->radius2 = radius * radius;
+}
+
+static void Mod_Alias_MorphMesh_CompileFrames(void)