mirror of
https://github.com/nzp-team/glquake.git
synced 2024-11-10 06:31:35 +00:00
r_lerpmodels
This commit is contained in:
parent
f1660ba56c
commit
3829f490cc
10 changed files with 220 additions and 36 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
BIN
nzportable.3dsx
BIN
nzportable.3dsx
Binary file not shown.
BIN
nzportable.elf
BIN
nzportable.elf
Binary file not shown.
|
@ -339,6 +339,10 @@ typedef enum {mod_brush, mod_sprite, mod_alias} modtype_t;
|
||||||
#define EF_TRACER2 64 // orange split trail + rotate
|
#define EF_TRACER2 64 // orange split trail + rotate
|
||||||
#define EF_TRACER3 128 // purple trail
|
#define EF_TRACER3 128 // purple trail
|
||||||
|
|
||||||
|
//johnfitz -- extra flags for rendering
|
||||||
|
#define MOD_NOLERP 256
|
||||||
|
//johnfits
|
||||||
|
|
||||||
typedef struct model_s
|
typedef struct model_s
|
||||||
{
|
{
|
||||||
char name[MAX_QPATH];
|
char name[MAX_QPATH];
|
||||||
|
|
|
@ -84,6 +84,8 @@ cvar_t r_mirroralpha = {"r_mirroralpha","1"};
|
||||||
cvar_t r_wateralpha = {"r_wateralpha","1"};
|
cvar_t r_wateralpha = {"r_wateralpha","1"};
|
||||||
cvar_t r_dynamic = {"r_dynamic","1"};
|
cvar_t r_dynamic = {"r_dynamic","1"};
|
||||||
cvar_t r_novis = {"r_novis","0"};
|
cvar_t r_novis = {"r_novis","0"};
|
||||||
|
cvar_t r_lerpmodels = {"r_lerpmodels", "1"};
|
||||||
|
cvar_t r_lerpmove = {"r_lerpmove", "1"};
|
||||||
|
|
||||||
cvar_t gl_finish = {"gl_finish","0"};
|
cvar_t gl_finish = {"gl_finish","0"};
|
||||||
cvar_t gl_clear = {"gl_clear","0"};
|
cvar_t gl_clear = {"gl_clear","0"};
|
||||||
|
@ -99,6 +101,16 @@ cvar_t gl_keeptjunctions = {"gl_keeptjunctions","0"};
|
||||||
cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"};
|
cvar_t gl_reporttjunctions = {"gl_reporttjunctions","0"};
|
||||||
cvar_t gl_doubleeyes = {"gl_doubleeys", "1"};
|
cvar_t gl_doubleeyes = {"gl_doubleeys", "1"};
|
||||||
|
|
||||||
|
//johnfitz -- struct for passing lerp information to drawing functions
|
||||||
|
typedef struct {
|
||||||
|
short pose1;
|
||||||
|
short pose2;
|
||||||
|
float blend;
|
||||||
|
vec3_t origin;
|
||||||
|
vec3_t angles;
|
||||||
|
} lerpdata_t;
|
||||||
|
//johnfitz
|
||||||
|
|
||||||
extern cvar_t gl_ztrick;
|
extern cvar_t gl_ztrick;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -284,34 +296,49 @@ int lastposenum;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
=============
|
||||||
GL_DrawAliasFrame
|
GL_DrawAliasFrame -- johnfitz -- rewritten to support colored light, lerping, entalpha, multitexture, and r_drawflat
|
||||||
=============
|
=============
|
||||||
*/
|
*/
|
||||||
void GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum)
|
void GL_DrawAliasFrame (aliashdr_t *paliashdr, lerpdata_t lerpdata)
|
||||||
{
|
{
|
||||||
float s, t;
|
float vertcolor[4];
|
||||||
float l;
|
trivertx_t *verts1, *verts2;
|
||||||
int i, j;
|
int *commands;
|
||||||
int index;
|
|
||||||
trivertx_t *v, *verts;
|
|
||||||
int list;
|
|
||||||
int *order;
|
|
||||||
vec3_t point;
|
|
||||||
float *normal;
|
|
||||||
int count;
|
int count;
|
||||||
|
float u,v;
|
||||||
|
float blend, iblend;
|
||||||
|
qboolean lerping;
|
||||||
|
|
||||||
lastposenum = posenum;
|
if (lerpdata.pose1 != lerpdata.pose2)
|
||||||
|
{
|
||||||
|
lerping = true;
|
||||||
|
verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
|
||||||
|
verts2 = verts1;
|
||||||
|
verts1 += lerpdata.pose1 * paliashdr->poseverts;
|
||||||
|
verts2 += lerpdata.pose2 * paliashdr->poseverts;
|
||||||
|
blend = lerpdata.blend;
|
||||||
|
iblend = 1.0f - blend;
|
||||||
|
}
|
||||||
|
else // poses the same means either 1. the entity has paused its animation, or 2. r_lerpmodels is disabled
|
||||||
|
{
|
||||||
|
lerping = false;
|
||||||
|
verts1 = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
|
||||||
|
verts2 = verts1; // avoid bogus compiler warning
|
||||||
|
verts1 += lerpdata.pose1 * paliashdr->poseverts;
|
||||||
|
blend = iblend = 0; // avoid bogus compiler warning
|
||||||
|
}
|
||||||
|
|
||||||
verts = (trivertx_t *)((byte *)paliashdr + paliashdr->posedata);
|
commands = (int *)((byte *)paliashdr + paliashdr->commands);
|
||||||
verts += posenum * paliashdr->poseverts;
|
|
||||||
order = (int *)((byte *)paliashdr + paliashdr->commands);
|
vertcolor[3] = 255; //never changes, so there's no need to put this inside the loop
|
||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
// get the vertex count and primitive type
|
// get the vertex count and primitive type
|
||||||
count = *order++;
|
count = *commands++;
|
||||||
if (!count)
|
if (!count)
|
||||||
break; // done
|
break; // done
|
||||||
|
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
{
|
{
|
||||||
count = -count;
|
count = -count;
|
||||||
|
@ -322,15 +349,36 @@ lastposenum = posenum;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
// texture coordinates come from the draw list
|
u = ((float *)commands)[0];
|
||||||
glTexCoord2f (((float *)order)[0], ((float *)order)[1]);
|
v = ((float *)commands)[1];
|
||||||
order += 2;
|
|
||||||
|
|
||||||
// normals and vertexes come from the frame list
|
glTexCoord2f (u, v);
|
||||||
l = shadedots[verts->lightnormalindex] * shadelight;
|
|
||||||
glColor3f (l, l, l);
|
commands += 2;
|
||||||
glVertex3f (verts->v[0], verts->v[1], verts->v[2]);
|
|
||||||
verts++;
|
if (lerping)
|
||||||
|
{
|
||||||
|
vertcolor[0] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[0];
|
||||||
|
vertcolor[1] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[1];
|
||||||
|
vertcolor[2] = (shadedots[verts1->lightnormalindex]*iblend + shadedots[verts2->lightnormalindex]*blend) * lightcolor[2];
|
||||||
|
glColor4fv (vertcolor);
|
||||||
|
|
||||||
|
glVertex3f (verts1->v[0]*iblend + verts2->v[0]*blend,
|
||||||
|
verts1->v[1]*iblend + verts2->v[1]*blend,
|
||||||
|
verts1->v[2]*iblend + verts2->v[2]*blend);
|
||||||
|
verts1++;
|
||||||
|
verts2++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vertcolor[0] = shadedots[verts1->lightnormalindex] * lightcolor[0];
|
||||||
|
vertcolor[1] = shadedots[verts1->lightnormalindex] * lightcolor[1];
|
||||||
|
vertcolor[2] = shadedots[verts1->lightnormalindex] * lightcolor[2];
|
||||||
|
glColor4fv (vertcolor);
|
||||||
|
|
||||||
|
glVertex3f (verts1->v[0], verts1->v[1], verts1->v[2]);
|
||||||
|
verts1++;
|
||||||
|
}
|
||||||
} while (--count);
|
} while (--count);
|
||||||
|
|
||||||
glEnd ();
|
glEnd ();
|
||||||
|
@ -409,34 +457,134 @@ void GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
R_SetupAliasFrame
|
R_SetupAliasFrame -- johnfitz -- rewritten to support lerping
|
||||||
|
|
||||||
=================
|
=================
|
||||||
*/
|
*/
|
||||||
void R_SetupAliasFrame (int frame, aliashdr_t *paliashdr)
|
void R_SetupAliasFrame (aliashdr_t *paliashdr, int frame, lerpdata_t *lerpdata)
|
||||||
{
|
{
|
||||||
int pose, numposes;
|
entity_t *e = currententity;
|
||||||
float interval;
|
int posenum, numposes;
|
||||||
|
|
||||||
if ((frame >= paliashdr->numframes) || (frame < 0))
|
if ((frame >= paliashdr->numframes) || (frame < 0))
|
||||||
{
|
{
|
||||||
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
|
Con_DPrintf ("R_AliasSetupFrame: no such frame %d for '%s'\n", frame, e->model->name);
|
||||||
frame = 0;
|
frame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
pose = paliashdr->frames[frame].firstpose;
|
posenum = paliashdr->frames[frame].firstpose;
|
||||||
numposes = paliashdr->frames[frame].numposes;
|
numposes = paliashdr->frames[frame].numposes;
|
||||||
|
|
||||||
if (numposes > 1)
|
if (numposes > 1)
|
||||||
{
|
{
|
||||||
interval = paliashdr->frames[frame].interval;
|
e->lerptime = paliashdr->frames[frame].interval;
|
||||||
pose += (int)(cl.time / interval) % numposes;
|
posenum += (int)(cl.time / e->lerptime) % numposes;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
e->lerptime = 0.1;
|
||||||
|
|
||||||
|
if (e->lerpflags & LERP_RESETANIM) //kill any lerp in progress
|
||||||
|
{
|
||||||
|
e->lerpstart = 0;
|
||||||
|
e->previouspose = posenum;
|
||||||
|
e->currentpose = posenum;
|
||||||
|
e->lerpflags -= LERP_RESETANIM;
|
||||||
|
}
|
||||||
|
else if (e->currentpose != posenum) // pose changed, start new lerp
|
||||||
|
{
|
||||||
|
if (e->lerpflags & LERP_RESETANIM2) //defer lerping one more time
|
||||||
|
{
|
||||||
|
e->lerpstart = 0;
|
||||||
|
e->previouspose = posenum;
|
||||||
|
e->currentpose = posenum;
|
||||||
|
e->lerpflags -= LERP_RESETANIM2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
e->lerpstart = cl.time;
|
||||||
|
e->previouspose = e->currentpose;
|
||||||
|
e->currentpose = posenum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
GL_DrawAliasFrame (paliashdr, pose);
|
//set up values
|
||||||
|
if (r_lerpmodels.value && !(e->model->flags & MOD_NOLERP && r_lerpmodels.value != 2))
|
||||||
|
{
|
||||||
|
if (e->lerpflags & LERP_FINISH && numposes == 1)
|
||||||
|
lerpdata->blend = CLAMP (0, (cl.time - e->lerpstart) / (e->lerpfinish - e->lerpstart), 1);
|
||||||
|
else
|
||||||
|
lerpdata->blend = CLAMP (0, (cl.time - e->lerpstart) / e->lerptime, 1);
|
||||||
|
lerpdata->pose1 = e->previouspose;
|
||||||
|
lerpdata->pose2 = e->currentpose;
|
||||||
|
}
|
||||||
|
else //don't lerp
|
||||||
|
{
|
||||||
|
lerpdata->blend = 1;
|
||||||
|
lerpdata->pose1 = posenum;
|
||||||
|
lerpdata->pose2 = posenum;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
=================
|
||||||
|
R_SetupEntityTransform -- johnfitz -- set up transform part of lerpdata
|
||||||
|
=================
|
||||||
|
*/
|
||||||
|
void R_SetupEntityTransform (entity_t *e, lerpdata_t *lerpdata)
|
||||||
|
{
|
||||||
|
float blend;
|
||||||
|
vec3_t d;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
// if LERP_RESETMOVE, kill any lerps in progress
|
||||||
|
if (e->lerpflags & LERP_RESETMOVE)
|
||||||
|
{
|
||||||
|
e->movelerpstart = 0;
|
||||||
|
VectorCopy (e->origin, e->previousorigin);
|
||||||
|
VectorCopy (e->origin, e->currentorigin);
|
||||||
|
VectorCopy (e->angles, e->previousangles);
|
||||||
|
VectorCopy (e->angles, e->currentangles);
|
||||||
|
e->lerpflags -= LERP_RESETMOVE;
|
||||||
|
}
|
||||||
|
else if (!VectorCompare (e->origin, e->currentorigin) || !VectorCompare (e->angles, e->currentangles)) // origin/angles changed, start new lerp
|
||||||
|
{
|
||||||
|
e->movelerpstart = cl.time;
|
||||||
|
VectorCopy (e->currentorigin, e->previousorigin);
|
||||||
|
VectorCopy (e->origin, e->currentorigin);
|
||||||
|
VectorCopy (e->currentangles, e->previousangles);
|
||||||
|
VectorCopy (e->angles, e->currentangles);
|
||||||
|
}
|
||||||
|
|
||||||
|
//set up values
|
||||||
|
if (r_lerpmove.value && e != &cl.viewent && e->lerpflags & LERP_MOVESTEP)
|
||||||
|
{
|
||||||
|
if (e->lerpflags & LERP_FINISH)
|
||||||
|
blend = CLAMP (0, (cl.time - e->movelerpstart) / (e->lerpfinish - e->movelerpstart), 1);
|
||||||
|
else
|
||||||
|
blend = CLAMP (0, (cl.time - e->movelerpstart) / 0.1, 1);
|
||||||
|
|
||||||
|
//translation
|
||||||
|
VectorSubtract (e->currentorigin, e->previousorigin, d);
|
||||||
|
lerpdata->origin[0] = e->previousorigin[0] + d[0] * blend;
|
||||||
|
lerpdata->origin[1] = e->previousorigin[1] + d[1] * blend;
|
||||||
|
lerpdata->origin[2] = e->previousorigin[2] + d[2] * blend;
|
||||||
|
|
||||||
|
//rotation
|
||||||
|
VectorSubtract (e->currentangles, e->previousangles, d);
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
if (d[i] > 180) d[i] -= 360;
|
||||||
|
if (d[i] < -180) d[i] += 360;
|
||||||
|
}
|
||||||
|
lerpdata->angles[0] = e->previousangles[0] + d[0] * blend;
|
||||||
|
lerpdata->angles[1] = e->previousangles[1] + d[1] * blend;
|
||||||
|
lerpdata->angles[2] = e->previousangles[2] + d[2] * blend;
|
||||||
|
}
|
||||||
|
else //don't lerp
|
||||||
|
{
|
||||||
|
VectorCopy (e->origin, lerpdata->origin);
|
||||||
|
VectorCopy (e->angles, lerpdata->angles);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=================
|
=================
|
||||||
|
@ -457,6 +605,7 @@ void R_DrawAliasModel (entity_t *e)
|
||||||
int index;
|
int index;
|
||||||
float s, t, an;
|
float s, t, an;
|
||||||
int anim;
|
int anim;
|
||||||
|
lerpdata_t lerpdata;
|
||||||
|
|
||||||
clmodel = currententity->model;
|
clmodel = currententity->model;
|
||||||
|
|
||||||
|
@ -526,7 +675,7 @@ void R_DrawAliasModel (entity_t *e)
|
||||||
//
|
//
|
||||||
// locate the proper data
|
// locate the proper data
|
||||||
//
|
//
|
||||||
paliashdr = (aliashdr_t *)Mod_Extradata (currententity->model);
|
paliashdr = (aliashdr_t *)Mod_Extradata (e->model);
|
||||||
|
|
||||||
c_alias_polys += paliashdr->numtris;
|
c_alias_polys += paliashdr->numtris;
|
||||||
|
|
||||||
|
@ -567,7 +716,9 @@ void R_DrawAliasModel (entity_t *e)
|
||||||
if (gl_affinemodels.value)
|
if (gl_affinemodels.value)
|
||||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
|
||||||
R_SetupAliasFrame (currententity->frame, paliashdr);
|
R_SetupAliasFrame (paliashdr, e->frame, &lerpdata);
|
||||||
|
R_SetupEntityTransform (e, &lerpdata);
|
||||||
|
GL_DrawAliasFrame(paliashdr, lerpdata);
|
||||||
|
|
||||||
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
|
||||||
|
|
||||||
|
|
|
@ -188,6 +188,8 @@ void R_Init (void)
|
||||||
Cvar_RegisterVariable (&r_dynamic);
|
Cvar_RegisterVariable (&r_dynamic);
|
||||||
Cvar_RegisterVariable (&r_novis);
|
Cvar_RegisterVariable (&r_novis);
|
||||||
Cvar_RegisterVariable (&r_speeds);
|
Cvar_RegisterVariable (&r_speeds);
|
||||||
|
Cvar_RegisterVariable (&r_lerpmodels);
|
||||||
|
Cvar_RegisterVariable (&r_lerpmove);
|
||||||
|
|
||||||
Cvar_RegisterVariable (&gl_finish);
|
Cvar_RegisterVariable (&gl_finish);
|
||||||
Cvar_RegisterVariable (&gl_clear);
|
Cvar_RegisterVariable (&gl_clear);
|
||||||
|
|
|
@ -192,6 +192,8 @@ extern cvar_t r_mirroralpha;
|
||||||
extern cvar_t r_wateralpha;
|
extern cvar_t r_wateralpha;
|
||||||
extern cvar_t r_dynamic;
|
extern cvar_t r_dynamic;
|
||||||
extern cvar_t r_novis;
|
extern cvar_t r_novis;
|
||||||
|
extern cvar_t r_lerpmodels;
|
||||||
|
extern cvar_t r_lerpmove;
|
||||||
|
|
||||||
extern cvar_t gl_clear;
|
extern cvar_t gl_clear;
|
||||||
extern cvar_t gl_cull;
|
extern cvar_t gl_cull;
|
||||||
|
|
|
@ -189,6 +189,8 @@ extern cvar_t r_fullbright;
|
||||||
extern cvar_t r_lightmap;
|
extern cvar_t r_lightmap;
|
||||||
extern cvar_t r_shadows;
|
extern cvar_t r_shadows;
|
||||||
extern cvar_t r_dynamic;
|
extern cvar_t r_dynamic;
|
||||||
|
extern cvar_t r_lerpmodels;
|
||||||
|
extern cvar_t r_lerpmove;
|
||||||
|
|
||||||
extern cvar_t gl_clear;
|
extern cvar_t gl_clear;
|
||||||
extern cvar_t gl_cull;
|
extern cvar_t gl_cull;
|
||||||
|
|
|
@ -71,6 +71,8 @@ extern cvar_t r_numsurfs;
|
||||||
extern cvar_t r_reportedgeout;
|
extern cvar_t r_reportedgeout;
|
||||||
extern cvar_t r_maxedges;
|
extern cvar_t r_maxedges;
|
||||||
extern cvar_t r_numedges;
|
extern cvar_t r_numedges;
|
||||||
|
extern cvar_t r_lerpmodels;
|
||||||
|
extern cvar_t r_lerpmove;
|
||||||
|
|
||||||
#define XCENTERING (1.0 / 2.0)
|
#define XCENTERING (1.0 / 2.0)
|
||||||
#define YCENTERING (1.0 / 2.0)
|
#define YCENTERING (1.0 / 2.0)
|
||||||
|
|
|
@ -35,6 +35,13 @@ typedef struct efrag_s
|
||||||
struct efrag_s *entnext;
|
struct efrag_s *entnext;
|
||||||
} efrag_t;
|
} efrag_t;
|
||||||
|
|
||||||
|
//johnfitz -- for lerping
|
||||||
|
#define LERP_MOVESTEP (1<<0) //this is a MOVETYPE_STEP entity, enable movement lerp
|
||||||
|
#define LERP_RESETANIM (1<<1) //disable anim lerping until next anim frame
|
||||||
|
#define LERP_RESETANIM2 (1<<2) //set this and previous flag to disable anim lerping for two anim frames
|
||||||
|
#define LERP_RESETMOVE (1<<3) //disable movement lerping until next origin/angles change
|
||||||
|
#define LERP_FINISH (1<<4) //use lerpfinish time from server update instead of assuming interval of 0.1
|
||||||
|
//johnfitz
|
||||||
|
|
||||||
typedef struct entity_s
|
typedef struct entity_s
|
||||||
{
|
{
|
||||||
|
@ -68,6 +75,20 @@ typedef struct entity_s
|
||||||
// that splits bmodel, or NULL if
|
// that splits bmodel, or NULL if
|
||||||
// not split
|
// not split
|
||||||
|
|
||||||
|
byte lerpflags; //johnfitz -- lerping
|
||||||
|
float lerpstart; //johnfitz -- animation lerping
|
||||||
|
float lerptime; //johnfitz -- animation lerping
|
||||||
|
float lerpfinish; //johnfitz -- lerping -- server sent us a more accurate interval, use it instead of 0.1
|
||||||
|
short previouspose; //johnfitz -- animation lerping
|
||||||
|
short currentpose; //johnfitz -- animation lerping
|
||||||
|
// short futurepose; //johnfitz -- animation lerping
|
||||||
|
float movelerpstart; //johnfitz -- transform lerping
|
||||||
|
vec3_t previousorigin; //johnfitz -- transform lerping
|
||||||
|
vec3_t currentorigin; //johnfitz -- transform lerping
|
||||||
|
vec3_t previousangles; //johnfitz -- transform lerping
|
||||||
|
vec3_t currentangles; //johnfitz -- transform lerping
|
||||||
|
|
||||||
|
|
||||||
int z_head;
|
int z_head;
|
||||||
int z_larm;
|
int z_larm;
|
||||||
int z_rarm;
|
int z_rarm;
|
||||||
|
|
Loading…
Reference in a new issue