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:
Jeff Teunissen 2000-12-11 09:59:27 +00:00
parent e886b0566d
commit d8e1f27d4b
6 changed files with 367 additions and 189 deletions

View file

@ -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;

View file

@ -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 !!!

View file

@ -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);
@ -498,24 +490,19 @@ CL_LinkPacketEntities (void)
for (pnum = 0; pnum < pack->num_entities; pnum++) {
s1 = &pack->entities[pnum];
s2 = s1; // FIXME: no interpolation right now
s2 = s1; // FIXME: no interpolation right now
// 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);
@ -781,13 +757,14 @@ CL_ParsePlayerinfo (void)
num = MSG_ReadByte ();
if (num > MAX_CLIENTS)
// Sys_Error ("CL_ParsePlayerinfo: bad num");
// Sys_Error ("CL_ParsePlayerinfo: bad num");
Host_EndGame ("CL_ParsePlayerinfo: bad num");
info = &cl.players[num];
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;

View file

@ -50,83 +50,83 @@
#include "va.h"
#include "view.h"
entity_t r_worldentity;
entity_t r_worldentity;
vec3_t modelorg, r_entorigin;
entity_t *currententity;
vec3_t modelorg, r_entorigin;
entity_t *currententity;
int r_visframecount; // bumped when going to a new PVS
int r_framecount; // used for dlight push checking
int r_visframecount; // bumped when going to a new PVS
int r_framecount; // used for dlight push checking
mplane_t frustum[4];
mplane_t frustum[4];
int c_brush_polys, c_alias_polys;
int c_brush_polys, c_alias_polys;
qboolean envmap; // true during envmap command capture
qboolean envmap; // true during envmap command capture
//
int playertextures; // up to 16 color translated skins
int playertextures; // up to 16 color translated skins
//
// view origin
//
vec3_t vup;
vec3_t vpn;
vec3_t vright;
vec3_t r_origin;
vec3_t vup;
vec3_t vpn;
vec3_t vright;
vec3_t r_origin;
float r_world_matrix[16];
float r_base_world_matrix[16];
float r_world_matrix[16];
float r_base_world_matrix[16];
//
// screen size info
//
refdef_t r_refdef;
refdef_t r_refdef;
mleaf_t *r_viewleaf, *r_oldviewleaf;
mleaf_t *r_viewleaf, *r_oldviewleaf;
int d_lightstylevalue[256]; // 8.8 fraction of base light value
int d_lightstylevalue[256]; // 8.8 fraction of base light value
vec3_t shadecolor; // Ender (Extend) Colormod
float modelalpha; // Ender (EXtend) Alpha
vec3_t shadecolor; // Ender (Extend) Colormod
float modelalpha; // Ender (EXtend) Alpha
void R_MarkLeaves (void);
void R_MarkLeaves (void);
cvar_t *r_norefresh;
cvar_t *r_drawentities;
cvar_t *r_drawviewmodel;
cvar_t *r_speeds;
cvar_t *r_shadows;
cvar_t *r_wateralpha;
cvar_t *r_waterripple;
cvar_t *r_dynamic;
cvar_t *r_novis;
cvar_t *r_netgraph;
cvar_t *r_norefresh;
cvar_t *r_drawentities;
cvar_t *r_drawviewmodel;
cvar_t *r_speeds;
cvar_t *r_shadows;
cvar_t *r_wateralpha;
cvar_t *r_waterripple;
cvar_t *r_dynamic;
cvar_t *r_novis;
cvar_t *r_netgraph;
cvar_t *gl_clear;
cvar_t *gl_cull;
cvar_t *gl_texsort;
cvar_t *gl_smooth;
cvar_t *gl_smoothdlights;
cvar_t *gl_affinemodels;
cvar_t *gl_flashblend;
cvar_t *gl_playermip;
cvar_t *gl_nocolors;
cvar_t *gl_keeptjunctions;
cvar_t *gl_particles;
cvar_t *gl_clear;
cvar_t *gl_cull;
cvar_t *gl_texsort;
cvar_t *gl_smooth;
cvar_t *gl_smoothdlights;
cvar_t *gl_affinemodels;
cvar_t *gl_flashblend;
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;
cvar_t *gl_sky_clip;
cvar_t *r_skyname;
cvar_t *gl_skymultipass;
cvar_t *gl_sky_clip;
cvar_t *gl_fb_models;
cvar_t *gl_fb_bmodels;
cvar_t *gl_fb_models;
cvar_t *gl_fb_bmodels;
cvar_t *brighten;
cvar_t *brighten;
extern cvar_t *scr_fov;
@ -345,23 +345,23 @@ float r_avertexnormals[NUMVERTEXNORMALS][3] = {
#include "anorms.h"
};
vec3_t shadevector;
float shadelight;
vec3_t shadevector;
float shadelight;
// precalculated dot products for quantized angles
#define SHADEDOT_QUANT 16
float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
float r_avertexnormal_dots[SHADEDOT_QUANT][256] =
#include "anorm_dots.h"
;
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
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);
}
/*
=================
@ -522,15 +692,16 @@ R_DrawAliasModel
static void
R_DrawAliasModel (entity_t *e)
{
int i;
int lnum;
vec3_t dist;
float add;
model_t *clmodel;
vec3_t mins, maxs;
aliashdr_t *paliashdr;
float an;
int anim;
int i;
int lnum;
vec3_t dist;
float add;
model_t *clmodel;
vec3_t mins, maxs;
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;
}
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)];
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,15 +821,21 @@ R_DrawAliasModel (entity_t *e)
if (gl_affinemodels->int_val)
glHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
R_SetupAliasFrame (currententity->frame, paliashdr, false);
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]);
R_SetupAliasFrame (currententity->frame, paliashdr, true);
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)
@ -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);
GL_DrawAliasShadow (paliashdr, lastposenum);
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);

View file

@ -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,

View file

@ -272,7 +272,7 @@ ED_FindFunction (char *name)
return NULL;
}
eval_t *
eval_t *
GetEdictFieldValue (edict_t *ed, char *field)
{
ddef_t *def = NULL;
@ -308,7 +308,7 @@ PR_ValueString
Returns a string describing *data in a type specific manner
=============
*/
char *
char *
PR_ValueString (etype_t type, eval_t *val)
{
static char line[256];
@ -362,7 +362,7 @@ Returns a string describing *data in a type specific manner
Easier to parse than PR_ValueString
=============
*/
char *
char *
PR_UglyValueString (etype_t type, eval_t *val)
{
static char line[256];
@ -413,7 +413,7 @@ Returns a string with a description and the contents of a global,
padded to 20 field width
============
*/
char *
char *
PR_GlobalString (int ofs)
{
char *s;
@ -440,7 +440,7 @@ PR_GlobalString (int ofs)
return line;
}
char *
char *
PR_GlobalStringNoContents (int ofs)
{
int i;
@ -724,7 +724,7 @@ ED_ParseGlobals (char *data)
ED_NewString
=============
*/
char *
char *
ED_NewString (char *string)
{
char *new, *new_p;
@ -828,7 +828,7 @@ ed should be a properly initialized empty edict.
Used for initial level load and for savegames.
====================
*/
char *
char *
ED_ParseEdict (char *data, edict_t *ent)
{
ddef_t *key;
@ -1249,7 +1249,7 @@ PR_Init_Cvars (void)
edict_t *
edict_t *
EDICT_NUM (int n)
{
if (n < 0 || n >= MAX_EDICTS)