clean out the non-renderer fields from entity_t. not yet a noticable gain

but more work needs to be done on the linking code in the client. However,
there /does/ seem to be a slight gain with possibly less variance.
This commit is contained in:
Bill Currie 2001-11-27 21:42:49 +00:00
parent 4689350283
commit f7c90759af
6 changed files with 149 additions and 162 deletions

View file

@ -69,33 +69,21 @@ extern lightstyle_t r_lightstyle[MAX_LIGHTSTYLES];
typedef struct entity_s
{
qboolean forcelink; // model changed
struct entity_state_s *baseline; // to fill in defaults in updates
double msgtime; // time of last update
vec3_t origin;
vec3_t old_origin;
vec3_t angles;
vec3_t msg_origins[2]; // last two updates (0 is newest)
vec3_t msg_angles[2]; // last two updates (0 is newest)
struct model_s *model; // NULL = no model
struct model_s *_model; // for nq skin support
int frame;
byte *colormap;
int skinnum; // for Alias models
int _skinnum; // for nq skin support
struct skin_s *skin;
struct player_info_s *scoreboard; // identify player
float syncbase; // for client-side animations
struct efrag_s *efrag; // linked list of efrags
int visframe; // last frame this entity was
// found in an active leaf
int effects; // light, particals, etc
float colormod[3]; // color tint for model
vec3_t colormod; // color tint for model
float alpha; // opacity (alpha) of the model
float scale; // size scaler of the model
float glow_size; // how big the glow is (can be negative)

View file

@ -31,18 +31,17 @@
#include <stdio.h>
#include "QF/info.h"
#include "QF/input.h"
#include "QF/mathlib.h"
#include "QF/model.h"
#include "QF/sound.h"
#include "QF/vfs.h"
#include "QF/render.h"
#include "game.h"
#include "net.h"
#include "protocol.h"
#include "r_local.h"
#include "QF/render.h"
#include "game.h"
typedef struct usercmd_s
@ -223,6 +222,19 @@ typedef struct
} client_state_t;
typedef struct cl_entity_state_s {
entity_t *ent;
entity_state_t baseline;
int forcelink;
vec3_t msg_origins[2];
vec3_t msg_angles[2];
double msgtime;
int effects;
int colors;
struct model_s *model;
int skinnum;
} cl_entity_state_t;
/*
cvars
*/
@ -274,6 +286,7 @@ extern client_state_t cl;
// FIXME, allocate dynamically
extern entity_t cl_entities[MAX_EDICTS];
extern cl_entity_state_t cl_baselines[MAX_EDICTS];
extern entity_t cl_static_entities[MAX_STATIC_ENTITIES];
extern int fps_count;

View file

