int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, int startTagIndex, qhandle_t frameModel, int startFrame, qhandle_t endFrameModel, int endFrame, float frac, const char *tagName ) { iqmData_t *startSkeleton, *endSkeleton; float jointMats[IQM_MAX_JOINTS * 12]; int joint; char *names = data->names; // get joint number by reading the joint names for( joint = 0; joint < data->num_joints; joint++ ) { if( joint >= startTagIndex && !strcmp( tagName, names ) ) break; names += strlen( names ) + 1; } if( joint >= data->num_joints ) { return -1; } // just checking if tag exists if( !tag ) { return joint; } startSkeleton = R_GetIQMModelDataByHandle( frameModel, data ); endSkeleton = R_GetIQMModelDataByHandle( endFrameModel, data ); ComputeJointMats( data, startSkeleton, endSkeleton, startFrame, endFrame, frac, jointMats ); tag->axis[0][0] = jointMats[12 * joint + 0]; tag->axis[1][0] = jointMats[12 * joint + 1]; tag->axis[2][0] = jointMats[12 * joint + 2]; tag->origin[0] = jointMats[12 * joint + 3]; tag->axis[0][1] = jointMats[12 * joint + 4]; tag->axis[1][1] = jointMats[12 * joint + 5]; tag->axis[2][1] = jointMats[12 * joint + 6]; tag->origin[1] = jointMats[12 * joint + 7]; tag->axis[0][2] = jointMats[12 * joint + 8]; tag->axis[1][2] = jointMats[12 * joint + 9]; tag->axis[2][2] = jointMats[12 * joint + 10]; tag->origin[2] = jointMats[12 * joint + 11]; return joint; }
int R_IQMLerpTag(orientation_t* tag, iqmData_t* data, int startFrame, int endFrame, float frac, const char* tagName) { float jointMats[IQM_MAX_JOINTS * 12]; int joint; char* names = data->names; // get joint number by reading the joint names for (joint = 0; joint < data->num_joints; joint++) { if (!strcmp(tagName, names)) break; names += strlen(names) + 1; } if (joint >= data->num_joints) { AxisClear(tag->axis); VectorClear(tag->origin); return qfalse; } ComputeJointMats(data, startFrame, endFrame, frac, jointMats); tag->axis[0][0] = jointMats[12 * joint + 0]; tag->axis[1][0] = jointMats[12 * joint + 1]; tag->axis[2][0] = jointMats[12 * joint + 2]; tag->origin[0] = jointMats[12 * joint + 3]; tag->axis[0][1] = jointMats[12 * joint + 4]; tag->axis[1][1] = jointMats[12 * joint + 5]; tag->axis[2][1] = jointMats[12 * joint + 6]; tag->origin[1] = jointMats[12 * joint + 7]; tag->axis[0][2] = jointMats[12 * joint + 8]; tag->axis[1][2] = jointMats[12 * joint + 9]; tag->axis[2][2] = jointMats[12 * joint + 10]; tag->origin[2] = jointMats[12 * joint + 11]; return qtrue; }
/* ================= RB_AddIQMSurfaces Compute vertices for this model surface ================= */ void RB_IQMSurfaceAnim(surfaceType_t* surface) { srfIQModel_t* surf = (srfIQModel_t*)surface; iqmData_t* data = surf->data; float jointMats[IQM_MAX_JOINTS * 12]; int i; vec4_t* outXYZ = &tess.xyz[tess.numVertexes]; vec4_t* outNormal = &tess.normal[tess.numVertexes]; vec2_t (*outTexCoord)[2] = &tess.texCoords[tess.numVertexes]; color4ub_t* outColor = &tess.vertexColors[tess.numVertexes]; int frame = backEnd.currentEntity->e.frame % data->num_frames; int oldframe = backEnd.currentEntity->e.oldframe % data->num_frames; float backlerp = backEnd.currentEntity->e.backlerp; int* tri; glIndex_t* ptr; glIndex_t base; RB_CHECKOVERFLOW(surf->num_vertexes, surf->num_triangles * 3); // compute interpolated joint matrices ComputeJointMats(data, frame, oldframe, backlerp, jointMats); // transform vertexes and fill other data for (i = 0; i < surf->num_vertexes; i++, outXYZ++, outNormal++, outTexCoord++, outColor++) { int j, k; float vtxMat[12]; float nrmMat[9]; int vtx = i + surf->first_vertex; // compute the vertex matrix by blending the up to // four blend weights for (k = 0; k < 12; k++) vtxMat[k] = data->blendWeights[4 * vtx] * jointMats[12 * data->blendIndexes[4 * vtx] + k]; for (j = 1; j < 4; j++) { if (data->blendWeights[4 * vtx + j] <= 0) break; for (k = 0; k < 12; k++) vtxMat[k] += data->blendWeights[4 * vtx + j] * jointMats[12 * data->blendIndexes[4 * vtx + j] + k]; } for (k = 0; k < 12; k++) vtxMat[k] *= 1.0f / 255.0f; // compute the normal matrix as transpose of the adjoint // of the vertex matrix nrmMat[ 0] = vtxMat[ 5] * vtxMat[10] - vtxMat[ 6] * vtxMat[ 9]; nrmMat[ 1] = vtxMat[ 6] * vtxMat[ 8] - vtxMat[ 4] * vtxMat[10]; nrmMat[ 2] = vtxMat[ 4] * vtxMat[ 9] - vtxMat[ 5] * vtxMat[ 8]; nrmMat[ 3] = vtxMat[ 2] * vtxMat[ 9] - vtxMat[ 1] * vtxMat[10]; nrmMat[ 4] = vtxMat[ 0] * vtxMat[10] - vtxMat[ 2] * vtxMat[ 8]; nrmMat[ 5] = vtxMat[ 1] * vtxMat[ 8] - vtxMat[ 0] * vtxMat[ 9]; nrmMat[ 6] = vtxMat[ 1] * vtxMat[ 6] - vtxMat[ 2] * vtxMat[ 5]; nrmMat[ 7] = vtxMat[ 2] * vtxMat[ 4] - vtxMat[ 0] * vtxMat[ 6]; nrmMat[ 8] = vtxMat[ 0] * vtxMat[ 5] - vtxMat[ 1] * vtxMat[ 4]; (*outTexCoord)[0][0] = data->texcoords[2 * vtx + 0]; (*outTexCoord)[0][1] = data->texcoords[2 * vtx + 1]; (*outTexCoord)[1][0] = (*outTexCoord)[0][0]; (*outTexCoord)[1][1] = (*outTexCoord)[0][1]; (*outXYZ)[0] = vtxMat[ 0] * data->positions[3 * vtx + 0] + vtxMat[ 1] * data->positions[3 * vtx + 1] + vtxMat[ 2] * data->positions[3 * vtx + 2] + vtxMat[ 3]; (*outXYZ)[1] = vtxMat[ 4] * data->positions[3 * vtx + 0] + vtxMat[ 5] * data->positions[3 * vtx + 1] + vtxMat[ 6] * data->positions[3 * vtx + 2] + vtxMat[ 7]; (*outXYZ)[2] = vtxMat[ 8] * data->positions[3 * vtx + 0] + vtxMat[ 9] * data->positions[3 * vtx + 1] + vtxMat[10] * data->positions[3 * vtx + 2] + vtxMat[11]; (*outXYZ)[3] = 1.0f; (*outNormal)[0] = nrmMat[ 0] * data->normals[3 * vtx + 0] + nrmMat[ 1] * data->normals[3 * vtx + 1] + nrmMat[ 2] * data->normals[3 * vtx + 2]; (*outNormal)[1] = nrmMat[ 3] * data->normals[3 * vtx + 0] + nrmMat[ 4] * data->normals[3 * vtx + 1] + nrmMat[ 5] * data->normals[3 * vtx + 2]; (*outNormal)[2] = nrmMat[ 6] * data->normals[3 * vtx + 0] + nrmMat[ 7] * data->normals[3 * vtx + 1] + nrmMat[ 8] * data->normals[3 * vtx + 2]; (*outNormal)[3] = 0.0f; (*outColor)[0] = data->colors[4 * vtx + 0]; (*outColor)[1] = data->colors[4 * vtx + 1]; (*outColor)[2] = data->colors[4 * vtx + 2]; (*outColor)[3] = data->colors[4 * vtx + 3]; } tri = data->triangles + 3 * surf->first_triangle; ptr = &tess.indexes[tess.numIndexes]; base = tess.numVertexes; for (i = 0; i < surf->num_triangles; i++) { *ptr++ = base + (*tri++ - surf->first_vertex); *ptr++ = base + (*tri++ - surf->first_vertex); *ptr++ = base + (*tri++ - surf->first_vertex); } tess.numIndexes += 3 * surf->num_triangles; tess.numVertexes += surf->num_vertexes; }