- else
- {
- // 2 poses
- while(count--)
- {
- // 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], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone2++;
- bone++;
- out++;
- }
- }
- }
- else
- {
- // 1 pose
- if (lerp1 != 1)
- {
- // lerp != 1.0
- while(count--)
- {
- // 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], &m.m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &m.m[0], &out->m[0]);
- bone1++;
- bone++;
- out++;
- }
- }
- else
- {
- // lerp == 1.0
- while(count--)
- {
- if (bone->parent >= 0)
- R_ConcatTransforms(&zymbonepose[bone->parent].m[0], &bone1->m[0], &out->m[0]);
- else
- R_ConcatTransforms(&rootmatrix.m[0], &bone1->m[0], &out->m[0]);
- bone1++;
- bone++;
- out++;
- }
- }
- }
-}
-
-void ZymoticTransformVerts(int vertcount, int *bonecounts, zymvertex_t *vert)
-{
- int c;
- float *out = aliasvert;
- zymbonematrix *matrix;
- while(vertcount--)
- {
- c = *bonecounts++;
- // FIXME: validate bonecounts at load time (must be >= 1)
- 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 += 3;
- }
-}
-
-float ixtable[4096];
-
-void ZymoticCalcNormals(int vertcount, int shadercount, int *renderlist)
-{
- int a, b, c, d;
- float *out, v1[3], v2[3], normal[3];
- int *u;
- if (!ixtable[1])
- {
- ixtable[0] = 0;
- for (a = 1;a < 4096;a++)
- ixtable[a] = 1.0f / a;
- }
- // clear normals
- memset(aliasvertnorm, 0, sizeof(float[3]) * vertcount);
- memset(aliasvertusage, 0, sizeof(int) * vertcount);
- // parse render list and accumulate surface normals
- while(shadercount--)
- {
- d = *renderlist++;
- while (d--)
- {
- a = renderlist[0]*3;
- b = renderlist[1]*3;
- c = renderlist[2]*3;
- v1[0] = aliasvert[a+0] - aliasvert[b+0];
- v1[1] = aliasvert[a+1] - aliasvert[b+1];
- v1[2] = aliasvert[a+2] - aliasvert[b+2];
- v2[0] = aliasvert[c+0] - aliasvert[b+0];
- v2[1] = aliasvert[c+1] - aliasvert[b+1];
- v2[2] = aliasvert[c+2] - aliasvert[b+2];
- CrossProduct(v1, v2, normal);
- VectorNormalize(normal);
- // add surface normal to vertices
- aliasvertnorm[a+0] += normal[0];
- aliasvertnorm[a+1] += normal[1];
- aliasvertnorm[a+2] += normal[2];
- aliasvertusage[a]++;
- aliasvertnorm[b+0] += normal[0];
- aliasvertnorm[b+1] += normal[1];
- aliasvertnorm[b+2] += normal[2];
- aliasvertusage[b]++;
- aliasvertnorm[c+0] += normal[0];
- aliasvertnorm[c+1] += normal[1];
- aliasvertnorm[c+2] += normal[2];
- aliasvertusage[c]++;
- renderlist += 3;
- }
- }
- // average surface normals
- out = aliasvertnorm;
- u = aliasvertusage;
- while(vertcount--)
- {
- if (*u > 1)
- {
- a = ixtable[*u];
- out[0] *= a;
- out[1] *= a;
- out[2] *= a;
- }
- u++;
- out += 3;
- }
-}
-
-void GL_DrawZymoticModelMesh(byte *colors, zymtype1header_t *m)
-{
- int i, c, *renderlist;
- rtexture_t **texture;
- if (!r_render.value)
- return;
- renderlist = (int *)(m->lump_render.start + (int) m);
- texture = (rtexture_t **)(m->lump_shaders.start + (int) m);
- glVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- glColorPointer(4, GL_UNSIGNED_BYTE, 0, colors);
- glEnableClientState(GL_COLOR_ARRAY);
-
- glTexCoordPointer(2, GL_FLOAT, 0, (float *)(m->lump_texcoords.start + (int) m));
- glEnableClientState(GL_TEXTURE_COORD_ARRAY);
-
- for (i = 0;i < m->numshaders;i++)
- {
- c = (*renderlist++) * 3;
- glBindTexture(GL_TEXTURE_2D, R_GetTexture(*texture));
- texture++;
- glDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
- renderlist += c;
- }
-
- glDisableClientState(GL_TEXTURE_COORD_ARRAY);
-
- glDisableClientState(GL_COLOR_ARRAY);
-
- glDisableClientState(GL_VERTEX_ARRAY);
-}
-
-void GL_DrawZymoticModelMeshFog(vec3_t org, zymtype1header_t *m)
-{
- vec3_t diff;
- int i, c, *renderlist;
- if (!r_render.value)
- return;
- renderlist = (int *)(m->lump_render.start + (int) m);
- glDisable(GL_TEXTURE_2D);
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable (GL_BLEND);
- glDepthMask(0); // disable zbuffer updates
-
- VectorSubtract(org, r_origin, diff);
- glColor4f(fogcolor[0], fogcolor[1], fogcolor[2], exp(fogdensity/DotProduct(diff,diff)));
-
- glVertexPointer(3, GL_FLOAT, 0, aliasvert);
- glEnableClientState(GL_VERTEX_ARRAY);
-
- for (i = 0;i < m->numshaders;i++)
- {
- c = (*renderlist++) * 3;
- glDrawElements(GL_TRIANGLES, c, GL_UNSIGNED_INT, renderlist);
- renderlist += c;
- }
-
- glDisableClientState(GL_VERTEX_ARRAY);
-
- glEnable(GL_TEXTURE_2D);
- glColor3f (1,1,1);
-}
-
-/*
-=================
-R_DrawZymoticFrame
-=================
-*/
-void R_DrawZymoticFrame (zymtype1header_t *m, float alpha, vec3_t color, entity_t *ent, int shadow, vec3_t org, vec3_t angles, vec_t scale, frameblend_t *blend, int skinblah, int effects, int flags)
-{
- ZymoticLerpBones(m->numbones, (zymbonematrix *)(m->lump_poses.start + (int) m), blend, (zymbone_t *)(m->lump_bones.start + (int) m), org, angles, scale);
- ZymoticTransformVerts(m->numverts, (int *)(m->lump_vertbonecounts.start + (int) m), (zymvertex_t *)(m->lump_verts.start + (int) m));
- ZymoticCalcNormals(m->numverts, m->numshaders, (int *)(m->lump_render.start + (int) m));
-
- R_LightModel(ent, m->numverts, org, color);
-
- if (!r_render.value)
- return;
- glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
- glShadeModel(GL_SMOOTH);
- if (effects & EF_ADDITIVE)
- {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE); // additive rendering
- glEnable(GL_BLEND);
- glDepthMask(0);
- }
- else if (alpha != 1.0)
- {
- glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
- glEnable(GL_BLEND);
- glDepthMask(0);
- }
- else
- {
- glDisable(GL_BLEND);
- glDepthMask(1);