@ -86,9 +86,8 @@ client_state_t cl;
// FIXME: put these on hunk?
entity_t cl_entities[MAX_EDICTS];
entity_state_t cl_baselines[MAX_EDICTS];
cl_entity_state_t cl_baselines[MAX_EDICTS];
entity_t cl_static_entities[MAX_STATIC_ENTITIES];
entity_state_t cl_static_entity_baselines[MAX_STATIC_ENTITIES];
void
@ -179,12 +178,13 @@ CL_ClearState (void)
R_ClearParticles (); // FIXME: for R_ClearFires
for (i = 0; i < MAX_EDICTS; i++) {
cl_entities[i].baseline = &cl_baselines[i];
cl_entities[i].baseline->alpha = 255;
cl_entities[i].baseline->scale = 16;
cl_entities[i].baseline->glow_color = 254;
cl_entities[i].baseline->glow_size = 0;
cl_entities[i].baseline->colormod = 255;
cl_baselines[i].ent = &cl_entities[i];
cl_entities[i].alpha = 255;
cl_entities[i].scale = 16;
cl_entities[i].glow_color = 254;
cl_entities[i].glow_size = 0;
cl_entities[i].colormod[0] = cl_entities[i].colormod[1]
= cl_entities[i].colormod[2] = 1;
}
}
@ -496,6 +496,7 @@ CL_RelinkEntities (void)
{
entity_t **_ent;
entity_t *ent;
cl_entity_state_t *state;
dlight_t *dl;
float bobjrotate, frac, f, d;
int i, j;
@ -526,44 +527,45 @@ CL_RelinkEntities (void)
bobjrotate = anglemod (100 * cl.time);
// start on the entity after the world
for (i = 1, ent = cl_entities + 1; i < cl.num_entities; i++, ent++) {
for (i = 1, state = cl_baselines + 1; i < cl.num_entities; i++, state++) {
ent = state->ent;
if (!ent->model) { // empty slot
if (ent->forcelink)
if (state->forcelink)
R_RemoveEfrags (ent); // just became empty
continue;
}
// if the object wasn't included in the last packet, remove it
if (ent->msgtime != cl.mtime[0]) {
if (state->msgtime != cl.mtime[0]) {
ent->model = NULL;
continue;
}
VectorCopy (ent->origin, ent->old_origin);
if (ent->forcelink) { // the entity was not updated in the
if (state->forcelink) { // the entity was not updated in the
// last message so move to the final spot
VectorCopy (ent->msg_origins[0], ent->origin);
VectorCopy (ent->msg_angles[0], ent->angles);
VectorCopy (state->msg_origins[0], ent->origin);
VectorCopy (state->msg_angles[0], ent->angles);
ent->pose1 = ent->pose2 = -1;
} else { // if the delta is large, assume a
// teleport and don't lerp
f = frac;
for (j = 0; j < 3; j++) {
delta[j] = ent->msg_origins[0][j] - ent->msg_origins[1][j];
delta[j] = state->msg_origins[0][j] - state->msg_origins[1][j];
if (delta[j] > 100 || delta[j] < -100)
f = 1; // assume a teleportation, not a motion
}
// interpolate the origin and angles
for (j = 0; j < 3; j++) {
ent->origin[j] = ent->msg_origins[1][j] + f * delta[j];
ent->origin[j] = state->msg_origins[1][j] + f * delta[j];
d = ent->msg_angles[0][j] - ent->msg_angles[1][j];
d = state->msg_angles[0][j] - state->msg_angles[1][j];
if (d > 180)
d -= 360;
else if (d < -180)
d += 360;
ent->angles[j] = ent->msg_angles[1][j] + f * d;
ent->angles[j] = state->msg_angles[1][j] + f * d;
}
}
@ -578,9 +580,9 @@ CL_RelinkEntities (void)
if (ent->model->flags & EF_ROTATE)
ent->angles[1] = bobjrotate;
if (ent->effects & EF_BRIGHTFIELD)
if (state->baseline.effects & EF_BRIGHTFIELD)
R_EntityParticles (ent);
if (ent->effects & EF_MUZZLEFLASH) {
if (state->baseline.effects & EF_MUZZLEFLASH) {
vec3_t fv, rv, uv;
dl = R_AllocDlight (i);
@ -596,9 +598,9 @@ CL_RelinkEntities (void)
dl->color[1] = 0.1;
dl->color[2] = 0.05;
}
CL_NewDlight (i, ent->origin, ent->effects);
if (VectorDistance_fast(ent->msg_origins[1], ent->origin) > (256*256))
VectorCopy (ent ->origin, ent->msg_origins[1]);
CL_NewDlight (i, ent->origin, state->baseline.effects);
if (VectorDistance_fast(state->msg_origins[1], ent->origin) > (256*256))
VectorCopy (ent ->origin, state->msg_origins[1]);
if (ent->model->flags & EF_ROCKET) {
dl = R_AllocDlight (i);
VectorCopy (ent->origin, dl->origin);
@ -619,7 +621,7 @@ CL_RelinkEntities (void)
else if (ent->model->flags & EF_TRACER3)
R_VoorTrail (ent);
ent->forcelink = false;
state->forcelink = false;
if (i == cl.viewentity && !chase_active->int_val) {
continue;
@ -725,8 +727,6 @@ Force_CenterView_f (void)
void
CL_Init (void)
{
int i;
SZ_Alloc (&cls.message, 1024);
CL_InitInput ();
@ -743,8 +743,4 @@ CL_Init (void)
Cmd_AddCommand ("demolist", Con_Demolist_DEM_f, "List available demos");
Cmd_AddCommand ("force_centerview", Force_CenterView_f, "force the view "
"to be level");
for (i = 0; i < MAX_STATIC_ENTITIES; i++) {
cl_static_entities[i].baseline = &cl_static_entity_baselines[i];
}
}

View file

@ -105,19 +105,21 @@ char *svc_strings[] = {
This error checks and tracks the total number of entities
*/
entity_t *
cl_entity_state_t *
CL_EntityNum (int num)
{
if (num >= cl.num_entities) {
if (num >= MAX_EDICTS)
Host_Error ("CL_EntityNum: %i is an invalid number", num);
while (cl.num_entities <= num) {
cl_baselines[cl.num_entities].ent =
&cl_entities[cl.num_entities];
cl_entities[cl.num_entities].colormap = vid.colormap8;
cl.num_entities++;
}
}
return &cl_entities[num];
return &cl_baselines[num];
}
void
@ -328,6 +330,7 @@ void
CL_ParseUpdate (int bits)
{
entity_t *ent;
cl_entity_state_t *state;
int modnum, num, skin, i;
model_t *model;
qboolean forcelink;
@ -349,13 +352,14 @@ CL_ParseUpdate (int bits)
else
num = MSG_ReadByte (net_message);
ent = CL_EntityNum (num);
state = CL_EntityNum (num);
ent = state->ent;
for (i = 0; i < 16; i++)
if (bits & (1 << i))
bitcounts[i]++;
if (ent->msgtime != cl.mtime[1])
if (state->msgtime != cl.mtime[1])
forcelink = true; // no previous frame to lerp from
else
forcelink = false;
@ -369,14 +373,14 @@ CL_ParseUpdate (int bits)
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
}
ent->msgtime = cl.mtime[0];
state->msgtime = cl.mtime[0];
if (bits & U_MODEL) {
modnum = MSG_ReadByte (net_message);
if (modnum >= MAX_MODELS)
Host_Error ("CL_ParseModel: bad modnum");
} else
modnum = ent->baseline->modelindex;
modnum = state->baseline.modelindex;
model = cl.model_precache[modnum];
if (model != ent->model) {
@ -397,12 +401,12 @@ CL_ParseUpdate (int bits)
if (bits & U_FRAME)
ent->frame = MSG_ReadByte (net_message);
else
ent->frame = ent->baseline->frame;
ent->frame = state->baseline.frame;
if (bits & U_COLORMAP)
i = MSG_ReadByte (net_message);
else
i = ent->baseline->colormap;
i = state->baseline.colormap;
if (!i)
ent->colormap = vid.colormap8;
else {
@ -414,7 +418,7 @@ CL_ParseUpdate (int bits)
if (bits & U_SKIN)
skin = MSG_ReadByte (net_message);
else
skin = ent->baseline->skin;
skin = state->baseline.skin;
if (skin != ent->skinnum) {
ent->skinnum = skin;
//XXX if (num > 0 && num <= cl.maxclients)
@ -422,73 +426,73 @@ CL_ParseUpdate (int bits)
}
if (bits & U_EFFECTS)
ent->effects = MSG_ReadByte (net_message);
state->effects = MSG_ReadByte (net_message);
else
ent->effects = ent->baseline->effects;
state->effects = state->baseline.effects;
// shift the known values for interpolation
VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
VectorCopy (state->msg_origins[0], state->msg_origins[1]);
VectorCopy (state->msg_angles[0], state->msg_angles[1]);
if (bits & U_ORIGIN1)
ent->msg_origins[0][0] = MSG_ReadCoord (net_message);
state->msg_origins[0][0] = MSG_ReadCoord (net_message);
else
ent->msg_origins[0][0] = ent->baseline->origin[0];
state->msg_origins[0][0] = state->baseline.origin[0];
if (bits & U_ANGLE1)
ent->msg_angles[0][0] = MSG_ReadAngle (net_message);
state->msg_angles[0][0] = MSG_ReadAngle (net_message);
else
ent->msg_angles[0][0] = ent->baseline->angles[0];
state->msg_angles[0][0] = state->baseline.angles[0];
if (bits & U_ORIGIN2)
ent->msg_origins[0][1] = MSG_ReadCoord (net_message);
state->msg_origins[0][1] = MSG_ReadCoord (net_message);
else
ent->msg_origins[0][1] = ent->baseline->origin[1];
state->msg_origins[0][1] = state->baseline.origin[1];
if (bits & U_ANGLE2)
ent->msg_angles[0][1] = MSG_ReadAngle (net_message);
state->msg_angles[0][1] = MSG_ReadAngle (net_message);
else
ent->msg_angles[0][1] = ent->baseline->angles[1];
state->msg_angles[0][1] = state->baseline.angles[1];
if (bits & U_ORIGIN3)
ent->msg_origins[0][2] = MSG_ReadCoord (net_message);
state->msg_origins[0][2] = MSG_ReadCoord (net_message);
else
ent->msg_origins[0][2] = ent->baseline->origin[2];
state->msg_origins[0][2] = state->baseline.origin[2];
if (bits & U_ANGLE3)
ent->msg_angles[0][2] = MSG_ReadAngle (net_message);
state->msg_angles[0][2] = MSG_ReadAngle (net_message);
else
ent->msg_angles[0][2] = ent->baseline->angles[2];
state->msg_angles[0][2] = state->baseline.angles[2];
if (bits & U_NOLERP)
ent->forcelink = true;
state->forcelink = true;
if (forcelink) { // didn't have an update last message
VectorCopy (ent->msg_origins[0], ent->msg_origins[1]);
VectorCopy (ent->msg_origins[0], ent->origin);
VectorCopy (ent->msg_angles[0], ent->msg_angles[1]);
VectorCopy (ent->msg_angles[0], ent->angles);
ent->forcelink = true;
VectorCopy (state->msg_origins[0], state->msg_origins[1]);
VectorCopy (state->msg_origins[0], ent->origin);
VectorCopy (state->msg_angles[0], state->msg_angles[1]);
VectorCopy (state->msg_angles[0], ent->angles);
state->forcelink = true;
}
}
void
CL_ParseBaseline (entity_t *ent)
CL_ParseBaseline (cl_entity_state_t *state)
{
int i;
ent->baseline->modelindex = MSG_ReadByte (net_message);
ent->baseline->frame = MSG_ReadByte (net_message);
ent->baseline->colormap = MSG_ReadByte (net_message);
ent->baseline->skin = MSG_ReadByte (net_message);
state->baseline.modelindex = MSG_ReadByte (net_message);
state->baseline.frame = MSG_ReadByte (net_message);
state->baseline.colormap = MSG_ReadByte (net_message);
state->baseline.skin = MSG_ReadByte (net_message);
for (i = 0; i < 3; i++) {
ent->baseline->origin[i] = MSG_ReadCoord (net_message);
ent->baseline->angles[i] = MSG_ReadAngle (net_message);
state->baseline.origin[i] = MSG_ReadCoord (net_message);
state->baseline.angles[i] = MSG_ReadAngle (net_message);
}
// LordHavoc: set up the baseline to account for new effects (alpha,
// colormod, etc)
ent->baseline->alpha = 255;
ent->baseline->scale = 16;
ent->baseline->glow_color = 254;
ent->baseline->glow_size = 0;
ent->baseline->colormod = 255;
state->baseline.alpha = 255;
state->baseline.scale = 16;
state->baseline.glow_color = 254;
state->baseline.glow_size = 0;
state->baseline.colormod = 255;
}
/*
@ -598,6 +602,7 @@ CL_ParseClientdata (int bits)
void
CL_ParseStatic (void)
{
cl_entity_state_t state;
entity_t *ent;
int i;
@ -606,24 +611,24 @@ CL_ParseStatic (void)
Host_Error ("Too many static entities");
ent = &cl_static_entities[i];
cl.num_statics++;
CL_ParseBaseline (ent);
CL_ParseBaseline (&state);
// copy it to the current state
ent->model = cl.model_precache[ent->baseline->modelindex];
ent->frame = ent->baseline->frame;
ent->model = cl.model_precache[state.baseline.modelindex];
ent->frame = state.baseline.frame;
ent->colormap = vid.colormap8;
ent->skinnum = ent->baseline->skin;
ent->effects = ent->baseline->effects;
ent->skinnum = state.baseline.skin;
//FIXME ent->effects = state.baseline.effects;
ent->alpha = ent->baseline->alpha / 255.0;
ent->scale = ent->baseline->scale / 16.0;
ent->glow_color = ent->baseline->glow_color;
ent->glow_size = ent->baseline->glow_size;
ent->alpha = state.baseline.alpha / 255.0;
ent->scale = state.baseline.scale / 16.0;
ent->glow_color = state.baseline.glow_color;
ent->glow_size = state.baseline.glow_size;
//FIXME need to get this from baseline
ent->colormod[0] = ent->colormod[1] = ent->colormod[2] = 1;
VectorCopy (ent->baseline->origin, ent->origin);
VectorCopy (ent->baseline->angles, ent->angles);
VectorCopy (state.baseline.origin, ent->origin);
VectorCopy (state.baseline.angles, ent->angles);
R_AddEfrags (ent);
}

View file

@ -127,7 +127,7 @@ CL_NewTranslation (int slot, skin_t *skin)
int top, bottom;
byte *dest;
model_t *model;
entity_t *entity;
cl_entity_state_t *state;
int skinnum;
if (slot > cl.maxclients)
@ -137,9 +137,9 @@ CL_NewTranslation (int slot, skin_t *skin)
dest = player->translations;
top = (player->colors & 0xf0) >> 4;
bottom = player->colors & 15;
entity = &cl_entities[1 + slot];
model = entity->model;
skinnum = entity->skinnum;
state = &cl_baselines[1 + slot];
model = state->ent->model;
skinnum = state->ent->skinnum;
memset (skin, 0, sizeof (*skin)); //XXX external skins not yet supported
@ -150,13 +150,13 @@ CL_NewTranslation (int slot, skin_t *skin)
skin->data.texels = 0; //FIXME
if (player->colors == player->_colors
&& entity->model == entity->_model
&& entity->skinnum == entity->_skinnum)
&& model == state->model
&& skinnum == state->skinnum)
return;
player->_colors = player->colors;
entity->_model = entity->model;
entity->_skinnum = entity->skinnum;
state->model = model;
state->skinnum = skinnum;
Skin_Set_Translate (top, bottom, dest);
Skin_Do_Translation_Model (model, skinnum, slot, skin);

View file

@ -64,9 +64,14 @@ static struct predicted_player {
vec3_t origin; // predicted origin
} predicted_players[MAX_CLIENTS];
entity_t cl_packet_ents[512]; // FIXME: magic number
entity_t cl_flag_ents[MAX_CLIENTS];
#define MAX_PROJECTILES 32
int cl_num_projectiles;
entity_t cl_player_ents[MAX_CLIENTS];
entity_t cl_flag_ents[MAX_CLIENTS];
entity_t cl_projectiles[MAX_PROJECTILES];
entity_t cl_packet_ents[512]; // FIXME: magic number
void
@ -392,6 +397,7 @@ CL_LinkPacketEntities (void)
entity_state_t *s1;
model_t *model;
packet_entities_t *pack;
player_info_t *info;
pack = &cl.frames[cls.netchan.incoming_sequence &
UPDATE_MASK].packet_entities;
@ -432,15 +438,15 @@ CL_LinkPacketEntities (void)
&& cl.players[s1->colormap - 1].name[0]
&& !strcmp ((*ent)->model->name, "progs/player.mdl")) {
(*ent)->colormap = cl.players[s1->colormap - 1].translations;
(*ent)->scoreboard = &cl.players[s1->colormap - 1];
info = &cl.players[s1->colormap - 1];
} else {
(*ent)->colormap = vid.colormap8;
(*ent)->scoreboard = NULL;
info = NULL;
}
if ((*ent)->scoreboard && !(*ent)->scoreboard->skin)
Skin_Find ((*ent)->scoreboard);
if ((*ent)->scoreboard && (*ent)->scoreboard->skin) {
if (info && !info->skin)
Skin_Find (info);
if (info && info->skin) {
(*ent)->skin = Skin_NewTempSkin ();
if ((*ent)->skin) {
i = s1->colormap - 1;
@ -531,15 +537,6 @@ CL_LinkPacketEntities (void)
/* PROJECTILE PARSING / LINKING */
typedef struct {
int modelindex;
entity_t ent;
} projectile_t;
#define MAX_PROJECTILES 32
projectile_t cl_projectiles[MAX_PROJECTILES];
int cl_num_projectiles;
void
CL_ClearProjectiles (void)
{
@ -556,7 +553,7 @@ CL_ParseProjectiles (void)
{
byte bits[6];
int i, c, j;
projectile_t *pr;
entity_t *pr;
c = MSG_ReadByte (net_message);
for (i = 0; i < c; i++) {
@ -569,12 +566,13 @@ CL_ParseProjectiles (void)
pr = &cl_projectiles[cl_num_projectiles];
cl_num_projectiles++;
pr->modelindex = cl_spikeindex;
pr->ent.origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
pr->ent.origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
pr->ent.origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
pr->ent.angles[0] = 360 * (bits[4] >> 4) / 16;
pr->ent.angles[1] = 360 * bits[5] / 256;
pr->model = cl.model_precache[cl_spikeindex];
pr->colormap = vid.colormap8;
pr->origin[0] = ((bits[0] + ((bits[1] & 15) << 8)) << 1) - 4096;
pr->origin[1] = (((bits[1] >> 4) + (bits[2] << 4)) << 1) - 4096;
pr->origin[2] = ((bits[3] + ((bits[4] & 15) << 8)) << 1) - 4096;
pr->angles[0] = 360 * (bits[4] >> 4) / 16;
pr->angles[1] = 360 * bits[5] / 256;
}
}
@ -583,30 +581,16 @@ CL_LinkProjectiles (void)
{
int i;
entity_t **ent;
projectile_t *pr;
entity_t *pr;
for (i = 0, pr = cl_projectiles; i < cl_num_projectiles; i++, pr++) {
if (pr->modelindex < 1)
if (!pr->model)
continue;
// grab an entity to fill in
ent = R_NewEntity ();
if (!ent)
break; // object list is full
*ent = &pr->ent;
(*ent)->model = cl.model_precache[pr->modelindex];
(*ent)->skinnum = 0;
(*ent)->frame = 0;
(*ent)->colormap = vid.colormap8;
(*ent)->scoreboard = NULL;
(*ent)->skin = NULL;
// LordHavoc: Endy had neglected to do this as part of the QSG
// VERSION 2 stuff
(*ent)->glow_size = 0;
(*ent)->glow_color = 254;
(*ent)->alpha = 1;
(*ent)->scale = 1;
(*ent)->colormod[0] = (*ent)->colormod[1] = (*ent)->colormod[2] = 1;
*ent = pr;
}
}
@ -651,9 +635,10 @@ CL_ParsePlayerinfo (void)
state->velocity[i] = 0;
}
if (flags & PF_MODEL)
state->modelindex = MSG_ReadByte (net_message);
i = MSG_ReadByte (net_message);
else
state->modelindex = cl_playerindex;
i = cl_playerindex;
state->modelindex = i;
if (flags & PF_SKINNUM)
state->skinnum = MSG_ReadByte (net_message);
@ -790,7 +775,7 @@ CL_LinkPlayers (void)
// the player object never gets added
if (j == cl.playernum) {
if (!Cam_DrawPlayer (-1))
if (!Cam_DrawPlayer (-1)) // XXX
continue;
} else {
if (!Cam_DrawPlayer (j))
@ -816,17 +801,17 @@ CL_LinkPlayers (void)
ent->model = cl.model_precache[state->modelindex];
ent->skinnum = state->skinnum;
ent->colormap = info->translations;
if (state->modelindex == cl_playerindex)
ent->scoreboard = info; // use custom skin
else
ent->scoreboard = NULL;
if (ent->scoreboard && !ent->scoreboard->skin)
Skin_Find (ent->scoreboard);
if (ent->scoreboard && ent->scoreboard->skin) {
ent->skin = Skin_NewTempSkin ();
if (ent->skin) {
CL_NewTranslation (j, ent->skin);
if (state->modelindex == cl_playerindex) { //XXX
// use custom skin
if (!info->skin)
Skin_Find (info);
if (info && info->skin) {
ent->skin = Skin_NewTempSkin ();
if (ent->skin) {
CL_NewTranslation (j, ent->skin);
}
} else {
ent->skin = NULL;
}
} else {
ent->skin = NULL;