- int i;
- float lerp1, lerp2, lerp3, lerp4;
- zymbonematrix *out, rootmatrix, m;
- const zymbonematrix *bone1, *bone2, *bone3, *bone4;
-
- rootmatrix.m[0][0] = 1;
- rootmatrix.m[0][1] = 0;
- rootmatrix.m[0][2] = 0;
- rootmatrix.m[0][3] = 0;
- rootmatrix.m[1][0] = 0;
- rootmatrix.m[1][1] = 1;
- rootmatrix.m[1][2] = 0;
- rootmatrix.m[1][3] = 0;
- rootmatrix.m[2][0] = 0;
- rootmatrix.m[2][1] = 0;
- rootmatrix.m[2][2] = 1;
- rootmatrix.m[2][3] = 0;
-
- bone1 = bonebase + blend[0].frame * count;
- lerp1 = blend[0].lerp;
- if (blend[1].lerp)
- {
- bone2 = bonebase + blend[1].frame * count;
- lerp2 = blend[1].lerp;
- if (blend[2].lerp)
- {
- bone3 = bonebase + blend[2].frame * count;
- lerp3 = blend[2].lerp;
- if (blend[3].lerp)
- {
- // 4 poses
- bone4 = bonebase + blend[3].frame * count;
- lerp4 = blend[3].lerp;
- for (i = 0, out = zymbonepose;i < count;i++, out++)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3 + bone4->m[0][0] * lerp4;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3 + bone4->m[0][1] * lerp4;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3 + bone4->m[0][2] * lerp4;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3 + bone4->m[0][3] * lerp4;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3 + bone4->m[1][0] * lerp4;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3 + bone4->m[1][1] * lerp4;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3 + bone4->m[1][2] * lerp4;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3 + bone4->m[1][3] * lerp4;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3 + bone4->m[2][0] * lerp4;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3 + bone4->m[2][1] * lerp4;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3 + bone4->m[2][2] * lerp4;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3 + bone4->m[2][3] * lerp4;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
- bone1++;
- bone2++;
- bone3++;
- bone4++;
- bone++;
- }
- }
- else
- {
- // 3 poses
- for (i = 0, out = zymbonepose;i < count;i++, out++)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2 + bone3->m[0][0] * lerp3;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2 + bone3->m[0][1] * lerp3;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2 + bone3->m[0][2] * lerp3;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2 + bone3->m[0][3] * lerp3;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2 + bone3->m[1][0] * lerp3;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2 + bone3->m[1][1] * lerp3;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2 + bone3->m[1][2] * lerp3;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2 + bone3->m[1][3] * lerp3;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2 + bone3->m[2][0] * lerp3;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2 + bone3->m[2][1] * lerp3;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2 + bone3->m[2][2] * lerp3;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2 + bone3->m[2][3] * lerp3;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
- bone1++;
- bone2++;
- bone3++;
- bone++;
- }
- }
- }
- else
- {
- // 2 poses
- for (i = 0, out = zymbonepose;i < count;i++, out++)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1 + bone2->m[0][0] * lerp2;
- m.m[0][1] = bone1->m[0][1] * lerp1 + bone2->m[0][1] * lerp2;
- m.m[0][2] = bone1->m[0][2] * lerp1 + bone2->m[0][2] * lerp2;
- m.m[0][3] = bone1->m[0][3] * lerp1 + bone2->m[0][3] * lerp2;
- m.m[1][0] = bone1->m[1][0] * lerp1 + bone2->m[1][0] * lerp2;
- m.m[1][1] = bone1->m[1][1] * lerp1 + bone2->m[1][1] * lerp2;
- m.m[1][2] = bone1->m[1][2] * lerp1 + bone2->m[1][2] * lerp2;
- m.m[1][3] = bone1->m[1][3] * lerp1 + bone2->m[1][3] * lerp2;
- m.m[2][0] = bone1->m[2][0] * lerp1 + bone2->m[2][0] * lerp2;
- m.m[2][1] = bone1->m[2][1] * lerp1 + bone2->m[2][1] * lerp2;
- m.m[2][2] = bone1->m[2][2] * lerp1 + bone2->m[2][2] * lerp2;
- m.m[2][3] = bone1->m[2][3] * lerp1 + bone2->m[2][3] * lerp2;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
- bone1++;
- bone2++;
- bone++;
- }
- }
- }
- else
- {
- // 1 pose
- if (lerp1 != 1)
- {
- // lerp != 1.0
- for (i = 0, out = zymbonepose;i < count;i++, out++)
- {
- // interpolate matrices
- m.m[0][0] = bone1->m[0][0] * lerp1;
- m.m[0][1] = bone1->m[0][1] * lerp1;
- m.m[0][2] = bone1->m[0][2] * lerp1;
- m.m[0][3] = bone1->m[0][3] * lerp1;
- m.m[1][0] = bone1->m[1][0] * lerp1;
- m.m[1][1] = bone1->m[1][1] * lerp1;
- m.m[1][2] = bone1->m[1][2] * lerp1;
- m.m[1][3] = bone1->m[1][3] * lerp1;
- m.m[2][0] = bone1->m[2][0] * lerp1;
- m.m[2][1] = bone1->m[2][1] * lerp1;
- m.m[2][2] = bone1->m[2][2] * lerp1;
- m.m[2][3] = bone1->m[2][3] * lerp1;
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &m.m[0][0], &out->m[0][0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0][0], &m.m[0][0], &out->m[0][0]);
- bone1++;
- bone++;
- }
- }
- else
- {
- // lerp == 1.0
- for (i = 0, out = zymbonepose;i < count;i++, out++)
- {
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0][0], &bone1->m[0][0], &out->m[0][0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0][0], &bone1->m[0][0], &out->m[0][0]);
- bone1++;
- bone++;
- }
- }
- }
- return true;
-}
-
-void ZymoticTransformVerts(int vertcount, float *vertex, int *bonecounts, zymvertex_t *vert)
-{
- int c;
- float *out = vertex;
- zymbonematrix *matrix;
- while(vertcount--)
- {
- c = *bonecounts++;
- // FIXME: validate bonecounts at load time (must be >= 1)
- // FIXME: need 4th component in origin, for how much of the translate to blend in
- if (c == 1)
- {
- matrix = &zymbonepose[vert->bonenum];
- out[0] = vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
- out[1] = vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
- out[2] = vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
- vert++;
- }
- else
- {
- VectorClear(out);
- while(c--)
- {
- matrix = &zymbonepose[vert->bonenum];
- out[0] += vert->origin[0] * matrix->m[0][0] + vert->origin[1] * matrix->m[0][1] + vert->origin[2] * matrix->m[0][2] + matrix->m[0][3];
- out[1] += vert->origin[0] * matrix->m[1][0] + vert->origin[1] * matrix->m[1][1] + vert->origin[2] * matrix->m[1][2] + matrix->m[1][3];
- out[2] += vert->origin[0] * matrix->m[2][0] + vert->origin[1] * matrix->m[2][1] + vert->origin[2] * matrix->m[2][2] + matrix->m[2][3];
- vert++;
- }
- }
- out += 4;
- }
-}
-
-void ZymoticCalcNormals(int vertcount, float *vertex, float *normals, int shadercount, int *renderlist)
-{
- int a, b, c, d;
- float *out, v1[3], v2[3], normal[3], s;
- int *u;
- // clear normals
- memset(normals, 0, sizeof(float) * vertcount * 3);
- memset(aliasvertusage, 0, sizeof(int) * vertcount);
- // parse render list and accumulate surface normals
- while(shadercount--)
- {
- d = *renderlist++;
- while (d--)
- {
- a = renderlist[0]*4;
- b = renderlist[1]*4;
- c = renderlist[2]*4;
- v1[0] = vertex[a+0] - vertex[b+0];
- v1[1] = vertex[a+1] - vertex[b+1];
- v1[2] = vertex[a+2] - vertex[b+2];
- v2[0] = vertex[c+0] - vertex[b+0];
- v2[1] = vertex[c+1] - vertex[b+1];
- v2[2] = vertex[c+2] - vertex[b+2];
- CrossProduct(v1, v2, normal);
- VectorNormalizeFast(normal);
- // add surface normal to vertices
- a = renderlist[0] * 3;
- normals[a+0] += normal[0];
- normals[a+1] += normal[1];
- normals[a+2] += normal[2];
- aliasvertusage[renderlist[0]]++;
- a = renderlist[1] * 3;
- normals[a+0] += normal[0];
- normals[a+1] += normal[1];
- normals[a+2] += normal[2];
- aliasvertusage[renderlist[1]]++;
- a = renderlist[2] * 3;
- normals[a+0] += normal[0];
- normals[a+1] += normal[1];
- normals[a+2] += normal[2];
- aliasvertusage[renderlist[2]]++;
- renderlist += 3;
- }
- }
- // FIXME: precalc this
- // average surface normals
- out = normals;
- u = aliasvertusage;
- while(vertcount--)
- {
- if (*u > 1)
- {
- s = ixtable[*u];
- out[0] *= s;
- out[1] *= s;
- out[2] *= s;
- }
- u++;
- out += 3;
- }
-}
-
-void R_DrawZymoticModelMeshCallback (const void *calldata1, int calldata2)
-{
- float fog, ifog, colorscale;