mirror of
https://git.code.sf.net/p/quake/newtree
synced 2024-11-22 04:01:17 +00:00
pr_edict.c: whitespace
rest: Implement model animation interpolation for alias models. Trying to implement this has been an annoyance for some time, but IT WORKS NOW. set gl_lerp_anims to zero to disable.
This commit is contained in:
parent
e886b0566d
commit
d8e1f27d4b
6 changed files with 367 additions and 189 deletions
|
@ -54,8 +54,7 @@ typedef struct
|
|||
|
||||
// player_state_t is the information needed by a player entity
|
||||
// to do move prediction and to generate a drawable entity
|
||||
typedef struct
|
||||
{
|
||||
typedef struct player_state_s {
|
||||
int messagenum; // all player's won't be updated each frame
|
||||
|
||||
double state_time; // not the same as the packet time,
|
||||
|
@ -67,6 +66,7 @@ typedef struct
|
|||
vec3_t velocity;
|
||||
int weaponframe;
|
||||
|
||||
int number;
|
||||
int modelindex;
|
||||
int frame;
|
||||
int skinnum;
|
||||
|
|
|
@ -79,6 +79,12 @@ typedef struct entity_s
|
|||
// FIXME: could turn these into a union
|
||||
int trivial_accept;
|
||||
struct mnode_s *topnode; // for bmodels, first world node that splits bmodel, or NULL if not split
|
||||
|
||||
// Animation interpolation
|
||||
float frame_start_time;
|
||||
float frame_interval;
|
||||
int pose1;
|
||||
int pose2;
|
||||
} entity_t;
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
||||
|
|
109
source/cl_ents.c
109
source/cl_ents.c
|
@ -355,21 +355,14 @@ CL_ParsePacketEntities (qboolean delta)
|
|||
|
||||
full = false;
|
||||
if (oldpacket != -1) {
|
||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) { // we
|
||||
// can't
|
||||
// use
|
||||
// this,
|
||||
// it
|
||||
// is
|
||||
// too
|
||||
// old
|
||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
||||
// we can't use this, it is too old
|
||||
FlushEntityPacket ();
|
||||
return;
|
||||
}
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
||||
} else { // this is a full update that we can
|
||||
// start delta compressing from now
|
||||
} else { // a full update that we can start delta compressing from now
|
||||
oldp = &dummy;
|
||||
dummy.num_entities = 0;
|
||||
cl.validsequence = cls.netchan.incoming_sequence;
|
||||
|
@ -489,8 +482,7 @@ CL_LinkPacketEntities (void)
|
|||
extern int cl_playerindex;
|
||||
extern int cl_h_playerindex, cl_gib1index, cl_gib2index, cl_gib3index;
|
||||
|
||||
pack =
|
||||
&cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].packet_entities;
|
||||
pack = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].packet_entities;
|
||||
|
||||
autorotate = anglemod (100 * cl.time);
|
||||
|
||||
|
@ -502,20 +494,15 @@ CL_LinkPacketEntities (void)
|
|||
|
||||
// spawn light flashes, even ones coming from invisible objects
|
||||
if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
||||
s1->origin[2], 200 + (rand () & 31), 0.1, 3);
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 3);
|
||||
else if (s1->effects & EF_BLUE)
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
||||
s1->origin[2], 200 + (rand () & 31), 0.1, 1);
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 1);
|
||||
else if (s1->effects & EF_RED)
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
||||
s1->origin[2], 200 + (rand () & 31), 0.1, 2);
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 2);
|
||||
else if (s1->effects & EF_BRIGHTLIGHT)
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
||||
s1->origin[2] + 16, 400 + (rand () & 31), 0.1, 0);
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand () & 31), 0.1, 0);
|
||||
else if (s1->effects & EF_DIMLIGHT)
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
||||
s1->origin[2], 200 + (rand () & 31), 0.1, 0);
|
||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 0);
|
||||
|
||||
// if set to invisible, skip
|
||||
if (!s1->modelindex)
|
||||
|
@ -536,8 +523,7 @@ CL_LinkPacketEntities (void)
|
|||
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||
break; // object list is full
|
||||
|
||||
ent = &cl_visedicts[cl_numvisedicts];
|
||||
cl_numvisedicts++;
|
||||
ent = &cl_visedicts[cl_numvisedicts++];
|
||||
|
||||
ent->keynum = s1->number;
|
||||
ent->model = model = cl.model_precache[s1->modelindex];
|
||||
|
@ -552,36 +538,22 @@ CL_LinkPacketEntities (void)
|
|||
ent->scoreboard = NULL;
|
||||
}
|
||||
|
||||
|
||||
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
|
||||
// Ender: Extend (Colormod) [QSG - Begin]
|
||||
// N.B: All messy code below is the sole fault of LordHavoc and
|
||||
// his futile attempts to save bandwidth. :)
|
||||
//
|
||||
ent->glowsize =
|
||||
s1->glowsize <
|
||||
128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
|
||||
// if (s1->glowsize != 0)
|
||||
// Con_Printf("glowsize: %d\n", s1->glowsize);
|
||||
ent->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
|
||||
ent->glowcolor = s1->glowcolor;
|
||||
// if (s1->glowcolor != 254)
|
||||
// Con_Printf("glowcolor: %d\n", s1->glowcolor);
|
||||
ent->alpha = s1->alpha / 255.0;
|
||||
// if (s1->alpha != 255)
|
||||
// Con_Printf("alpha: %d\n", s1->alpha);
|
||||
ent->scale = s1->scale / 16.0;
|
||||
// if (s1->scale != 16)
|
||||
// Con_Printf("scale: %d\n", s1->scale);
|
||||
|
||||
if (s1->colormod == 255)
|
||||
if (s1->colormod == 255) {
|
||||
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
|
||||
else {
|
||||
// Con_Printf("colormod: %d\n", s1->colormod);
|
||||
} else {
|
||||
ent->colormod[0] = (float) ((s1->colormod >> 5) & 7) * (1.0 / 7.0);
|
||||
ent->colormod[1] = (float) ((s1->colormod >> 2) & 7) * (1.0 / 7.0);
|
||||
ent->colormod[2] = (float) (s1->colormod & 3) * (1.0 / 3.0);
|
||||
}
|
||||
//
|
||||
// Ender: Extend (Colormod) [QSG - End]
|
||||
|
||||
// set skin
|
||||
|
@ -590,8 +562,7 @@ CL_LinkPacketEntities (void)
|
|||
// set frame
|
||||
ent->frame = s1->frame;
|
||||
|
||||
// rotate binary objects locally
|
||||
if (model->flags & EF_ROTATE) {
|
||||
if (model->flags & EF_ROTATE) { // rotate binary objects locally
|
||||
ent->angles[0] = 0;
|
||||
ent->angles[1] = autorotate;
|
||||
ent->angles[2] = 0;
|
||||
|
@ -611,8 +582,7 @@ CL_LinkPacketEntities (void)
|
|||
|
||||
// calculate origin
|
||||
for (i = 0; i < 3; i++)
|
||||
ent->origin[i] = s2->origin[i] +
|
||||
f * (s1->origin[i] - s2->origin[i]);
|
||||
ent->origin[i] = s2->origin[i] + f * (s1->origin[i] - s2->origin[i]);
|
||||
|
||||
// add automatic particle trails
|
||||
if (!model->flags)
|
||||
|
@ -621,12 +591,17 @@ CL_LinkPacketEntities (void)
|
|||
// scan the old entity display list for a matching
|
||||
for (i = 0; i < cl_oldnumvisedicts; i++) {
|
||||
if (cl_oldvisedicts[i].keynum == ent->keynum) {
|
||||
ent->frame_start_time = cl_oldvisedicts[i].frame_start_time;
|
||||
ent->frame_interval = cl_oldvisedicts[i].frame_interval;
|
||||
ent->pose1 = cl_oldvisedicts[i].pose1;
|
||||
ent->pose2 = cl_oldvisedicts[i].pose2;
|
||||
VectorCopy (cl_oldvisedicts[i].origin, old_origin);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == cl_oldnumvisedicts)
|
||||
continue; // not in last message
|
||||
|
||||
if (i == cl_oldnumvisedicts) // not in last message
|
||||
continue;
|
||||
|
||||
for (i = 0; i < 3; i++)
|
||||
if (abs (old_origin[i] - ent->origin[i]) > 128) { // no trail
|
||||
|
@ -634,6 +609,7 @@ CL_LinkPacketEntities (void)
|
|||
VectorCopy (ent->origin, old_origin);
|
||||
break;
|
||||
}
|
||||
|
||||
if (model->flags & EF_ROCKET) {
|
||||
R_RocketTrail (old_origin, ent->origin, 0, ent);
|
||||
dl = CL_AllocDlight (s1->number);
|
||||
|
@ -788,6 +764,7 @@ CL_ParsePlayerinfo (void)
|
|||
|
||||
state = &cl.frames[parsecountmod].playerstate[num];
|
||||
|
||||
state->number = num;
|
||||
flags = state->flags = MSG_ReadShort ();
|
||||
|
||||
state->messagenum = cl.parsecount;
|
||||
|
@ -944,7 +921,6 @@ CL_LinkPlayers (void)
|
|||
if (state->messagenum != cl.parsecount)
|
||||
continue; // not present this frame
|
||||
|
||||
// FIXME: Use a findvar or something for gl_flashblend --KB
|
||||
// spawn light flashes, even ones coming from invisible objects
|
||||
if (!gl_flashblend->int_val || j != cl.playernum) {
|
||||
|
||||
|
@ -986,12 +962,23 @@ CL_LinkPlayers (void)
|
|||
continue;
|
||||
|
||||
// grab an entity to fill in
|
||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||
break; // object list is full
|
||||
if (cl_numvisedicts == MAX_VISEDICTS) // object list is full
|
||||
break;
|
||||
|
||||
ent = &cl_visedicts[cl_numvisedicts];
|
||||
cl_numvisedicts++;
|
||||
ent->keynum = 0;
|
||||
|
||||
// scan the old entity display list for a matching player
|
||||
for (i = 0; i < cl_oldnumvisedicts; i++) {
|
||||
if (cl_oldvisedicts[i].keynum == state->number) {
|
||||
ent->frame_start_time = cl_oldvisedicts[i].frame_start_time;
|
||||
ent->frame_interval = cl_oldvisedicts[i].frame_interval;
|
||||
ent->pose1 = cl_oldvisedicts[i].pose1;
|
||||
ent->pose2 = cl_oldvisedicts[i].pose2;
|
||||
}
|
||||
}
|
||||
|
||||
ent->keynum = 0;
|
||||
ent->model = cl.model_precache[state->modelindex];
|
||||
ent->skinnum = state->skinnum;
|
||||
ent->frame = state->frame;
|
||||
|
@ -1019,17 +1006,10 @@ CL_LinkPlayers (void)
|
|||
|
||||
// only predict half the move to minimize overruns
|
||||
msec = 500 * (playertime - state->state_time);
|
||||
if (msec <= 0
|
||||
|| (!cl_predict_players->int_val
|
||||
&& !cl_predict_players2->int_val)) {
|
||||
if (msec <= 0 || (!cl_predict_players->int_val && !cl_predict_players2->int_val)) {
|
||||
VectorCopy (state->origin, ent->origin);
|
||||
//Con_DPrintf ("nopredict\n");
|
||||
} else {
|
||||
// predict players movement
|
||||
if (msec > 255)
|
||||
msec = 255;
|
||||
state->command.msec = msec;
|
||||
//Con_DPrintf ("predict: %i\n", msec);
|
||||
} else { // predict players movement
|
||||
state->command.msec = msec = min (msec, 255);
|
||||
|
||||
oldphysent = pmove.numphysent;
|
||||
CL_SetSolidPlayers (j);
|
||||
|
@ -1145,9 +1125,7 @@ CL_SetUpPlayerPrediction (qboolean dopred)
|
|||
// Con_DPrintf ("nopredict\n");
|
||||
} else {
|
||||
// predict players movement
|
||||
if (msec > 255)
|
||||
msec = 255;
|
||||
state->command.msec = msec;
|
||||
state->command.msec = msec = min (msec, 255);
|
||||
// Con_DPrintf ("predict: %i\n", msec);
|
||||
|
||||
CL_PredictUsercmd (state, &exact, &state->command, false);
|
||||
|
@ -1221,8 +1199,7 @@ CL_EmitEntities (void)
|
|||
return;
|
||||
|
||||
cl_oldnumvisedicts = cl_numvisedicts;
|
||||
cl_oldvisedicts =
|
||||
cl_visedicts_list[(cls.netchan.incoming_sequence - 1) & 1];
|
||||
cl_oldvisedicts = cl_visedicts_list[(cls.netchan.incoming_sequence - 1) & 1];
|
||||
cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence & 1];
|
||||
|
||||
cl_numvisedicts = 0;
|
||||
|
|
|
@ -50,7 +50,6 @@
|
|||
#include "va.h"
|
||||
#include "view.h"
|
||||
|
||||
|
||||
entity_t r_worldentity;
|
||||
|
||||
vec3_t modelorg, r_entorigin;
|
||||
|
@ -118,6 +117,7 @@ cvar_t *gl_playermip;
|
|||
cvar_t *gl_nocolors;
|
||||
cvar_t *gl_keeptjunctions;
|
||||
cvar_t *gl_particles;
|
||||
cvar_t *gl_lerp_anim;
|
||||
|
||||
cvar_t *r_skyname;
|
||||
cvar_t *gl_skymultipass;
|
||||
|
@ -356,12 +356,12 @@ float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
|
|||
|
||||
float *shadedots = r_avertexnormal_dots[0];
|
||||
|
||||
int lastposenum;
|
||||
int lastposenum, lastposenum0;
|
||||
|
||||
/*
|
||||
=============
|
||||
GL_DrawAliasFrame
|
||||
=============
|
||||
GL_DrawAliasFrame
|
||||
|
||||
Standard model drawing
|
||||
*/
|
||||
static void
|
||||
GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
||||
|
@ -385,8 +385,9 @@ GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
|||
if (count < 0) {
|
||||
count = -count;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
} else
|
||||
} else {
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
do {
|
||||
// texture coordinates come from the draw list
|
||||
|
@ -416,11 +417,76 @@ GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
|||
glColor3ubv (lighthalf_v);
|
||||
}
|
||||
|
||||
/*
|
||||
GL_DrawAliasBlendedFrame
|
||||
|
||||
Interpolated model drawing
|
||||
*/
|
||||
void
|
||||
GL_DrawAliasBlendedFrame (aliashdr_t *paliashdr, int pose1, int pose2, float blend, qboolean fb)
|
||||
{
|
||||
float l;
|
||||
trivertx_t *verts1;
|
||||
trivertx_t *verts2;
|
||||
int *order;
|
||||
int count;
|
||||
vec3_t d;
|
||||
|
||||
lastposenum0 = pose1;
|
||||
lastposenum = pose2;
|
||||
|
||||
verts1 = (trivertx_t *) ((byte *) paliashdr + paliashdr->posedata);
|
||||
verts2 = verts1;
|
||||
|
||||
verts1 += pose1 * paliashdr->poseverts;
|
||||
verts2 += pose2 * paliashdr->poseverts;
|
||||
|
||||
order = (int *) ((byte *) paliashdr + paliashdr->commands);
|
||||
|
||||
while ((count = *order++)) {
|
||||
// get the vertex count and primitive type
|
||||
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
} else {
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
do {
|
||||
// texture coordinates come from the draw list
|
||||
glTexCoord2f (((float *) order)[0], ((float *) order)[1]);
|
||||
order += 2;
|
||||
|
||||
if (fb) {
|
||||
glColor4f (1, 1, 1, modelalpha);
|
||||
} else {
|
||||
// normals and vertexes come from the frame list
|
||||
// blend the light intensity from the two frames together
|
||||
d[0] = shadedots[verts2->lightnormalindex] - shadedots[verts1->lightnormalindex];
|
||||
|
||||
l = shadelight * (shadedots[verts1->lightnormalindex] + (blend * d[0]));
|
||||
glColor4f (shadecolor[0] * l, shadecolor[1] * l, shadecolor[2] * l, modelalpha);
|
||||
}
|
||||
|
||||
VectorSubtract (verts2->v, verts1->v, d);
|
||||
|
||||
// blend the vertex positions from each frame together
|
||||
glVertex3f (verts1->v[0] + (blend * d[0]),
|
||||
verts1->v[1] + (blend * d[1]),
|
||||
verts1->v[2] + (blend * d[2]));
|
||||
|
||||
verts1++;
|
||||
verts2++;
|
||||
} while (--count);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
GL_DrawAliasShadow
|
||||
=============
|
||||
GL_DrawAliasShadow
|
||||
|
||||
Standard shadow drawing
|
||||
*/
|
||||
extern vec3_t lightspot;
|
||||
|
||||
|
@ -442,11 +508,9 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
|||
|
||||
height = -lheight + 1.0;
|
||||
|
||||
while (1) {
|
||||
while ((count = *order++)) {
|
||||
// get the vertex count and primitive type
|
||||
count = *order++;
|
||||
if (!count)
|
||||
break; // done
|
||||
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
|
@ -459,15 +523,9 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
|||
order += 2;
|
||||
|
||||
// normals and vertexes come from the frame list
|
||||
point[0] =
|
||||
verts->v[0] * paliashdr->mdl.scale[0] +
|
||||
paliashdr->mdl.scale_origin[0];
|
||||
point[1] =
|
||||
verts->v[1] * paliashdr->mdl.scale[1] +
|
||||
paliashdr->mdl.scale_origin[1];
|
||||
point[2] =
|
||||
verts->v[2] * paliashdr->mdl.scale[2] +
|
||||
paliashdr->mdl.scale_origin[2];
|
||||
point[0] = verts->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0];
|
||||
point[1] = verts->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1];
|
||||
point[2] = verts->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2];
|
||||
|
||||
point[0] -= shadevector[0] * (point[2] + lheight);
|
||||
point[1] -= shadevector[1] * (point[2] + lheight);
|
||||
|
@ -482,13 +540,75 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
GL_DrawAliasBlendedShadow
|
||||
|
||||
Interpolated shadow drawing
|
||||
*/
|
||||
void
|
||||
GL_DrawAliasBlendedShadow (aliashdr_t *paliashdr, int pose1, int pose2, entity_t *e)
|
||||
{
|
||||
trivertx_t *verts1, *verts2;
|
||||
vec3_t point1, point2, d;
|
||||
int *order, count;
|
||||
float height, lheight, blend;
|
||||
|
||||
blend = (realtime - e->frame_start_time) / e->frame_interval;
|
||||
blend = min (blend, 1);
|
||||
|
||||
lheight = e->origin[2] - lightspot[2];
|
||||
height = -lheight + 1.0;
|
||||
|
||||
verts2 = verts1 = (trivertx_t *) ((byte *) paliashdr + paliashdr->posedata);
|
||||
|
||||
verts1 += pose1 * paliashdr->poseverts;
|
||||
verts2 += pose2 * paliashdr->poseverts;
|
||||
|
||||
order = (int *) ((byte *) paliashdr + paliashdr->commands);
|
||||
|
||||
while ((count = *order++)) {
|
||||
// get the vertex count and primitive type
|
||||
|
||||
if (count < 0) {
|
||||
count = -count;
|
||||
glBegin (GL_TRIANGLE_FAN);
|
||||
} else {
|
||||
glBegin (GL_TRIANGLE_STRIP);
|
||||
}
|
||||
|
||||
do {
|
||||
order += 2;
|
||||
|
||||
point1[0] = verts1->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0];
|
||||
point1[1] = verts1->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1];
|
||||
point1[2] = verts1->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2];
|
||||
|
||||
point1[0] -= shadevector[0] * (point1[2] + lheight);
|
||||
point1[1] -= shadevector[1] * (point1[2] + lheight);
|
||||
|
||||
point2[0] = verts2->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0];
|
||||
point2[1] = verts2->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1];
|
||||
point2[2] = verts2->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2];
|
||||
|
||||
point2[0] -= shadevector[0] * (point2[2] + lheight);
|
||||
point2[1] -= shadevector[1] * (point2[2] + lheight);
|
||||
|
||||
VectorSubtract (point2, point1, d);
|
||||
|
||||
glVertex3f (point1[0] + (blend * d[0]), point1[1] + (blend * d[1]), height);
|
||||
|
||||
verts1++;
|
||||
verts2++;
|
||||
} while (--count);
|
||||
glEnd ();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
R_SetupAliasFrame
|
||||
R_SetupAliasFrame
|
||||
|
||||
=================
|
||||
*/
|
||||
static void
|
||||
R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb)
|
||||
|
@ -512,6 +632,56 @@ R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb)
|
|||
GL_DrawAliasFrame (paliashdr, pose, fb);
|
||||
}
|
||||
|
||||
/*
|
||||
R_SetupAliasBlendedFrame
|
||||
|
||||
|
||||
*/
|
||||
void
|
||||
R_SetupAliasBlendedFrame (int frame, aliashdr_t *paliashdr, entity_t *e, qboolean fb)
|
||||
{
|
||||
int pose, numposes;
|
||||
float blend;
|
||||
|
||||
if ((frame >= paliashdr->mdl.numframes) || (frame < 0)) {
|
||||
Con_DPrintf ("R_AliasSetupFrame: no such frame %d\n", frame);
|
||||
frame = 0;
|
||||
}
|
||||
|
||||
pose = paliashdr->frames[frame].firstpose;
|
||||
numposes = paliashdr->frames[frame].numposes;
|
||||
|
||||
if (numposes > 1) {
|
||||
e->frame_interval = paliashdr->frames[frame].interval;
|
||||
pose += (int) (cl.time / e->frame_interval) % numposes;
|
||||
} else {
|
||||
/* One tenth of a second is a 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. */
|
||||
e->frame_interval = 0.2;
|
||||
}
|
||||
|
||||
if (e->pose2 != pose) {
|
||||
e->frame_start_time = realtime;
|
||||
e->pose1 = e->pose2;
|
||||
e->pose2 = pose;
|
||||
blend = 0;
|
||||
} else {
|
||||
blend = (realtime - e->frame_start_time) / e->frame_interval;
|
||||
blend = min (blend, 1);
|
||||
}
|
||||
// Sys_Printf ("numposes: %d, pose1: %d, pose2: %d\n", numposes, e->pose1, e->pose2);
|
||||
|
||||
// wierd things start happening if blend passes 1
|
||||
if (cl.paused)
|
||||
blend = 1;
|
||||
|
||||
GL_DrawAliasBlendedFrame (paliashdr, e->pose1, e->pose2, blend, fb);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
|
@ -531,6 +701,7 @@ R_DrawAliasModel (entity_t *e)
|
|||
aliashdr_t *paliashdr;
|
||||
float an;
|
||||
int anim;
|
||||
qboolean torch = false;
|
||||
|
||||
clmodel = currententity->model;
|
||||
|
||||
|
@ -567,10 +738,9 @@ R_DrawAliasModel (entity_t *e)
|
|||
for (lnum = 0; lnum < MAX_DLIGHTS; lnum++) {
|
||||
if (cl_dlights[lnum].die >= cl.time) {
|
||||
VectorSubtract (currententity->origin,
|
||||
cl_dlights[lnum].origin, dist);
|
||||
add =
|
||||
(cl_dlights[lnum].radius * cl_dlights[lnum].radius * 8) /
|
||||
(DotProduct (dist, dist)); // FIXME Deek
|
||||
cl_dlights[lnum].origin,
|
||||
dist);
|
||||
add = (cl_dlights[lnum].radius * cl_dlights[lnum].radius * 8) / (DotProduct (dist, dist)); // FIXME Deek
|
||||
|
||||
if (add > 0) {
|
||||
shadelight += add;
|
||||
|
@ -582,18 +752,19 @@ R_DrawAliasModel (entity_t *e)
|
|||
shadelight = min (shadelight, 100);
|
||||
|
||||
// ZOID: never allow players to go totally black
|
||||
if (!strcmp (clmodel->name, "progs/player.mdl")) {
|
||||
if (strequal (clmodel->name, "progs/player.mdl")) {
|
||||
shadelight = max (shadelight, 8);
|
||||
} else if (!gl_fb_models->int_val
|
||||
&& (!strcmp (clmodel->name, "progs/flame.mdl")
|
||||
|| !strcmp (clmodel->name, "progs/flame2.mdl"))) {
|
||||
// HACK HACK HACK -- no fullbright colors, so make torches full light
|
||||
shadelight = 256;
|
||||
|
||||
}
|
||||
|
||||
shadedots =
|
||||
r_avertexnormal_dots[((int) (e->angles[1] * (SHADEDOT_QUANT / 360.0))) &
|
||||
(SHADEDOT_QUANT - 1)];
|
||||
if (strnequal (clmodel->name, "progs/flame", 11)) {
|
||||
torch = true;
|
||||
if (!gl_fb_models->int_val) { // make torches full brightness anyway
|
||||
shadelight = 256;
|
||||
}
|
||||
}
|
||||
|
||||
shadedots = r_avertexnormal_dots[((int) (e->angles[1] * (SHADEDOT_QUANT / 360.0))) & (SHADEDOT_QUANT - 1)];
|
||||
shadelight /= 200.0;
|
||||
|
||||
an = e->angles[1] / 180 * M_PI;
|
||||
|
@ -616,11 +787,11 @@ R_DrawAliasModel (entity_t *e)
|
|||
glPushMatrix ();
|
||||
R_RotateForEntity (e);
|
||||
|
||||
if (!strcmp (clmodel->name, "progs/eyes.mdl")) {
|
||||
if (strequal (clmodel->name, "progs/eyes.mdl")) {
|
||||
glTranslatef (paliashdr->mdl.scale_origin[0],
|
||||
paliashdr->mdl.scale_origin[1],
|
||||
paliashdr->mdl.scale_origin[2] - (22 + 8));
|
||||
// double size of eyes, since they are really hard to see in gl
|
||||
// double size of eyes, since they are really hard to see in GL
|
||||
glScalef (paliashdr->mdl.scale[0] * 2, paliashdr->mdl.scale[1] * 2,
|
||||
paliashdr->mdl.scale[2] * 2);
|
||||
} else {
|
||||
|
@ -650,16 +821,22 @@ R_DrawAliasModel (entity_t *e)
|
|||
if (gl_affinemodels->int_val)
|
||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
||||
|
||||
if (gl_lerp_anim->int_val && !torch) {
|
||||
R_SetupAliasBlendedFrame (currententity->frame, paliashdr, currententity, false);
|
||||
} else {
|
||||
R_SetupAliasFrame (currententity->frame, paliashdr, false);
|
||||
}
|
||||
|
||||
// This block is GL fullbright support for objects...
|
||||
if (clmodel->hasfullbrights && gl_fb_models->int_val &&
|
||||
paliashdr->gl_fb_texturenum[currententity->skinnum][anim]) {
|
||||
glBindTexture (GL_TEXTURE_2D,
|
||||
paliashdr->gl_fb_texturenum[currententity->
|
||||
skinnum][anim]);
|
||||
glBindTexture (GL_TEXTURE_2D, paliashdr->gl_fb_texturenum[currententity->skinnum][anim]);
|
||||
if (gl_lerp_anim->int_val && !torch) {
|
||||
R_SetupAliasBlendedFrame (currententity->frame, paliashdr, currententity, true);
|
||||
} else {
|
||||
R_SetupAliasFrame (currententity->frame, paliashdr, true);
|
||||
}
|
||||
}
|
||||
|
||||
if (gl_affinemodels->int_val)
|
||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||
|
@ -667,16 +844,30 @@ R_DrawAliasModel (entity_t *e)
|
|||
glPopMatrix ();
|
||||
|
||||
if (r_shadows->int_val) {
|
||||
// torches, grenades, and lightning bolts do not have shadows
|
||||
if (torch)
|
||||
return;
|
||||
if (strequal (clmodel->name, "progs/grenade.mdl"))
|
||||
return;
|
||||
if (strnequal (clmodel->name, "progs/bolt", 10))
|
||||
return;
|
||||
|
||||
glPushMatrix ();
|
||||
R_RotateForEntity (e);
|
||||
|
||||
glDisable (GL_TEXTURE_2D);
|
||||
glColor4f (0, 0, 0, 0.5);
|
||||
|
||||
if (gl_lerp_anim->int_val) {
|
||||
GL_DrawAliasBlendedShadow (paliashdr, lastposenum0, lastposenum, currententity);
|
||||
} else {
|
||||
GL_DrawAliasShadow (paliashdr, lastposenum);
|
||||
}
|
||||
|
||||
glEnable (GL_TEXTURE_2D);
|
||||
glColor3ubv (lighthalf_v);
|
||||
glPopMatrix ();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//==================================================================================
|
||||
|
@ -810,7 +1001,7 @@ R_SetupFrame
|
|||
static void
|
||||
R_SetupFrame (void)
|
||||
{
|
||||
// don't allow cheats in multiplayer
|
||||
// don't allow cheats in multiplayer
|
||||
if (!atoi (Info_ValueForKey (cl.serverinfo, "watervis")))
|
||||
Cvar_SetValue (r_wateralpha, 1);
|
||||
|
||||
|
@ -818,12 +1009,12 @@ R_SetupFrame (void)
|
|||
|
||||
r_framecount++;
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
// build the transformation matrix for the given view angles
|
||||
VectorCopy (r_refdef.vieworg, r_origin);
|
||||
|
||||
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
|
||||
|
||||
// current viewleaf
|
||||
// current viewleaf
|
||||
r_oldviewleaf = r_viewleaf;
|
||||
r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
|
||||
|
||||
|
|
|
@ -65,6 +65,7 @@ void R_InitBubble ();
|
|||
void R_FireColor_f (void);
|
||||
|
||||
cvar_t *gl_fires;
|
||||
extern cvar_t *gl_lerp_anim;
|
||||
qboolean allowskybox; // allow skyboxes? --KB
|
||||
|
||||
/*
|
||||
|
@ -252,6 +253,9 @@ R_Init_Cvars (void)
|
|||
|
||||
gl_keeptjunctions = Cvar_Get ("gl_keeptjunctions", "1", CVAR_NONE, "None");
|
||||
|
||||
gl_lerp_anim = Cvar_Get ("gl_lerp_anim", "1", CVAR_ARCHIVE,
|
||||
"Toggles model animation interpolation");
|
||||
|
||||
r_skyname = Cvar_Get ("r_skyname", "none", CVAR_NONE,
|
||||
"name of the current skybox");
|
||||
gl_skymultipass = Cvar_Get ("gl_skymultipass", "1", CVAR_NONE,
|
||||
|
|
Loading…
Reference in a new issue