Rip out the duplicate lerp code and merge it.

While the vertex lerping needs to be duplicated in the current GL code,
there's no need for the setup code to be duplicated. Also, I want it for
GLSL.
This commit is contained in:
Bill Currie 2012-01-04 16:26:52 +09:00
parent 99381b8b8c
commit f0e88bbe85
3 changed files with 114 additions and 146 deletions

View file

@ -189,6 +189,7 @@ surf_t *R_GetSurf (void);
void R_AliasDrawModel (alight_t *plighting);
maliasskindesc_t *R_AliasGetSkindesc (int skinnum, aliashdr_t *hdr);
maliasframedesc_t *R_AliasGetFramedesc (int framenum, aliashdr_t *hdr);
float R_AliasGetLerpedFrames (entity_t *ent, aliashdr_t *hdr);
void R_BeginEdgeFrame (void);
void R_ScanEdges (void);
void D_DrawSurfaces (void);

View file

@ -246,24 +246,16 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, vert_order_t *vo)
}
static inline vert_order_t *
GL_GetAliasFrameVerts16 (int frame, aliashdr_t *paliashdr, entity_t *e)
GL_GetAliasFrameVerts16 (aliashdr_t *paliashdr, entity_t *e)
{
float interval;
int count, numposes, pose, i;
float blend;
int count, i;
trivertx16_t *verts;
vert_order_t *vo;
blended_vert_t *vo_v;
if ((frame >= paliashdr->mdl.numframes) || (frame < 0)) {
if (developer->int_val)
Sys_MaskPrintf (SYS_DEV,
"R_AliasSetupFrame: no such frame %d %s\n", frame,
currententity->model->name);
frame = 0;
}
blend = R_AliasGetLerpedFrames (e, paliashdr);
pose = paliashdr->frames[frame].firstpose;
numposes = paliashdr->frames[frame].numposes;
verts = (trivertx16_t *) ((byte *) paliashdr + paliashdr->posedata);
count = paliashdr->poseverts;
@ -277,72 +269,38 @@ GL_GetAliasFrameVerts16 (int frame, aliashdr_t *paliashdr, entity_t *e)
vo->tex_coord = NULL;
}
vo->count = count;
if (numposes > 1) {
interval = paliashdr->frames[frame].interval;
pose += (int) (r_realtime / interval) % numposes;
if (!gl_lerp_anim->int_val)
blend = 1.0;
if (blend == 0.0) {
verts = verts + e->pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
} else {
/*
One tenth of a second is good for most Quake animations. If
the nextthink is longer then the animation is usually meant
to pause (e.g. check out the shambler magic animation in
shambler.qc). If its shorter then things will still be
smoothed partly, and the jumps will be less noticable
because of the shorter time. So, this is probably a good
assumption.
*/
interval = 0.1;
}
if (gl_lerp_anim->int_val) {
trivertx16_t *verts1, *verts2;
float blend;
e->frame_interval = interval;
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
if (e->pose2 != pose) {
e->frame_start_time = r_realtime;
if (e->pose2 == -1) {
e->pose1 = pose;
} else {
e->pose1 = e->pose2;
}
e->pose2 = pose;
blend = 0.0;
} else if (r_paused) {
blend = 1.0;
} else {
blend = (r_realtime - e->frame_start_time) / e->frame_interval;
blend = min (blend, 1.0);
}
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
float *n1, *n2;
if (blend == 0.0) {
verts = verts + e->pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
} else {
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
float *n1, *n2;
VectorBlend (verts1->v, verts2->v, blend, vo_v->vert);
n1 = r_avertexnormals[verts1->lightnormalindex];
n2 = r_avertexnormals[verts2->lightnormalindex];
VectorBlend (n1, n2, blend, vo_v->normal);
if (VectorIsZero (vo_v->normal)) {
if (blend < 0.5) {
VectorCopy (n1, vo_v->normal);
} else {
VectorCopy (n2, vo_v->normal);
}
VectorBlend (verts1->v, verts2->v, blend, vo_v->vert);
n1 = r_avertexnormals[verts1->lightnormalindex];
n2 = r_avertexnormals[verts2->lightnormalindex];
VectorBlend (n1, n2, blend, vo_v->normal);
if (VectorIsZero (vo_v->normal)) {
if (blend < 0.5) {
VectorCopy (n1, vo_v->normal);
} else {
VectorCopy (n2, vo_v->normal);
}
}
return vo;
}
} else {
verts += pose * count;
return vo;
}
for (i = 0, vo_v = vo->verts; i < count; i++, vo_v++, verts++) {
@ -353,24 +311,15 @@ GL_GetAliasFrameVerts16 (int frame, aliashdr_t *paliashdr, entity_t *e)
}
static inline vert_order_t *
GL_GetAliasFrameVerts (int frame, aliashdr_t *paliashdr, entity_t *e)
GL_GetAliasFrameVerts (aliashdr_t *paliashdr, entity_t *e)
{
float interval;
int count, numposes, pose, i;
float blend;
int count, i;
trivertx_t *verts;
vert_order_t *vo;
blended_vert_t *vo_v;
if ((frame >= paliashdr->mdl.numframes) || (frame < 0)) {
if (developer->int_val)
Sys_MaskPrintf (SYS_DEV,
"R_AliasSetupFrame: no such frame %d %s\n", frame,
currententity->model->name);
frame = 0;
}
pose = paliashdr->frames[frame].firstpose;
numposes = paliashdr->frames[frame].numposes;
blend = R_AliasGetLerpedFrames (e, paliashdr);
verts = (trivertx_t *) ((byte *) paliashdr + paliashdr->posedata);
@ -385,72 +334,36 @@ GL_GetAliasFrameVerts (int frame, aliashdr_t *paliashdr, entity_t *e)
}
vo->count = count;
if (numposes > 1) {
interval = paliashdr->frames[frame].interval;
pose += (int) (r_realtime / interval) % numposes;
if (!gl_lerp_anim->int_val)
blend = 1.0;
if (blend == 0.0) {
verts = verts + e->pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
} else {
/*
One tenth of a second is good for most Quake animations. If
the nextthink is longer then the animation is usually meant
to pause (e.g. check out the shambler magic animation in
shambler.qc). If its shorter then things will still be
smoothed partly, and the jumps will be less noticable
because of the shorter time. So, this is probably a good
assumption.
*/
interval = 0.1;
}
if (gl_lerp_anim->int_val) {
trivertx_t *verts1, *verts2;
float blend;
e->frame_interval = interval;
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
if (e->pose2 != pose) {
e->frame_start_time = r_realtime;
if (e->pose2 == -1) {
e->pose1 = pose;
} else {
e->pose1 = e->pose2;
}
e->pose2 = pose;
blend = 0.0;
} else if (r_paused) {
blend = 1.0;
} else {
blend = (r_realtime - e->frame_start_time) / e->frame_interval;
blend = min (blend, 1.0);
}
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
float *n1, *n2;
if (blend == 0.0) {
verts = verts + e->pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
} else {
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
float *n1, *n2;
VectorBlend (verts1->v, verts2->v, blend, vo_v->vert);
n1 = r_avertexnormals[verts1->lightnormalindex];
n2 = r_avertexnormals[verts2->lightnormalindex];
VectorBlend (n1, n2, blend, vo_v->normal);
if (VectorIsZero (vo_v->normal)) {
if (blend < 0.5) {
VectorCopy (n1, vo_v->normal);
} else {
VectorCopy (n2, vo_v->normal);
}
VectorBlend (verts1->v, verts2->v, blend, vo_v->vert);
n1 = r_avertexnormals[verts1->lightnormalindex];
n2 = r_avertexnormals[verts2->lightnormalindex];
VectorBlend (n1, n2, blend, vo_v->normal);
if (VectorIsZero (vo_v->normal)) {
if (blend < 0.5) {
VectorCopy (n1, vo_v->normal);
} else {
VectorCopy (n2, vo_v->normal);
}
}
return vo;
}
} else {
verts += pose * count;
return vo;
}
for (i = 0, vo_v = vo->verts; i < count; i++, vo_v++, verts++) {
@ -626,10 +539,10 @@ R_DrawAliasModel (entity_t *e)
if (paliashdr->mdl.ident == HEADER_MDL16) {
VectorScale (paliashdr->mdl.scale, e->scale / 256.0, scale);
vo = GL_GetAliasFrameVerts16 (e->frame, paliashdr, e);
vo = GL_GetAliasFrameVerts16 (paliashdr, e);
} else {
VectorScale (paliashdr->mdl.scale, e->scale, scale);
vo = GL_GetAliasFrameVerts (e->frame, paliashdr, e);
vo = GL_GetAliasFrameVerts (paliashdr, e);
}
// setup the transform

View file

@ -78,8 +78,8 @@ R_AliasGetSkindesc (int skinnum, aliashdr_t *ahdr)
return pskindesc;
}
VISIBLE maliasframedesc_t *
R_AliasGetFramedesc (int framenum, aliashdr_t *hdr)
static maliasframedesc_t *
alias_get_frame (int framenum, aliashdr_t *hdr, float *frame_interval)
{
float *intervals;
float fullinterval, time, targettime;
@ -95,8 +95,21 @@ R_AliasGetFramedesc (int framenum, aliashdr_t *hdr)
}
frame = &hdr->frames[framenum];
if (frame->type == ALIAS_SINGLE)
if (frame->type == ALIAS_SINGLE) {
if (frame_interval) {
/*
One tenth of a second is good for most Quake animations. If
the nextthink is longer then the animation is usually meant
to pause (e.g. check out the shambler magic animation in
shambler.qc). If its shorter then things will still be
smoothed partly, and the jumps will be less noticable
because of the shorter time. So, this is probably a good
assumption.
*/
*frame_interval = 0.1;
}
return frame;
}
group = (maliasgroup_t *) ((byte *) hdr + frame->frame);
intervals = (float *) ((byte *) hdr + group->intervals);
@ -113,5 +126,46 @@ R_AliasGetFramedesc (int framenum, aliashdr_t *hdr)
if (intervals[i] > targettime)
break;
}
if (frame_interval) {
*frame_interval = intervals[i];
if (i)
*frame_interval -= intervals[i - 1];
}
return &group->frames[i];
}
VISIBLE maliasframedesc_t *
R_AliasGetFramedesc (int framenum, aliashdr_t *hdr)
{
return alias_get_frame (framenum, hdr, 0);
}
float
R_AliasGetLerpedFrames (entity_t *ent, aliashdr_t *hdr)
{
maliasframedesc_t *frame;
float frame_interval;
int pose;
float blend;
frame = alias_get_frame (ent->frame, hdr, &frame_interval);
pose = frame->firstpose;
ent->frame_interval = frame_interval;
if (ent->pose2 != pose) {
ent->frame_start_time = r_realtime;
if (ent->pose2 == -1) {
ent->pose1 = pose;
} else {
ent->pose1 = ent->pose2;
}
ent->pose2 = pose;
blend = 0.0;
} else if (r_paused) {
blend = 1.0;
} else {
blend = (r_realtime - ent->frame_start_time) / ent->frame_interval;
blend = min (blend, 1.0);
}
return blend;
}