mirror of
https://git.code.sf.net/p/quake/newtree
synced 2024-11-25 21:41:57 +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
|
// player_state_t is the information needed by a player entity
|
||||||
// to do move prediction and to generate a drawable 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
|
int messagenum; // all player's won't be updated each frame
|
||||||
|
|
||||||
double state_time; // not the same as the packet time,
|
double state_time; // not the same as the packet time,
|
||||||
|
@ -67,6 +66,7 @@ typedef struct
|
||||||
vec3_t velocity;
|
vec3_t velocity;
|
||||||
int weaponframe;
|
int weaponframe;
|
||||||
|
|
||||||
|
int number;
|
||||||
int modelindex;
|
int modelindex;
|
||||||
int frame;
|
int frame;
|
||||||
int skinnum;
|
int skinnum;
|
||||||
|
|
|
@ -79,6 +79,12 @@ typedef struct entity_s
|
||||||
// FIXME: could turn these into a union
|
// FIXME: could turn these into a union
|
||||||
int trivial_accept;
|
int trivial_accept;
|
||||||
struct mnode_s *topnode; // for bmodels, first world node that splits bmodel, or NULL if not split
|
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;
|
} entity_t;
|
||||||
|
|
||||||
// !!! if this is changed, it must be changed in asm_draw.h too !!!
|
// !!! 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;
|
full = false;
|
||||||
if (oldpacket != -1) {
|
if (oldpacket != -1) {
|
||||||
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) { // we
|
if (cls.netchan.outgoing_sequence - oldpacket >= UPDATE_BACKUP - 1) {
|
||||||
// can't
|
// we can't use this, it is too old
|
||||||
// use
|
|
||||||
// this,
|
|
||||||
// it
|
|
||||||
// is
|
|
||||||
// too
|
|
||||||
// old
|
|
||||||
FlushEntityPacket ();
|
FlushEntityPacket ();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cl.validsequence = cls.netchan.incoming_sequence;
|
cl.validsequence = cls.netchan.incoming_sequence;
|
||||||
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
oldp = &cl.frames[oldpacket & UPDATE_MASK].packet_entities;
|
||||||
} else { // this is a full update that we can
|
} else { // a full update that we can start delta compressing from now
|
||||||
// start delta compressing from now
|
|
||||||
oldp = &dummy;
|
oldp = &dummy;
|
||||||
dummy.num_entities = 0;
|
dummy.num_entities = 0;
|
||||||
cl.validsequence = cls.netchan.incoming_sequence;
|
cl.validsequence = cls.netchan.incoming_sequence;
|
||||||
|
@ -489,8 +482,7 @@ CL_LinkPacketEntities (void)
|
||||||
extern int cl_playerindex;
|
extern int cl_playerindex;
|
||||||
extern int cl_h_playerindex, cl_gib1index, cl_gib2index, cl_gib3index;
|
extern int cl_h_playerindex, cl_gib1index, cl_gib2index, cl_gib3index;
|
||||||
|
|
||||||
pack =
|
pack = &cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].packet_entities;
|
||||||
&cl.frames[cls.netchan.incoming_sequence & UPDATE_MASK].packet_entities;
|
|
||||||
|
|
||||||
autorotate = anglemod (100 * cl.time);
|
autorotate = anglemod (100 * cl.time);
|
||||||
|
|
||||||
|
@ -502,20 +494,15 @@ CL_LinkPacketEntities (void)
|
||||||
|
|
||||||
// spawn light flashes, even ones coming from invisible objects
|
// spawn light flashes, even ones coming from invisible objects
|
||||||
if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
|
if ((s1->effects & (EF_BLUE | EF_RED)) == (EF_BLUE | EF_RED))
|
||||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 3);
|
||||||
s1->origin[2], 200 + (rand () & 31), 0.1, 3);
|
|
||||||
else if (s1->effects & EF_BLUE)
|
else if (s1->effects & EF_BLUE)
|
||||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 1);
|
||||||
s1->origin[2], 200 + (rand () & 31), 0.1, 1);
|
|
||||||
else if (s1->effects & EF_RED)
|
else if (s1->effects & EF_RED)
|
||||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 2);
|
||||||
s1->origin[2], 200 + (rand () & 31), 0.1, 2);
|
|
||||||
else if (s1->effects & EF_BRIGHTLIGHT)
|
else if (s1->effects & EF_BRIGHTLIGHT)
|
||||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2] + 16, 400 + (rand () & 31), 0.1, 0);
|
||||||
s1->origin[2] + 16, 400 + (rand () & 31), 0.1, 0);
|
|
||||||
else if (s1->effects & EF_DIMLIGHT)
|
else if (s1->effects & EF_DIMLIGHT)
|
||||||
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1],
|
CL_NewDlight (s1->number, s1->origin[0], s1->origin[1], s1->origin[2], 200 + (rand () & 31), 0.1, 0);
|
||||||
s1->origin[2], 200 + (rand () & 31), 0.1, 0);
|
|
||||||
|
|
||||||
// if set to invisible, skip
|
// if set to invisible, skip
|
||||||
if (!s1->modelindex)
|
if (!s1->modelindex)
|
||||||
|
@ -536,8 +523,7 @@ CL_LinkPacketEntities (void)
|
||||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
if (cl_numvisedicts == MAX_VISEDICTS)
|
||||||
break; // object list is full
|
break; // object list is full
|
||||||
|
|
||||||
ent = &cl_visedicts[cl_numvisedicts];
|
ent = &cl_visedicts[cl_numvisedicts++];
|
||||||
cl_numvisedicts++;
|
|
||||||
|
|
||||||
ent->keynum = s1->number;
|
ent->keynum = s1->number;
|
||||||
ent->model = model = cl.model_precache[s1->modelindex];
|
ent->model = model = cl.model_precache[s1->modelindex];
|
||||||
|
@ -552,36 +538,22 @@ CL_LinkPacketEntities (void)
|
||||||
ent->scoreboard = NULL;
|
ent->scoreboard = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
|
// LordHavoc: cleaned up Endy's coding style, and fixed Endy's bugs
|
||||||
// Ender: Extend (Colormod) [QSG - Begin]
|
// Ender: Extend (Colormod) [QSG - Begin]
|
||||||
// N.B: All messy code below is the sole fault of LordHavoc and
|
// N.B: All messy code below is the sole fault of LordHavoc and
|
||||||
// his futile attempts to save bandwidth. :)
|
// his futile attempts to save bandwidth. :)
|
||||||
//
|
ent->glowsize = s1->glowsize < 128 ? s1->glowsize * 8.0 : (s1->glowsize - 256) * 8.0;
|
||||||
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->glowcolor = s1->glowcolor;
|
ent->glowcolor = s1->glowcolor;
|
||||||
// if (s1->glowcolor != 254)
|
|
||||||
// Con_Printf("glowcolor: %d\n", s1->glowcolor);
|
|
||||||
ent->alpha = s1->alpha / 255.0;
|
ent->alpha = s1->alpha / 255.0;
|
||||||
// if (s1->alpha != 255)
|
|
||||||
// Con_Printf("alpha: %d\n", s1->alpha);
|
|
||||||
ent->scale = s1->scale / 16.0;
|
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;
|
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
|
||||||
else {
|
} else {
|
||||||
// Con_Printf("colormod: %d\n", s1->colormod);
|
|
||||||
ent->colormod[0] = (float) ((s1->colormod >> 5) & 7) * (1.0 / 7.0);
|
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[1] = (float) ((s1->colormod >> 2) & 7) * (1.0 / 7.0);
|
||||||
ent->colormod[2] = (float) (s1->colormod & 3) * (1.0 / 3.0);
|
ent->colormod[2] = (float) (s1->colormod & 3) * (1.0 / 3.0);
|
||||||
}
|
}
|
||||||
//
|
|
||||||
// Ender: Extend (Colormod) [QSG - End]
|
// Ender: Extend (Colormod) [QSG - End]
|
||||||
|
|
||||||
// set skin
|
// set skin
|
||||||
|
@ -590,8 +562,7 @@ CL_LinkPacketEntities (void)
|
||||||
// set frame
|
// set frame
|
||||||
ent->frame = s1->frame;
|
ent->frame = s1->frame;
|
||||||
|
|
||||||
// rotate binary objects locally
|
if (model->flags & EF_ROTATE) { // rotate binary objects locally
|
||||||
if (model->flags & EF_ROTATE) {
|
|
||||||
ent->angles[0] = 0;
|
ent->angles[0] = 0;
|
||||||
ent->angles[1] = autorotate;
|
ent->angles[1] = autorotate;
|
||||||
ent->angles[2] = 0;
|
ent->angles[2] = 0;
|
||||||
|
@ -611,8 +582,7 @@ CL_LinkPacketEntities (void)
|
||||||
|
|
||||||
// calculate origin
|
// calculate origin
|
||||||
for (i = 0; i < 3; i++)
|
for (i = 0; i < 3; i++)
|
||||||
ent->origin[i] = s2->origin[i] +
|
ent->origin[i] = s2->origin[i] + f * (s1->origin[i] - s2->origin[i]);
|
||||||
f * (s1->origin[i] - s2->origin[i]);
|
|
||||||
|
|
||||||
// add automatic particle trails
|
// add automatic particle trails
|
||||||
if (!model->flags)
|
if (!model->flags)
|
||||||
|
@ -621,12 +591,17 @@ CL_LinkPacketEntities (void)
|
||||||
// scan the old entity display list for a matching
|
// scan the old entity display list for a matching
|
||||||
for (i = 0; i < cl_oldnumvisedicts; i++) {
|
for (i = 0; i < cl_oldnumvisedicts; i++) {
|
||||||
if (cl_oldvisedicts[i].keynum == ent->keynum) {
|
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);
|
VectorCopy (cl_oldvisedicts[i].origin, old_origin);
|
||||||
break;
|
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++)
|
for (i = 0; i < 3; i++)
|
||||||
if (abs (old_origin[i] - ent->origin[i]) > 128) { // no trail
|
if (abs (old_origin[i] - ent->origin[i]) > 128) { // no trail
|
||||||
|
@ -634,6 +609,7 @@ CL_LinkPacketEntities (void)
|
||||||
VectorCopy (ent->origin, old_origin);
|
VectorCopy (ent->origin, old_origin);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (model->flags & EF_ROCKET) {
|
if (model->flags & EF_ROCKET) {
|
||||||
R_RocketTrail (old_origin, ent->origin, 0, ent);
|
R_RocketTrail (old_origin, ent->origin, 0, ent);
|
||||||
dl = CL_AllocDlight (s1->number);
|
dl = CL_AllocDlight (s1->number);
|
||||||
|
@ -788,6 +764,7 @@ CL_ParsePlayerinfo (void)
|
||||||
|
|
||||||
state = &cl.frames[parsecountmod].playerstate[num];
|
state = &cl.frames[parsecountmod].playerstate[num];
|
||||||
|
|
||||||
|
state->number = num;
|
||||||
flags = state->flags = MSG_ReadShort ();
|
flags = state->flags = MSG_ReadShort ();
|
||||||
|
|
||||||
state->messagenum = cl.parsecount;
|
state->messagenum = cl.parsecount;
|
||||||
|
@ -944,7 +921,6 @@ CL_LinkPlayers (void)
|
||||||
if (state->messagenum != cl.parsecount)
|
if (state->messagenum != cl.parsecount)
|
||||||
continue; // not present this frame
|
continue; // not present this frame
|
||||||
|
|
||||||
// FIXME: Use a findvar or something for gl_flashblend --KB
|
|
||||||
// spawn light flashes, even ones coming from invisible objects
|
// spawn light flashes, even ones coming from invisible objects
|
||||||
if (!gl_flashblend->int_val || j != cl.playernum) {
|
if (!gl_flashblend->int_val || j != cl.playernum) {
|
||||||
|
|
||||||
|
@ -986,12 +962,23 @@ CL_LinkPlayers (void)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// grab an entity to fill in
|
// grab an entity to fill in
|
||||||
if (cl_numvisedicts == MAX_VISEDICTS)
|
if (cl_numvisedicts == MAX_VISEDICTS) // object list is full
|
||||||
break; // object list is full
|
break;
|
||||||
|
|
||||||
ent = &cl_visedicts[cl_numvisedicts];
|
ent = &cl_visedicts[cl_numvisedicts];
|
||||||
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->model = cl.model_precache[state->modelindex];
|
||||||
ent->skinnum = state->skinnum;
|
ent->skinnum = state->skinnum;
|
||||||
ent->frame = state->frame;
|
ent->frame = state->frame;
|
||||||
|
@ -1019,17 +1006,10 @@ CL_LinkPlayers (void)
|
||||||
|
|
||||||
// only predict half the move to minimize overruns
|
// only predict half the move to minimize overruns
|
||||||
msec = 500 * (playertime - state->state_time);
|
msec = 500 * (playertime - state->state_time);
|
||||||
if (msec <= 0
|
if (msec <= 0 || (!cl_predict_players->int_val && !cl_predict_players2->int_val)) {
|
||||||
|| (!cl_predict_players->int_val
|
|
||||||
&& !cl_predict_players2->int_val)) {
|
|
||||||
VectorCopy (state->origin, ent->origin);
|
VectorCopy (state->origin, ent->origin);
|
||||||
//Con_DPrintf ("nopredict\n");
|
} else { // predict players movement
|
||||||
} else {
|
state->command.msec = msec = min (msec, 255);
|
||||||
// predict players movement
|
|
||||||
if (msec > 255)
|
|
||||||
msec = 255;
|
|
||||||
state->command.msec = msec;
|
|
||||||
//Con_DPrintf ("predict: %i\n", msec);
|
|
||||||
|
|
||||||
oldphysent = pmove.numphysent;
|
oldphysent = pmove.numphysent;
|
||||||
CL_SetSolidPlayers (j);
|
CL_SetSolidPlayers (j);
|
||||||
|
@ -1145,9 +1125,7 @@ CL_SetUpPlayerPrediction (qboolean dopred)
|
||||||
// Con_DPrintf ("nopredict\n");
|
// Con_DPrintf ("nopredict\n");
|
||||||
} else {
|
} else {
|
||||||
// predict players movement
|
// predict players movement
|
||||||
if (msec > 255)
|
state->command.msec = msec = min (msec, 255);
|
||||||
msec = 255;
|
|
||||||
state->command.msec = msec;
|
|
||||||
// Con_DPrintf ("predict: %i\n", msec);
|
// Con_DPrintf ("predict: %i\n", msec);
|
||||||
|
|
||||||
CL_PredictUsercmd (state, &exact, &state->command, false);
|
CL_PredictUsercmd (state, &exact, &state->command, false);
|
||||||
|
@ -1221,8 +1199,7 @@ CL_EmitEntities (void)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
cl_oldnumvisedicts = cl_numvisedicts;
|
cl_oldnumvisedicts = cl_numvisedicts;
|
||||||
cl_oldvisedicts =
|
cl_oldvisedicts = cl_visedicts_list[(cls.netchan.incoming_sequence - 1) & 1];
|
||||||
cl_visedicts_list[(cls.netchan.incoming_sequence - 1) & 1];
|
|
||||||
cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence & 1];
|
cl_visedicts = cl_visedicts_list[cls.netchan.incoming_sequence & 1];
|
||||||
|
|
||||||
cl_numvisedicts = 0;
|
cl_numvisedicts = 0;
|
||||||
|
|
|
@ -50,7 +50,6 @@
|
||||||
#include "va.h"
|
#include "va.h"
|
||||||
#include "view.h"
|
#include "view.h"
|
||||||
|
|
||||||
|
|
||||||
entity_t r_worldentity;
|
entity_t r_worldentity;
|
||||||
|
|
||||||
vec3_t modelorg, r_entorigin;
|
vec3_t modelorg, r_entorigin;
|
||||||
|
@ -118,6 +117,7 @@ cvar_t *gl_playermip;
|
||||||
cvar_t *gl_nocolors;
|
cvar_t *gl_nocolors;
|
||||||
cvar_t *gl_keeptjunctions;
|
cvar_t *gl_keeptjunctions;
|
||||||
cvar_t *gl_particles;
|
cvar_t *gl_particles;
|
||||||
|
cvar_t *gl_lerp_anim;
|
||||||
|
|
||||||
cvar_t *r_skyname;
|
cvar_t *r_skyname;
|
||||||
cvar_t *gl_skymultipass;
|
cvar_t *gl_skymultipass;
|
||||||
|
@ -356,12 +356,12 @@ float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
|
||||||
|
|
||||||
float *shadedots = r_avertexnormal_dots[0];
|
float *shadedots = r_avertexnormal_dots[0];
|
||||||
|
|
||||||
int lastposenum;
|
int lastposenum, lastposenum0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
=============
|
|
||||||
GL_DrawAliasFrame
|
GL_DrawAliasFrame
|
||||||
=============
|
|
||||||
|
Standard model drawing
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
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) {
|
if (count < 0) {
|
||||||
count = -count;
|
count = -count;
|
||||||
glBegin (GL_TRIANGLE_FAN);
|
glBegin (GL_TRIANGLE_FAN);
|
||||||
} else
|
} else {
|
||||||
glBegin (GL_TRIANGLE_STRIP);
|
glBegin (GL_TRIANGLE_STRIP);
|
||||||
|
}
|
||||||
|
|
||||||
do {
|
do {
|
||||||
// texture coordinates come from the draw list
|
// texture coordinates come from the draw list
|
||||||
|
@ -416,11 +417,76 @@ GL_DrawAliasFrame (aliashdr_t *paliashdr, int posenum, qboolean fb)
|
||||||
glColor3ubv (lighthalf_v);
|
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;
|
extern vec3_t lightspot;
|
||||||
|
|
||||||
|
@ -442,11 +508,9 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
||||||
|
|
||||||
height = -lheight + 1.0;
|
height = -lheight + 1.0;
|
||||||
|
|
||||||
while (1) {
|
while ((count = *order++)) {
|
||||||
// get the vertex count and primitive type
|
// get the vertex count and primitive type
|
||||||
count = *order++;
|
|
||||||
if (!count)
|
|
||||||
break; // done
|
|
||||||
if (count < 0) {
|
if (count < 0) {
|
||||||
count = -count;
|
count = -count;
|
||||||
glBegin (GL_TRIANGLE_FAN);
|
glBegin (GL_TRIANGLE_FAN);
|
||||||
|
@ -459,15 +523,9 @@ GL_DrawAliasShadow (aliashdr_t *paliashdr, int posenum)
|
||||||
order += 2;
|
order += 2;
|
||||||
|
|
||||||
// normals and vertexes come from the frame list
|
// normals and vertexes come from the frame list
|
||||||
point[0] =
|
point[0] = verts->v[0] * paliashdr->mdl.scale[0] + paliashdr->mdl.scale_origin[0];
|
||||||
verts->v[0] * paliashdr->mdl.scale[0] +
|
point[1] = verts->v[1] * paliashdr->mdl.scale[1] + paliashdr->mdl.scale_origin[1];
|
||||||
paliashdr->mdl.scale_origin[0];
|
point[2] = verts->v[2] * paliashdr->mdl.scale[2] + paliashdr->mdl.scale_origin[2];
|
||||||
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[0] -= shadevector[0] * (point[2] + lheight);
|
||||||
point[1] -= shadevector[1] * (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
|
static void
|
||||||
R_SetupAliasFrame (int frame, aliashdr_t *paliashdr, qboolean fb)
|
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);
|
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;
|
aliashdr_t *paliashdr;
|
||||||
float an;
|
float an;
|
||||||
int anim;
|
int anim;
|
||||||
|
qboolean torch = false;
|
||||||
|
|
||||||
clmodel = currententity->model;
|
clmodel = currententity->model;
|
||||||
|
|
||||||
|
@ -567,10 +738,9 @@ R_DrawAliasModel (entity_t *e)
|
||||||
for (lnum = 0; lnum < MAX_DLIGHTS; lnum++) {
|
for (lnum = 0; lnum < MAX_DLIGHTS; lnum++) {
|
||||||
if (cl_dlights[lnum].die >= cl.time) {
|
if (cl_dlights[lnum].die >= cl.time) {
|
||||||
VectorSubtract (currententity->origin,
|
VectorSubtract (currententity->origin,
|
||||||
cl_dlights[lnum].origin, dist);
|
cl_dlights[lnum].origin,
|
||||||
add =
|
dist);
|
||||||
(cl_dlights[lnum].radius * cl_dlights[lnum].radius * 8) /
|
add = (cl_dlights[lnum].radius * cl_dlights[lnum].radius * 8) / (DotProduct (dist, dist)); // FIXME Deek
|
||||||
(DotProduct (dist, dist)); // FIXME Deek
|
|
||||||
|
|
||||||
if (add > 0) {
|
if (add > 0) {
|
||||||
shadelight += add;
|
shadelight += add;
|
||||||
|
@ -582,18 +752,19 @@ R_DrawAliasModel (entity_t *e)
|
||||||
shadelight = min (shadelight, 100);
|
shadelight = min (shadelight, 100);
|
||||||
|
|
||||||
// ZOID: never allow players to go totally black
|
// 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);
|
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 =
|
if (strnequal (clmodel->name, "progs/flame", 11)) {
|
||||||
r_avertexnormal_dots[((int) (e->angles[1] * (SHADEDOT_QUANT / 360.0))) &
|
torch = true;
|
||||||
(SHADEDOT_QUANT - 1)];
|
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;
|
shadelight /= 200.0;
|
||||||
|
|
||||||
an = e->angles[1] / 180 * M_PI;
|
an = e->angles[1] / 180 * M_PI;
|
||||||
|
@ -616,11 +787,11 @@ R_DrawAliasModel (entity_t *e)
|
||||||
glPushMatrix ();
|
glPushMatrix ();
|
||||||
R_RotateForEntity (e);
|
R_RotateForEntity (e);
|
||||||
|
|
||||||
if (!strcmp (clmodel->name, "progs/eyes.mdl")) {
|
if (strequal (clmodel->name, "progs/eyes.mdl")) {
|
||||||
glTranslatef (paliashdr->mdl.scale_origin[0],
|
glTranslatef (paliashdr->mdl.scale_origin[0],
|
||||||
paliashdr->mdl.scale_origin[1],
|
paliashdr->mdl.scale_origin[1],
|
||||||
paliashdr->mdl.scale_origin[2] - (22 + 8));
|
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,
|
glScalef (paliashdr->mdl.scale[0] * 2, paliashdr->mdl.scale[1] * 2,
|
||||||
paliashdr->mdl.scale[2] * 2);
|
paliashdr->mdl.scale[2] * 2);
|
||||||
} else {
|
} else {
|
||||||
|
@ -650,16 +821,22 @@ R_DrawAliasModel (entity_t *e)
|
||||||
if (gl_affinemodels->int_val)
|
if (gl_affinemodels->int_val)
|
||||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
|
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);
|
R_SetupAliasFrame (currententity->frame, paliashdr, false);
|
||||||
|
}
|
||||||
|
|
||||||
// This block is GL fullbright support for objects...
|
// This block is GL fullbright support for objects...
|
||||||
if (clmodel->hasfullbrights && gl_fb_models->int_val &&
|
if (clmodel->hasfullbrights && gl_fb_models->int_val &&
|
||||||
paliashdr->gl_fb_texturenum[currententity->skinnum][anim]) {
|
paliashdr->gl_fb_texturenum[currententity->skinnum][anim]) {
|
||||||
glBindTexture (GL_TEXTURE_2D,
|
glBindTexture (GL_TEXTURE_2D, paliashdr->gl_fb_texturenum[currententity->skinnum][anim]);
|
||||||
paliashdr->gl_fb_texturenum[currententity->
|
if (gl_lerp_anim->int_val && !torch) {
|
||||||
skinnum][anim]);
|
R_SetupAliasBlendedFrame (currententity->frame, paliashdr, currententity, true);
|
||||||
|
} else {
|
||||||
R_SetupAliasFrame (currententity->frame, paliashdr, true);
|
R_SetupAliasFrame (currententity->frame, paliashdr, true);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (gl_affinemodels->int_val)
|
if (gl_affinemodels->int_val)
|
||||||
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
|
||||||
|
@ -667,16 +844,30 @@ R_DrawAliasModel (entity_t *e)
|
||||||
glPopMatrix ();
|
glPopMatrix ();
|
||||||
|
|
||||||
if (r_shadows->int_val) {
|
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 ();
|
glPushMatrix ();
|
||||||
R_RotateForEntity (e);
|
R_RotateForEntity (e);
|
||||||
|
|
||||||
glDisable (GL_TEXTURE_2D);
|
glDisable (GL_TEXTURE_2D);
|
||||||
glColor4f (0, 0, 0, 0.5);
|
glColor4f (0, 0, 0, 0.5);
|
||||||
|
|
||||||
|
if (gl_lerp_anim->int_val) {
|
||||||
|
GL_DrawAliasBlendedShadow (paliashdr, lastposenum0, lastposenum, currententity);
|
||||||
|
} else {
|
||||||
GL_DrawAliasShadow (paliashdr, lastposenum);
|
GL_DrawAliasShadow (paliashdr, lastposenum);
|
||||||
|
}
|
||||||
|
|
||||||
glEnable (GL_TEXTURE_2D);
|
glEnable (GL_TEXTURE_2D);
|
||||||
glColor3ubv (lighthalf_v);
|
glColor3ubv (lighthalf_v);
|
||||||
glPopMatrix ();
|
glPopMatrix ();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//==================================================================================
|
//==================================================================================
|
||||||
|
|
|
@ -65,6 +65,7 @@ void R_InitBubble ();
|
||||||
void R_FireColor_f (void);
|
void R_FireColor_f (void);
|
||||||
|
|
||||||
cvar_t *gl_fires;
|
cvar_t *gl_fires;
|
||||||
|
extern cvar_t *gl_lerp_anim;
|
||||||
qboolean allowskybox; // allow skyboxes? --KB
|
qboolean allowskybox; // allow skyboxes? --KB
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -252,6 +253,9 @@ R_Init_Cvars (void)
|
||||||
|
|
||||||
gl_keeptjunctions = Cvar_Get ("gl_keeptjunctions", "1", CVAR_NONE, "None");
|
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,
|
r_skyname = Cvar_Get ("r_skyname", "none", CVAR_NONE,
|
||||||
"name of the current skybox");
|
"name of the current skybox");
|
||||||
gl_skymultipass = Cvar_Get ("gl_skymultipass", "1", CVAR_NONE,
|
gl_skymultipass = Cvar_Get ("gl_skymultipass", "1", CVAR_NONE,
|
||||||
|
|
Loading…
Reference in a new issue