[renderer] Clean up entity_t to a certain extent

This is the first step towards component-based entities.

There's still some transform-related stuff in the struct that needs to
be moved, but it's all entirely client related (rather than renderer)
and will probably go into a "client" component. Also, the current
components are directly included structs rather than references as I
didn't want to deal with the object management at this stage.

As part of the process (because transforms use simd) this also starts
the process of moving QF to using simd for vectors and matrices. There's
now a mess of simd and sisd code mixed together, but it works
surprisingly well together.
This commit is contained in:
Bill Currie 2021-03-09 23:52:40 +09:00
parent 09e1a63470
commit fbc1bd9f6e
59 changed files with 881 additions and 682 deletions

View file

@ -92,16 +92,18 @@ void Transform_GetLocalInverse (const transform_t *transform, mat4f_t mat);
void Transform_GetWorldMatrix (const transform_t *transform, mat4f_t mat);
void Transform_GetWorldInverse (const transform_t *transform, mat4f_t mat);
vec4f_t Transform_GetLocalPosition (const transform_t *transform) __attribute__((pure));
void Transform_SetLocalPosition (transform_t *transform_t, vec4f_t position);
void Transform_SetLocalPosition (transform_t *transform, vec4f_t position);
vec4f_t Transform_GetLocalRotation (const transform_t *transform) __attribute__((pure));
void Transform_SetLocalRotation (transform_t *transform_t, vec4f_t rotation);
void Transform_SetLocalRotation (transform_t *transform, vec4f_t rotation);
vec4f_t Transform_GetLocalScale (const transform_t *transform) __attribute__((pure));
void Transform_SetLocalScale (transform_t *transform_t, vec4f_t scale);
void Transform_SetLocalScale (transform_t *transform, vec4f_t scale);
vec4f_t Transform_GetWorldPosition (const transform_t *transform) __attribute__((pure));
void Transform_SetWorldPosition (transform_t *transform_t, vec4f_t position);
void Transform_SetWorldPosition (transform_t *transform, vec4f_t position);
vec4f_t Transform_GetWorldRotation (const transform_t *transform) __attribute__((pure));
void Transform_SetWorldRotation (transform_t *transform_t, vec4f_t rotation);
void Transform_SetWorldRotation (transform_t *transform, vec4f_t rotation);
vec4f_t Transform_GetWorldScale (const transform_t *transform) __attribute__((pure));
void Transform_SetLocalTransform (transform_t *transform, vec4f_t scale,
vec4f_t rotation, vec4f_t position);
// NOTE: these use X: right, Y: forward, Z:up
// aslo, not guaranteed to be normalized or even orthogonal
vec4f_t Transform_Forward (const transform_t *transform) __attribute__((pure));

View file

@ -90,47 +90,56 @@ typedef struct
//===============
typedef struct animation_s {
int frame;
float syncbase; // randomize time base for local animations
float frame_start_time;
float frame_interval;
int pose1;
int pose2;
float blend;
int nolerp; // don't lerp this frame (pose data invalid)
} animation_t;
typedef struct visibility_s {
struct entity_s *entity; // owning entity
struct efrag_s *efrag; // linked list of efrags
struct mnode_s *topnode; // bmodels, first world node that
// splits bmodel, or NULL if not split
// applies to other models, too
int visframe; // last frame this entity was
// found in an active leaf
int trivial_accept; // view clipping (frustum and depth)
} visibility_t;
typedef struct renderer_s {
struct model_s *model; // NULL = no model
struct skin_s *skin;
float colormod[4]; // color tint and alpha for model
int skinnum; // for Alias models
int fullbright;
float min_light;
mat4_t full_transform;
} renderer_t;
typedef struct entity_s {
struct entity_s *next;
struct entity_s *unext; //FIXME this shouldn't be here. for qw demos
struct transform_s *transform;
animation_t animation;
visibility_t visibility;
renderer_t renderer;
int active;
//XXX FIXME XXX should not be here
float scale;
vec3_t origin;
vec3_t old_origin;
vec3_t angles;
vec_t transform[4 * 4];
vec_t full_transform[4 * 4];
struct model_s *model; // NULL = no model
int frame;
int skinnum; // for Alias models
struct skin_s *skin;
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
float colormod[4]; // color tint and alpha for model
float scale; // size scaler of the model
int fullbright;
float min_light;
// 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;
struct model_s *pose_model; // no lerp if not the same as model
} entity_t;
// !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct
{
typedef struct {
vrect_t vrect; // subwindow in video for refresh
// FIXME: not need vrect next field here?
vrect_t aliasvrect; // scaled Alias version

View file

@ -33,6 +33,8 @@
#include "QF/model.h"
#include "QF/render.h"
#include "QF/vid.h"
#include "QF/simd/mat4f.h"
#include "QF/simd/vec4f.h"
#include "r_shared.h"
#define ALIAS_BASE_SIZE_RATIO (1.0 / 11.0)
@ -136,8 +138,8 @@ extern qboolean r_cache_thrash; // set if thrashing the surface cache
extern qboolean insubmodel;
extern vec3_t r_worldmodelorg;
extern mat4_t glsl_projection;
extern mat4_t glsl_view;
extern mat4f_t glsl_projection;
extern mat4f_t glsl_view;
void R_SetFrustum (void);

View file

@ -295,18 +295,35 @@ Transform_GetWorldScale (const transform_t *transform)
return h->worldScale.a[transform->index];
}
void
Transform_SetLocalTransform (transform_t *transform, vec4f_t scale,
vec4f_t rotation, vec4f_t position)
{
hierarchy_t *h = transform->hierarchy;
mat4f_t mat;
mat4fquat (mat, rotation);
position[3] = 1;
h->localMatrix.a[transform->index][0] = mat[0] * scale[0];
h->localMatrix.a[transform->index][1] = mat[1] * scale[1];
h->localMatrix.a[transform->index][2] = mat[2] * scale[2];
h->localMatrix.a[transform->index][3] = position;
h->modified.a[transform->index] = 1;
Hierarchy_UpdateMatrices (h);
}
vec4f_t
Transform_Forward (const transform_t *transform)
{
hierarchy_t *h = transform->hierarchy;
return h->worldMatrix.a[transform->index][1];
return h->worldMatrix.a[transform->index][0];
}
vec4f_t
Transform_Right (const transform_t *transform)
{
hierarchy_t *h = transform->hierarchy;
return h->worldMatrix.a[transform->index][0];
return -h->worldMatrix.a[transform->index][1];
}
vec4f_t

View file

@ -205,7 +205,7 @@ gl_R_ReadPointFile_f (void)
vec3_t org;
QFile *f;
mapname = strdup (r_worldentity.model->path);
mapname = strdup (r_worldentity.renderer.model->path);
if (!mapname)
Sys_Error ("Can't duplicate mapname!");
QFS_StripExtension (mapname, mapname);

View file

@ -582,7 +582,7 @@ gl_overbright_f (cvar_t *var)
return;
for (ent = r_ent_queue; ent; ent = ent->next) {
m = ent->model;
m = ent->renderer.model;
if (m->type != mod_brush)
continue;
@ -605,7 +605,7 @@ gl_overbright_f (cvar_t *var)
}
}
brush = &r_worldentity.model->brush;
brush = &r_worldentity.renderer.model->brush;
for (i = 0, fa = brush->surfaces; i < brush->numsurfaces; i++, fa++) {
if (fa->flags & (SURF_DRAWTURB | SURF_DRAWSKY))

View file

@ -43,6 +43,7 @@
#include <stdlib.h>
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/locs.h"
#include "QF/mathlib.h"
#include "QF/qargs.h"
@ -299,14 +300,14 @@ GL_GetAliasFrameVerts16 (aliashdr_t *paliashdr, entity_t *e)
if (blend == 0.0) {
verts = verts + e->pose1 * count;
verts = verts + e->animation.pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
verts = verts + e->animation.pose2 * count;
} else {
trivertx16_t *verts1, *verts2;
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
verts1 = verts + e->animation.pose1 * count;
verts2 = verts + e->animation.pose2 * count;
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
@ -362,14 +363,14 @@ GL_GetAliasFrameVerts (aliashdr_t *paliashdr, entity_t *e)
blend = 1.0;
if (blend == 0.0) {
verts = verts + e->pose1 * count;
verts = verts + e->animation.pose1 * count;
} else if (blend == 1.0) {
verts = verts + e->pose2 * count;
verts = verts + e->animation.pose2 * count;
} else {
trivertx_t *verts1, *verts2;
verts1 = verts + e->pose1 * count;
verts2 = verts + e->pose2 * count;
verts1 = verts + e->animation.pose1 * count;
verts2 = verts + e->animation.pose2 * count;
for (i = 0, vo_v = vo->verts; i < count;
i++, vo_v++, verts1++, verts2++) {
@ -415,7 +416,7 @@ gl_R_DrawAliasModel (entity_t *e)
vec3_t dist, scale;
vert_order_t *vo;
model = e->model;
model = e->renderer.model;
radius = model->radius;
if (e->scale != 1.0)
@ -425,18 +426,18 @@ gl_R_DrawAliasModel (entity_t *e)
VectorSubtract (r_origin, e->origin, modelorg);
gl_modelalpha = e->colormod[3];
gl_modelalpha = e->renderer.colormod[3];
is_fullbright = (model->fullbright || e->fullbright);
minlight = max (model->min_light, e->min_light);
is_fullbright = (model->fullbright || e->renderer.fullbright);
minlight = max (model->min_light, e->renderer.min_light);
qfglColor4fv (e->colormod);
qfglColor4fv (e->renderer.colormod);
if (!is_fullbright) {
float lightadj;
// get lighting information
R_LightPoint (&r_worldentity.model->brush, e->origin);
R_LightPoint (&r_worldentity.renderer.model->brush, e->origin);
lightadj = (ambientcolor[0] + ambientcolor[1] + ambientcolor[2]) / 765.0;
@ -530,24 +531,25 @@ gl_R_DrawAliasModel (entity_t *e)
VectorScale (emission, 1.5 / d, emission);
}
emission[0] *= e->colormod[0];
emission[1] *= e->colormod[1];
emission[2] *= e->colormod[2];
emission[3] *= e->colormod[3];
emission[0] *= e->renderer.colormod[0];
emission[1] *= e->renderer.colormod[1];
emission[2] *= e->renderer.colormod[2];
emission[3] *= e->renderer.colormod[3];
qfglColor4fv (emission);
}
}
// locate the proper data
if (!(paliashdr = e->model->aliashdr))
paliashdr = Cache_Get (&e->model->cache);
if (!(paliashdr = e->renderer.model->aliashdr)) {
paliashdr = Cache_Get (&e->renderer.model->cache);
}
gl_c_alias_polys += paliashdr->mdl.numtris;
// if the model has a colorised/external skin, use it, otherwise use
// the skin embedded in the model data
if (e->skin && e->skin->texnum && !gl_nocolors->int_val) {
skin_t *skin = e->skin;
if (e->renderer.skin && e->renderer.skin->texnum && !gl_nocolors->int_val) {
skin_t *skin = e->renderer.skin;
texture = skin->texnum;
if (gl_fb_models->int_val) {
@ -556,10 +558,11 @@ gl_R_DrawAliasModel (entity_t *e)
} else {
maliasskindesc_t *skindesc;
skindesc = R_AliasGetSkindesc (e->skinnum, paliashdr);
skindesc = R_AliasGetSkindesc (e->renderer.skinnum, paliashdr);
texture = skindesc->texnum;
if (gl_fb_models->int_val && !is_fullbright)
if (gl_fb_models->int_val && !is_fullbright) {
fb_texture = skindesc->fb_texnum;
}
}
if (paliashdr->mdl.ident == HEADER_MDL16) {
@ -640,7 +643,7 @@ gl_R_DrawAliasModel (entity_t *e)
qfglDisable (GL_NORMALIZE);
}
qfglColor4fv (e->colormod);
qfglColor4fv (e->renderer.colormod);
qfglBindTexture (GL_TEXTURE_2D, fb_texture);
GL_DrawAliasFrameTri (vo);
@ -660,7 +663,7 @@ gl_R_DrawAliasModel (entity_t *e)
qfglDisable (GL_NORMALIZE);
}
qfglColor4fv (e->colormod);
qfglColor4fv (e->renderer.colormod);
qfglBindTexture (GL_TEXTURE_2D, fb_texture);
GL_DrawAliasFrame (vo);
@ -678,7 +681,7 @@ gl_R_DrawAliasModel (entity_t *e)
// torches, grenades, and lightning bolts do not have shadows
if (r_shadows->int_val && model->shadow_alpha) {
mat4_t shadow_mat;
mat4f_t shadow_mat;
qfglPushMatrix ();
gl_R_RotateForEntity (e);
@ -690,19 +693,19 @@ gl_R_DrawAliasModel (entity_t *e)
qfglDepthMask (GL_FALSE);
if (gl_modelalpha < 1.0) {
VectorBlend (e->colormod, dark, 0.5, color);
VectorBlend (e->renderer.colormod, dark, 0.5, color);
color[3] = gl_modelalpha * (model->shadow_alpha / 255.0);
qfglColor4fv (color);
} else {
color_black[3] = model->shadow_alpha;
qfglColor4ubv (color_black);
}
shadevector[0] = 1;
shadevector[1] = 0;
shadevector[2] = 1;
VectorNormalize (shadevector);
Mat4Transpose (e->transform, shadow_mat);
Mat4as3MultVec (shadow_mat, shadevector, shadevector);
//FIXME fully vectorize
vec4f_t vec = { 707106781, 0, 707106781, 0 };
Transform_GetWorldMatrix (e->transform, shadow_mat);
mat4ftranspose (shadow_mat, shadow_mat);
vec = mvmulf (shadow_mat, vec);
VectorCopy (vec, shadevector);
if (vo->tex_coord)
GL_DrawAliasShadowTri (paliashdr, vo);
else
@ -722,6 +725,7 @@ gl_R_DrawAliasModel (entity_t *e)
qfglDisable (GL_LIGHT0 + used_lights);
}
if (!e->model->aliashdr)
Cache_Release (&e->model->cache);
if (!e->renderer.model->aliashdr) {
Cache_Release (&e->renderer.model->cache);
}
}

View file

@ -90,7 +90,7 @@ gl_draw_iqm_frame (iqm_t *iqm, gliqm_t *gl, iqmframe_t *frame, iqmmesh *mesh)
void
gl_R_DrawIQMModel (entity_t *ent)
{
model_t *model = ent->model;
model_t *model = ent->renderer.model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
gliqm_t *gl = (gliqm_t *) iqm->extra_data;
float blend;
@ -98,8 +98,8 @@ gl_R_DrawIQMModel (entity_t *ent)
int i;
blend = R_IQMGetLerpedFrames (ent, iqm);
frame = R_IQMBlendPalette (iqm, ent->pose1, ent->pose2, blend, 0,
gl->blend_palette, gl->palette_size);
frame = R_IQMBlendPalette (iqm, ent->animation.pose1, ent->animation.pose2,
blend, 0, gl->blend_palette, gl->palette_size);
qfglPushMatrix ();
gl_R_RotateForEntity (ent);

View file

@ -41,6 +41,7 @@
#include "QF/GL/defines.h"
#include "QF/GL/funcs.h"
#include "QF/entity.h"
#include "QF/model.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -66,8 +67,8 @@ R_GetSpriteFrame (entity_t *currententity)
mspriteframe_t *pspriteframe;
mspritegroup_t *pspritegroup;
psprite = currententity->model->cache.data;
frame = currententity->frame;
psprite = currententity->renderer.model->cache.data;
frame = currententity->animation.frame;
if ((frame >= psprite->numframes) || (frame < 0)) {
Sys_MaskPrintf (SYS_DEV, "R_DrawSprite: no such frame %d\n", frame);
@ -82,7 +83,7 @@ R_GetSpriteFrame (entity_t *currententity)
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
@ -103,35 +104,32 @@ static void
R_DrawSpriteModel_f (entity_t *e)
{
float modelalpha, color[4];
float *up, *right;
vec4f_t up = {}, right = {};
vec4f_t origin, point1, point2;
msprite_t *psprite;
mspriteframe_t *frame;
vec3_t point, point1, point2, v_up;
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->model->cache.data;
psprite = e->renderer.model->cache.data;
if (psprite->type == SPR_ORIENTED) { // bullet marks on walls
up = e->transform + 2 * 4;
right = e->transform + 1 * 4;
up = Transform_Up (e->transform);
right = Transform_Right (e->transform);
} else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) {
v_up[0] = 0;
v_up[1] = 0;
v_up[2] = 1;
up = v_up;
right = vright;
up = (vec4f_t) { 0, 0, 1, 0 };
VectorCopy (vright, right);
} else { // normal sprite
up = vup;
right = vright;
VectorCopy (vup, up);
VectorCopy (vright, right);
}
if (e->scale != 1.0) {
VectorScale (up, e->scale, up);
VectorScale (right, e->scale, right);
up *= e->scale;
right *= e->scale;
}
VectorCopy (e->colormod, color);
modelalpha = color[3] = e->colormod[3];
VectorCopy (e->renderer.colormod, color);
modelalpha = color[3] = e->renderer.colormod[3];
if (modelalpha < 1.0)
qfglDepthMask (GL_FALSE);
@ -141,23 +139,24 @@ R_DrawSpriteModel_f (entity_t *e)
qfglColor4fv (color);
origin = Transform_GetWorldPosition (e->transform);
point1 = origin + frame->down * up + frame->left * right;
point2 = origin + frame->up * up + frame->left * right;
qfglTexCoord2f (0, 1);
VectorMultAdd (e->origin, frame->down, up, point1);
VectorMultAdd (point1, frame->left, right, point);
qfglVertex3fv (point);
qfglVertex3fv (&point1[0]);
qfglTexCoord2f (0, 0);
VectorMultAdd (e->origin, frame->up, up, point2);
VectorMultAdd (point2, frame->left, right, point);
qfglVertex3fv (point);
qfglVertex3fv (&point2[0]);
point2 += frame->right * right;
point1 += frame->right * right;
qfglTexCoord2f (1, 0);
VectorMultAdd (point2, frame->right, right, point);
qfglVertex3fv (point);
qfglVertex3fv (&point2[0]);
qfglTexCoord2f (1, 1);
VectorMultAdd (point1, frame->right, right, point);
qfglVertex3fv (point);
qfglVertex3fv (&point1[0]);
qfglEnd ();
@ -169,60 +168,60 @@ static void
R_DrawSpriteModel_VA_f (entity_t *e)
{
unsigned char modelalpha, color[4];
float *up, *right;
vec4f_t up = {}, right = {};
vec4f_t origin, point1, point2;
int i;
// unsigned int vacount;
msprite_t *psprite;
mspriteframe_t *frame;
vec3_t point1, point2, v_up;
varray_t2f_c4ub_v3f_t *VA;
VA = gl_spriteVertexArray; // FIXME: Despair
// don't bother culling, it's just a single polygon without a surface cache
frame = R_GetSpriteFrame (e);
psprite = e->model->cache.data;
psprite = e->renderer.model->cache.data;
qfglBindTexture (GL_TEXTURE_2D, frame->gl_texturenum); // FIXME: DESPAIR
if (psprite->type == SPR_ORIENTED) { // bullet marks on walls
up = e->transform + 2 * 4;
right = e->transform + 1 * 4;
up = Transform_Up (e->transform);
right = Transform_Right (e->transform);
} else if (psprite->type == SPR_VP_PARALLEL_UPRIGHT) {
v_up[0] = 0;
v_up[1] = 0;
v_up[2] = 1;
up = v_up;
right = vright;
up = (vec4f_t) { 0, 0, 1, 0 };
VectorCopy (vright, right);
} else { // normal sprite
up = vup;
right = vright;
VectorCopy (vup, up);
VectorCopy (vright, right);
}
if (e->scale != 1.0) {
VectorScale (up, e->scale, up);
VectorScale (right, e->scale, right);
up *= e->scale;
right *= e->scale;
}
for (i = 0; i < 4; i++)
color[i] = e->colormod[i] * 255;
for (i = 0; i < 4; i++) {
color[i] = e->renderer.colormod[i] * 255;
}
memcpy (VA[0].color, color, 4);
memcpy (VA[1].color, color, 4);
memcpy (VA[2].color, color, 4);
memcpy (VA[3].color, color, 4);
modelalpha = color[3];
if (modelalpha < 255)
qfglDepthMask (GL_FALSE);
VectorMultAdd (e->origin, frame->down, up, point1);
VectorMultAdd (point1, frame->left, right, VA[0].vertex);
origin = Transform_GetWorldPosition (e->transform);
point1 = origin + frame->down * up + frame->left * right;
VectorCopy (point1, VA[0].vertex);
memcpy (VA[1].color, color, 4);
VectorMultAdd (e->origin, frame->up, up, point2);
VectorMultAdd (point2, frame->left, right, VA[1].vertex);
point2 = origin + frame->up * up + frame->left * right;
VectorCopy (point2, VA[1].vertex);
memcpy (VA[2].color, color, 4);
VectorMultAdd (point2, frame->right, right, VA[2].vertex);
memcpy (VA[3].color, color, 4);
VectorMultAdd (point1, frame->right, right, VA[3].vertex);
point2 += frame->right * right;
point1 += frame->right * right;
VectorCopy (point2, VA[2].vertex);
VectorCopy (point1, VA[3].vertex);
// VA += 4;
// vacount += 4;

View file

@ -44,6 +44,7 @@
#include "QF/cvar.h"
#include "QF/draw.h"
#include "QF/entity.h"
#include "QF/locs.h"
#include "QF/mathlib.h"
#include "QF/qargs.h"
@ -178,7 +179,9 @@ glrmain_init (void)
void
gl_R_RotateForEntity (entity_t *e)
{
qfglMultMatrixf (e->transform);
mat4f_t mat;
Transform_GetWorldMatrix (e->transform, mat);
qfglMultMatrixf (&mat[0][0]);
}
/*
@ -217,7 +220,7 @@ R_DrawEntitiesOnList (void)
}
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_alias)
if (ent->renderer.model->type != mod_alias)
continue;
currententity = ent;
@ -249,7 +252,7 @@ R_DrawEntitiesOnList (void)
}
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_iqm)
if (ent->renderer.model->type != mod_iqm)
continue;
currententity = ent;
@ -262,7 +265,7 @@ R_DrawEntitiesOnList (void)
if (gl_va_capable)
qfglInterleavedArrays (GL_T2F_C4UB_V3F, 0, gl_spriteVertexArray);
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_sprite)
if (ent->renderer.model->type != mod_sprite)
continue;
currententity = ent;
@ -279,7 +282,7 @@ R_DrawViewModel (void)
|| !r_drawviewmodel->int_val
|| gl_envmap
|| !r_drawentities->int_val
|| !currententity->model)
|| !currententity->renderer.model)
return;
// hack the depth range to prevent view model from poking into walls
@ -349,7 +352,7 @@ gl_R_SetupFrame (void)
R_SetFrustum ();
// current viewleaf
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
r_cache_thrash = false;
@ -559,10 +562,12 @@ R_Mirror (void)
static void
R_RenderView_ (void)
{
if (r_norefresh->int_val)
if (r_norefresh->int_val) {
return;
if (!r_worldentity.model)
}
if (!r_worldentity.renderer.model) {
Sys_Error ("R_RenderView: NULL worldmodel");
}
gl_mirror = false;
@ -892,7 +897,7 @@ R_RenderViewFishEye (void)
void
gl_R_ClearState (void)
{
r_worldentity.model = 0;
r_worldentity.renderer.model = 0;
R_ClearEfrags ();
R_ClearDlights ();
gl_R_ClearParticles ();

View file

@ -191,7 +191,7 @@ gl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
d_lightstylevalue[i] = 264; // normal light value
memset (&r_worldentity, 0, sizeof (r_worldentity));
r_worldentity.model = worldmodel;
r_worldentity.renderer.model = worldmodel;
brush = &worldmodel->brush;
R_FreeAllEntities ();
@ -230,7 +230,8 @@ gl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
continue;
if (*models[i]->path == '*')
continue;
if (models[i] != r_worldentity.model && models[i]->type == mod_brush)
if (models[i] != r_worldentity.renderer.model
&& models[i]->type == mod_brush)
register_textures (&models[i]->brush);
}
}

View file

@ -45,6 +45,7 @@
#include <stdio.h>
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/sys.h"
#include "QF/GL/defines.h"
@ -530,11 +531,14 @@ gl_R_DrawBrushModel (entity_t *e)
qboolean rotated;
vec3_t mins, maxs;
mod_brush_t *brush;
mat4f_t worldMatrix;
model = e->model;
model = e->renderer.model;
brush = &model->brush;
if (e->transform[0] != 1 || e->transform[5] != 1 || e->transform[10] != 1) {
Transform_GetWorldMatrix (e->transform, worldMatrix);
if (worldMatrix[0][0] != 1 || worldMatrix[1][1] != 1
|| worldMatrix[2][2] != 1) {
rotated = true;
radius = model->radius;
#if 0 //QSG FIXME
@ -559,12 +563,11 @@ gl_R_DrawBrushModel (entity_t *e)
VectorSubtract (r_refdef.vieworg, e->origin, modelorg);
if (rotated) {
vec3_t temp;
vec4f_t temp = { modelorg[0], modelorg[1], modelorg[2], 0 };
VectorCopy (modelorg, temp);
modelorg[0] = DotProduct (temp, e->transform + 0);
modelorg[1] = DotProduct (temp, e->transform + 4);
modelorg[2] = DotProduct (temp, e->transform + 8);
modelorg[0] = dotf (temp, worldMatrix[0])[0];
modelorg[1] = dotf (temp, worldMatrix[1])[0];
modelorg[2] = dotf (temp, worldMatrix[2])[0];
}
// calculate dynamic lighting for bmodel if it's not an instanced model
@ -584,7 +587,7 @@ gl_R_DrawBrushModel (entity_t *e)
qfglPushMatrix ();
gl_R_RotateForEntity (e);
qfglGetFloatv (GL_MODELVIEW_MATRIX, e->full_transform);
qfglGetFloatv (GL_MODELVIEW_MATRIX, e->renderer.full_transform);
qfglPopMatrix ();
psurf = &brush->surfaces[brush->firstmodelsurface];
@ -599,7 +602,8 @@ gl_R_DrawBrushModel (entity_t *e)
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
chain_surface (brush, psurf, e->full_transform, e->colormod);
chain_surface (brush, psurf, e->renderer.full_transform,
e->renderer.colormod);
}
}
}
@ -717,7 +721,7 @@ gl_R_DrawWorld (void)
entity_t worldent;
memset (&worldent, 0, sizeof (worldent));
worldent.model = r_worldentity.model;
worldent.renderer.model = r_worldentity.renderer.model;
VectorCopy (r_refdef.vieworg, modelorg);
@ -729,12 +733,13 @@ gl_R_DrawWorld (void)
gl_R_DrawSky ();
}
R_VisitWorldNodes (&r_worldentity.model->brush);
R_VisitWorldNodes (&r_worldentity.renderer.model->brush);
if (r_drawentities->int_val) {
entity_t *ent;
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_brush)
if (ent->renderer.model->type != mod_brush) {
continue;
}
currententity = ent;
gl_R_DrawBrushModel (currententity);

View file

@ -43,6 +43,7 @@
#include <stdlib.h>
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "QF/sys.h"
@ -111,7 +112,7 @@ static struct {
{"fog", 1},
};
static mat4_t alias_vp;
static mat4f_t alias_vp;
void
glsl_R_InitAlias (void)
@ -159,8 +160,9 @@ calc_lighting (entity_t *ent, float *ambient, float *shadelight,
int light;
VectorSet ( -1, 0, 0, lightvec); //FIXME
light = R_LightPoint (&r_worldentity.model->brush, ent->origin);
*ambient = max (light, max (ent->model->min_light, ent->min_light) * 128);
light = R_LightPoint (&r_worldentity.renderer.model->brush, ent->origin);
*ambient = max (light, max (ent->renderer.model->min_light,
ent->renderer.min_light) * 128);
*shadelight = *ambient;
for (i = 0; i < r_maxdlights; i++) {
@ -228,50 +230,52 @@ glsl_R_DrawAlias (void)
float skin_size[2];
float blend;
entity_t *ent = currententity;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
aliashdr_t *hdr;
vec_t norm_mat[9];
mat4_t mvp_mat;
int skin_tex;
int colormap;
aliasvrt_t *pose1 = 0; // VBO's are null based
aliasvrt_t *pose2 = 0; // VBO's are null based
mat4f_t worldMatrix;
if (!(hdr = model->aliashdr))
hdr = Cache_Get (&model->cache);
calc_lighting (ent, &ambient, &shadelight, lightvec);
Transform_GetWorldMatrix (ent->transform, worldMatrix);
// we need only the rotation for normals.
VectorCopy (ent->transform + 0, norm_mat + 0);
VectorCopy (ent->transform + 4, norm_mat + 3);
VectorCopy (ent->transform + 8, norm_mat + 6);
VectorCopy (worldMatrix[0], norm_mat + 0);
VectorCopy (worldMatrix[1], norm_mat + 3);
VectorCopy (worldMatrix[2], norm_mat + 6);
// ent model scaling and offset
Mat4Zero (mvp_mat);
mvp_mat[0] = hdr->mdl.scale[0];
mvp_mat[5] = hdr->mdl.scale[1];
mvp_mat[10] = hdr->mdl.scale[2];
mvp_mat[15] = 1;
VectorCopy (hdr->mdl.scale_origin, mvp_mat + 12);
Mat4Mult (ent->transform, mvp_mat, mvp_mat);
Mat4Mult (alias_vp, mvp_mat, mvp_mat);
mat4f_t mvp_mat = {
{ hdr->mdl.scale[0], 0, 0, 0 },
{ 0, hdr->mdl.scale[1], 0, 0 },
{ 0, 0, hdr->mdl.scale[2], 0 },
{ hdr->mdl.scale_origin[0], hdr->mdl.scale_origin[1],
hdr->mdl.scale_origin[2], 1 },
};
mmulf (mvp_mat, worldMatrix, mvp_mat);
mmulf (mvp_mat, alias_vp, mvp_mat);
colormap = glsl_colormap;
if (ent->skin && ent->skin->auxtex)
colormap = ent->skin->auxtex;
if (ent->skin && ent->skin->texnum) {
skin_t *skin = ent->skin;
if (ent->renderer.skin && ent->renderer.skin->auxtex)
colormap = ent->renderer.skin->auxtex;
if (ent->renderer.skin && ent->renderer.skin->texnum) {
skin_t *skin = ent->renderer.skin;
skin_tex = skin->texnum;
} else {
maliasskindesc_t *skindesc;
skindesc = R_AliasGetSkindesc (ent->skinnum, hdr);
skindesc = R_AliasGetSkindesc (ent->renderer.skinnum, hdr);
skin_tex = skindesc->texnum;
}
blend = R_AliasGetLerpedFrames (ent, hdr);
pose1 += ent->pose1 * hdr->poseverts;
pose2 += ent->pose2 * hdr->poseverts;
pose1 += ent->animation.pose1 * hdr->poseverts;
pose2 += ent->animation.pose2 * hdr->poseverts;
skin_size[0] = hdr->mdl.skinwidth;
skin_size[1] = hdr->mdl.skinheight;
@ -293,7 +297,8 @@ glsl_R_DrawAlias (void)
qfeglUniform1f (quake_mdl.shadelight.location, shadelight);
qfeglUniform3fv (quake_mdl.lightvec.location, 1, lightvec);
qfeglUniform2fv (quake_mdl.skin_size.location, 1, skin_size);
qfeglUniformMatrix4fv (quake_mdl.mvp_matrix.location, 1, false, mvp_mat);
qfeglUniformMatrix4fv (quake_mdl.mvp_matrix.location, 1, false,
&mvp_mat[0][0]);
qfeglUniformMatrix3fv (quake_mdl.norm_matrix.location, 1, false, norm_mat);
#ifndef TETRAHEDRON
@ -321,7 +326,7 @@ glsl_R_AliasBegin (void)
quat_t fog;
// pre-multiply the view and projection matricies
Mat4Mult (glsl_projection, glsl_view, alias_vp);
mmulf (alias_vp, glsl_projection, glsl_view);
qfeglUseProgram (quake_mdl.program);
qfeglEnableVertexAttribArray (quake_mdl.vertexa.location);

View file

@ -46,6 +46,7 @@
#include "QF/cvar.h"
#include "QF/dstring.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -94,7 +95,7 @@ static instsurf_t **instsurfs_tail = &instsurfs;
static instsurf_t *free_instsurfs;
static GLuint bsp_vbo;
static mat4_t bsp_vp;
static mat4f_t bsp_vp;
static GLuint skybox_tex;
static qboolean skybox_loaded;
@ -430,9 +431,9 @@ glsl_R_RegisterTextures (model_t **models, int num_models)
mod_brush_t *brush;
glsl_R_ClearTextures ();
glsl_R_InitSurfaceChains (&r_worldentity.model->brush);
glsl_R_InitSurfaceChains (&r_worldentity.renderer.model->brush);
glsl_R_AddTexture (r_notexture_mip);
register_textures (&r_worldentity.model->brush);
register_textures (&r_worldentity.renderer.model->brush);
for (i = 0; i < num_models; i++) {
m = models[i];
if (!m)
@ -441,7 +442,7 @@ glsl_R_RegisterTextures (model_t **models, int num_models)
if (*m->path == '*')
continue;
// world has already been done, not interested in non-brush models
if (m == r_worldentity.model || m->type != mod_brush)
if (m == r_worldentity.renderer.model || m->type != mod_brush)
continue;
brush = &m->brush;
brush->numsubmodels = 1; // no support for submodels in non-world model
@ -486,7 +487,7 @@ build_surf_displist (model_t **models, msurface_t *fa, int base,
if (fa->ec_index < 0) {
brush = &models[-fa->ec_index - 1]->brush;
} else {
brush = &r_worldentity.model->brush;
brush = &r_worldentity.renderer.model->brush;
}
vertices = brush->vertexes;
edges = brush->edges;
@ -585,7 +586,7 @@ glsl_R_BuildDisplayLists (model_t **models, int num_models)
}
surf = brush->surfaces + j;
surf->ec_index = dm - brush->submodels;
if (!surf->ec_index && m != r_worldentity.model)
if (!surf->ec_index && m != r_worldentity.renderer.model)
surf->ec_index = -1 - i; // instanced model
tex = surf->texinfo->texture->render;
CHAIN_SURF_F2B (surf, tex->tex_chain);
@ -662,9 +663,12 @@ R_DrawBrushModel (entity_t *e)
vec3_t mins, maxs, org;
mod_brush_t *brush;
model = e->model;
model = e->renderer.model;
brush = &model->brush;
if (e->transform[0] != 1 || e->transform[5] != 1 || e->transform[10] != 1) {
mat4f_t mat;
Transform_GetWorldMatrix (e->transform, mat);
memcpy (e->renderer.full_transform, mat, sizeof (mat));//FIXME
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
rotated = true;
radius = model->radius;
if (R_CullSphere (e->origin, radius))
@ -679,12 +683,11 @@ R_DrawBrushModel (entity_t *e)
VectorSubtract (r_refdef.vieworg, e->origin, org);
if (rotated) {
vec3_t temp;
vec4f_t temp = { org[0], org[1], org[2], 0 };
VectorCopy (org, temp);
org[0] = DotProduct (temp, e->transform + 0);
org[1] = DotProduct (temp, e->transform + 4);
org[2] = DotProduct (temp, e->transform + 8);
org[0] = dotf (temp, mat[0])[0];
org[1] = dotf (temp, mat[1])[0];
org[2] = dotf (temp, mat[2])[0];
}
// calculate dynamic lighting for bmodel if it's not an instanced model
@ -713,7 +716,8 @@ R_DrawBrushModel (entity_t *e)
// enqueue the polygon
if (((surf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON))
|| (!(surf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
chain_surface (brush, surf, e->transform, e->colormod);
chain_surface (brush, surf, e->renderer.full_transform,
e->renderer.colormod);
}
}
}
@ -842,10 +846,10 @@ draw_elechain (elechain_t *ec, int matloc, int vertloc, int tlstloc,
}
}
if (ec->transform) {
Mat4Mult (bsp_vp, ec->transform, mat);
Mat4Mult (&bsp_vp[0][0], ec->transform, mat);//FIXME
qfeglUniformMatrix4fv (matloc, 1, false, mat);
} else {
qfeglUniformMatrix4fv (matloc, 1, false, bsp_vp);
qfeglUniformMatrix4fv (matloc, 1, false, &bsp_vp[0][0]);
}
for (el = ec->elements; el; el = el->next) {
if (!el->list->size)
@ -873,7 +877,7 @@ bsp_begin (void)
QuatCopy (default_color, last_color);
qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
Mat4Mult (glsl_projection, glsl_view, bsp_vp);
mmulf (bsp_vp, glsl_projection, glsl_view);
qfeglUseProgram (quake_bsp.program);
qfeglEnableVertexAttribArray (quake_bsp.vertex.location);
@ -928,7 +932,7 @@ turb_begin (void)
QuatCopy (default_color, last_color);
qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
Mat4Mult (glsl_projection, glsl_view, bsp_vp);
mmulf (bsp_vp, glsl_projection, glsl_view);
qfeglUseProgram (quake_turb.program);
qfeglEnableVertexAttribArray (quake_turb.vertex.location);
@ -1001,7 +1005,7 @@ sky_begin (void)
QuatCopy (default_color, last_color);
qfeglVertexAttrib4fv (quake_bsp.color.location, default_color);
Mat4Mult (glsl_projection, glsl_view, bsp_vp);
mmulf (bsp_vp, glsl_projection, glsl_view);
if (skybox_loaded) {
sky_params.mvp_matrix = &quake_skybox.mvp_matrix;
@ -1127,15 +1131,15 @@ glsl_R_DrawWorld (void)
clear_texture_chains (); // do this first for water and skys
memset (&worldent, 0, sizeof (worldent));
worldent.model = r_worldentity.model;
worldent.renderer.model = r_worldentity.renderer.model;
currententity = &worldent;
R_VisitWorldNodes (&worldent.model->brush);
R_VisitWorldNodes (&worldent.renderer.model->brush);
if (r_drawentities->int_val) {
entity_t *ent;
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_brush)
if (ent->renderer.model->type != mod_brush)
continue;
currententity = ent;

View file

@ -43,6 +43,7 @@
#include <stdlib.h>
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/skin.h"
#include "QF/sys.h"
@ -137,7 +138,7 @@ static struct va_attr_s {
{&iqm_shader.vcolor, 4, GL_UNSIGNED_BYTE, 1},
};
static mat4_t iqm_vp;
static mat4f_t iqm_vp;
void
glsl_R_InitIQM (void)
@ -207,28 +208,31 @@ glsl_R_DrawIQM (void)
{
static quat_t color = { 1, 1, 1, 1};
entity_t *ent = currententity;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
glsliqm_t *glsl = (glsliqm_t *) iqm->extra_data;
dlight_t *lights[MAX_IQM_LIGHTS];
int i;
vec_t norm_mat[9];
mat4_t mvp_mat;
mat4f_t mvp_mat;
float blend;
iqmframe_t *frame;
R_LightPoint (&r_worldentity.model->brush, ent->origin);//FIXME min_light?
R_LightPoint (&r_worldentity.renderer.model->brush, ent->origin);//FIXME min_light?
VectorScale (ambientcolor, 1/255.0, ambientcolor);
R_FindNearLights (ent->origin, MAX_IQM_LIGHTS, lights);
// we need only the rotation for normals.
VectorCopy (ent->transform + 0, norm_mat + 0);
VectorCopy (ent->transform + 4, norm_mat + 3);
VectorCopy (ent->transform + 8, norm_mat + 6);
Mat4Mult (iqm_vp, ent->transform, mvp_mat);
mat4f_t mat;
Transform_GetWorldMatrix (ent->transform, mat);
VectorCopy (mat[0], norm_mat + 0);
VectorCopy (mat[1], norm_mat + 3);
VectorCopy (mat[2], norm_mat + 6);
mmulf (mvp_mat, iqm_vp, mat);
blend = R_IQMGetLerpedFrames (ent, iqm);
frame = R_IQMBlendFrames (iqm, ent->pose1, ent->pose2, blend, 0);
frame = R_IQMBlendFrames (iqm, ent->animation.pose1, ent->animation.pose2,
blend, 0);
qfeglUniform3fv (iqm_shader.ambient.location, 1, ambientcolor);
for (i = 0; i < MAX_IQM_LIGHTS; i++) {
@ -249,7 +253,8 @@ glsl_R_DrawIQM (void)
qfeglBindBuffer (GL_ARRAY_BUFFER, glsl->vertex_array);
qfeglBindBuffer (GL_ELEMENT_ARRAY_BUFFER, glsl->element_array);
qfeglUniformMatrix4fv (iqm_shader.mvp_matrix.location, 1, false, mvp_mat);
qfeglUniformMatrix4fv (iqm_shader.mvp_matrix.location, 1, false,
&mvp_mat[0][0]);
qfeglUniformMatrix3fv (iqm_shader.norm_matrix.location, 1, false,
norm_mat);
qfeglUniformMatrix4fv (iqm_shader.bonemats.location, iqm->num_joints,
@ -274,7 +279,7 @@ glsl_R_IQMBegin (void)
quat_t fog;
// pre-multiply the view and projection matricies
Mat4Mult (glsl_projection, glsl_view, iqm_vp);
mmulf (iqm_vp, glsl_projection, glsl_view);
qfeglUseProgram (iqm_shader.program);

View file

@ -60,15 +60,15 @@
#include "r_internal.h"
#include "vid_gl.h"
mat4_t glsl_projection;
mat4_t glsl_view;
mat4f_t glsl_projection;
mat4f_t glsl_view;
void
glsl_R_ViewChanged (float aspect)
{
double xmin, xmax, ymin, ymax;
float fovx, fovy, neard, fard;
vec_t *proj = glsl_projection;
vec4f_t *proj = glsl_projection;
fovx = r_refdef.fov_x;
fovy = r_refdef.fov_y;
@ -80,25 +80,30 @@ glsl_R_ViewChanged (float aspect)
xmax = neard * tan (fovx * M_PI / 360); // fov_2 / 2
xmin = -xmax;
proj[0] = (2 * neard) / (xmax - xmin);
proj[4] = 0;
proj[8] = (xmax + xmin) / (xmax - xmin);
proj[12] = 0;
proj[1] = 0;
proj[5] = (2 * neard) / (ymax - ymin);
proj[9] = (ymax + ymin) / (ymax - ymin);
proj[13] = 0;
proj[2] = 0;
proj[6] = 0;
proj[10] = (fard + neard) / (neard - fard);
proj[14] = (2 * fard * neard) / (neard - fard);
proj[3] = 0;
proj[7] = 0;
proj[11] = -1;
proj[15] = 0;
proj[0] = (vec4f_t) {
(2 * neard) / (xmax - xmin),
0,
0,
0
};
proj[1] = (vec4f_t) {
0,
(2 * neard) / (ymax - ymin),
0,
0
};
proj[2] = (vec4f_t) {
(xmax + xmin) / (xmax - xmin),
(ymax + ymin) / (ymax - ymin),
(fard + neard) / (neard - fard),
-1
};
proj[3] = (vec4f_t) {
0,
0,
(2 * fard * neard) / (neard - fard),
0
};
}
void
@ -110,22 +115,24 @@ glsl_R_SetupFrame (void)
VectorCopy (r_refdef.vieworg, r_origin);
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
R_SetFrustum ();
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
}
static void
R_SetupView (void)
{
float x, y, w, h;
mat4_t mat;
static mat4_t z_up = {
0, 0, -1, 0,
-1, 0, 0, 0,
0, 1, 0, 0,
0, 0, 0, 1,
static mat4f_t z_up = {
{ 0, 0, -1, 0},
{-1, 0, 0, 0},
{ 0, 1, 0, 0},
{ 0, 0, 0, 1},
};
vec4f_t rotation;
vec4f_t offset = { 0, 0, 0, 1 };
x = r_refdef.vrect.x;
y = (vid.height - (r_refdef.vrect.y + r_refdef.vrect.height));
@ -133,17 +140,12 @@ R_SetupView (void)
h = r_refdef.vrect.height;
qfeglViewport (x, y, w, h);
Mat4Zero (mat);
VectorCopy (vpn, mat + 0);
VectorNegate (vright, mat + 4); // we want vleft
VectorCopy (vup, mat + 8);
mat[15] = 1;
Mat4Transpose (mat, mat);//AngleVectors gives the transpose of what we want
Mat4Mult (z_up, mat, glsl_view);
Mat4Identity (mat);
VectorNegate (r_refdef.vieworg, mat + 12);
Mat4Mult (glsl_view, mat, glsl_view);
AngleQuat (r_refdef.viewangles, &rotation[0]);
rotation = qconjf (rotation);
mat4fquat (glsl_view, rotation);
mmulf (glsl_view, z_up, glsl_view);
VectorNegate (r_refdef.vieworg, offset);
glsl_view[3] = mvmulf (glsl_view, offset);
qfeglEnable (GL_CULL_FACE);
qfeglEnable (GL_DEPTH_TEST);
@ -161,7 +163,7 @@ R_RenderEntities (void)
do { \
begun = 0; \
for (ent = r_ent_queue; ent; ent = ent->next) { \
if (ent->model->type != mod_##type_name) \
if (ent->renderer.model->type != mod_##type_name) \
continue; \
if (!begun) { \
glsl_R_##Type##Begin (); \
@ -186,7 +188,7 @@ R_DrawViewModel (void)
if (vr_data.inhibit_viewmodel
|| !r_drawviewmodel->int_val
|| !r_drawentities->int_val
|| !currententity->model)
|| !currententity->renderer.model)
return;
// hack the depth range to prevent view model from poking into walls
@ -273,7 +275,7 @@ glsl_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
d_lightstylevalue[i] = 264; // normal light value
memset (&r_worldentity, 0, sizeof (r_worldentity));
r_worldentity.model = worldmodel;
r_worldentity.renderer.model = worldmodel;
// Force a vis update
r_viewleaf = NULL;

View file

@ -313,7 +313,7 @@ glsl_R_ReadPointFile_f (void)
vec3_t org;
QFile *f;
mapname = strdup (r_worldentity.model->path);
mapname = strdup (r_worldentity.renderer.model->path);
if (!mapname)
Sys_Error ("Can't duplicate mapname!");
QFS_StripExtension (mapname, mapname);
@ -1568,10 +1568,10 @@ draw_qf_particles (void)
particle_t *part;
vec3_t up_scale, right_scale, up_right_scale, down_right_scale;
partvert_t *VA;
mat4_t vp_mat;
mat4f_t vp_mat;
quat_t fog;
Mat4Mult (glsl_projection, glsl_view, vp_mat);
mmulf (vp_mat, glsl_projection, glsl_view);
qfeglDepthMask (GL_FALSE);
qfeglUseProgram (quake_part.program);
@ -1583,7 +1583,8 @@ draw_qf_particles (void)
fog[3] = glsl_Fog_GetDensity () / 64.0;
qfeglUniform4fv (quake_part.fog.location, 1, fog);
qfeglUniformMatrix4fv (quake_part.mvp_matrix.location, 1, false, vp_mat);
qfeglUniformMatrix4fv (quake_part.mvp_matrix.location, 1, false,
&vp_mat[0][0]);
qfeglUniform1i (quake_part.texture.location, 0);
qfeglActiveTexture (GL_TEXTURE0 + 0);
@ -1712,10 +1713,10 @@ draw_id_particles (void)
float minparticledist;
particle_t *part;
partvert_t *VA;
mat4_t vp_mat;
mat4f_t vp_mat;
quat_t fog;
Mat4Mult (glsl_projection, glsl_view, vp_mat);
mmulf (vp_mat, glsl_projection, glsl_view);
// LordHavoc: particles should not affect zbuffer
qfeglDepthMask (GL_FALSE);
@ -1723,7 +1724,8 @@ draw_id_particles (void)
qfeglEnableVertexAttribArray (quake_point.vertex.location);
qfeglEnableVertexAttribArray (quake_point.color.location);
qfeglUniformMatrix4fv (quake_point.mvp_matrix.location, 1, false, vp_mat);
qfeglUniformMatrix4fv (quake_point.mvp_matrix.location, 1, false,
&vp_mat[0][0]);
glsl_Fog_GetColor (fog);
fog[3] = glsl_Fog_GetDensity () / 64.0;

View file

@ -42,6 +42,7 @@
#endif
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/draw.h"
#include "QF/dstring.h"
#include "QF/quakefs.h"
@ -131,7 +132,7 @@ static void
R_GetSpriteFrames (entity_t *ent, msprite_t *sprite, mspriteframe_t **frame1,
mspriteframe_t **frame2, float *blend)
{
int framenum = currententity->frame;
int framenum = currententity->animation.frame;
int pose;
int i, numframes;
float *intervals;
@ -153,7 +154,7 @@ R_GetSpriteFrames (entity_t *ent, msprite_t *sprite, mspriteframe_t **frame1,
numframes = group->numframes;
fullinterval = intervals[numframes - 1];
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
targettime = time - ((int) (time / fullinterval)) * fullinterval;
for (i = 0; i < numframes - 1; i++) {
@ -170,17 +171,17 @@ R_GetSpriteFrames (entity_t *ent, msprite_t *sprite, mspriteframe_t **frame1,
//group frames.
*blend = R_EntityBlend (ent, pose, frame_interval);
if (group) {
*frame1 = group->frames[ent->pose1];
*frame2 = group->frames[ent->pose2];
*frame1 = group->frames[ent->animation.pose1];
*frame2 = group->frames[ent->animation.pose2];
} else {
*frame1 = sprite->frames[ent->pose1].frameptr;
*frame2 = sprite->frames[ent->pose2].frameptr;
*frame1 = sprite->frames[ent->animation.pose1].frameptr;
*frame2 = sprite->frames[ent->animation.pose2].frameptr;
}
}
static void
make_quad (mspriteframe_t *frame, const vec3_t vpn, const vec3_t vright,
const vec3_t vup, float verts[6][3])
make_quad (mspriteframe_t *frame, vec4f_t vpn, vec4f_t vright,
vec4f_t vup, float verts[6][3])
{
vec3_t left, up, right, down;
vec3_t ul, ur, ll, lr;
@ -209,11 +210,11 @@ void
R_DrawSprite (void)
{
entity_t *ent = currententity;
msprite_t *sprite = (msprite_t *) ent->model->cache.data;
msprite_t *sprite = (msprite_t *) ent->renderer.model->cache.data;
mspriteframe_t *frame1, *frame2;
float blend, sr, cr, dot, angle;
vec3_t tvec;
vec3_t svpn, svright, svup;
vec4f_t svpn = {}, svright = {}, svup = {};
static quat_t color = { 1, 1, 1, 1};
float vertsa[6][3], vertsb[6][3];
static float uvab[6][4] = {
@ -242,7 +243,7 @@ R_DrawSprite (void)
VectorSet (0, 0, 1, svup);
// CrossProduct (svup, -r_origin, svright)
VectorSet (tvec[1], -tvec[0], 0, svright);
VectorNormalize (svright);
svright /= vsqrtf (dotf (svright, svright));
// CrossProduct (svright, svup, svpn);
VectorSet (-svright[1], svright[0], 0, svpn);
break;
@ -267,16 +268,16 @@ R_DrawSprite (void)
VectorSet (0, 0, 1, svup);
// CrossProduct (svup, -r_origin, svright)
VectorSet (vpn[1], -vpn[0], 0, svright);
VectorNormalize (svright);
svright /= vsqrtf (dotf (svright, svright));
// CrossProduct (svright, svup, svpn);
VectorSet (-svright[1], svright[0], 0, svpn);
break;
case SPR_ORIENTED:
// generate the prite's axes according to the sprite's world
// orientation
VectorCopy (currententity->transform + 0, svpn);
VectorNegate (currententity->transform + 4, svright);
VectorCopy (currententity->transform + 8, svup);
svup = Transform_Up (currententity->transform);
svright = Transform_Right (currententity->transform);
svpn = Transform_Forward (currententity->transform);
break;
case SPR_VP_PARALLEL_ORIENTED:
// generate the sprite's axes parallel to the viewplane, but
@ -324,7 +325,7 @@ R_DrawSprite (void)
void
R_SpriteBegin (void)
{
mat4_t mat;
mat4f_t mat;
quat_t fog;
qfeglUseProgram (quake_sprite.program);
@ -352,8 +353,8 @@ R_SpriteBegin (void)
qfeglEnable (GL_TEXTURE_2D);
qfeglBindTexture (GL_TEXTURE_2D, glsl_palette);
Mat4Mult (glsl_projection, glsl_view, mat);
qfeglUniformMatrix4fv (quake_sprite.matrix.location, 1, false, mat);
mmulf (mat, glsl_projection, glsl_view);
qfeglUniformMatrix4fv (quake_sprite.matrix.location, 1, false, &mat[0][0]);
}
void

View file

@ -63,7 +63,7 @@ R_AliasGetSkindesc (int skinnum, aliashdr_t *ahdr)
numskins = paliasskingroup->numskins;
fullskininterval = pskinintervals[numskins - 1];
skintime = vr_data.realtime + currententity->syncbase;
skintime = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadAliasSkinGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
@ -118,7 +118,7 @@ alias_get_frame (int framenum, aliashdr_t *hdr, float *frame_interval)
numframes = group->numframes;
fullinterval = intervals[numframes - 1];
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadAliasGroup, we guaranteed all interval values
// are positive, so we don't have to worry about division by 0
@ -148,6 +148,6 @@ R_AliasGetLerpedFrames (entity_t *ent, aliashdr_t *hdr)
maliasframedesc_t *frame;
float interval;
frame = alias_get_frame (ent->frame, hdr, &interval);
frame = alias_get_frame (ent->animation.frame, hdr, &interval);
return R_EntityBlend (ent, frame->firstpose, interval);
}

View file

@ -54,7 +54,7 @@ R_MarkLeaves (void)
mleaf_t *leaf;
mnode_t *node;
msurface_t **mark;
mod_brush_t *brush = &r_worldentity.model->brush;
mod_brush_t *brush = &r_worldentity.renderer.model->brush;
if (r_oldviewleaf == r_viewleaf && !r_novis->int_val)
return;
@ -70,7 +70,7 @@ R_MarkLeaves (void)
vis = solid;
memset (solid, 0xff, (brush->numleafs + 7) >> 3);
} else
vis = Mod_LeafPVS (r_viewleaf, r_worldentity.model);
vis = Mod_LeafPVS (r_viewleaf, r_worldentity.renderer.model);
for (i = 0; (int) i < brush->numleafs; i++) {
if (vis[i >> 3] & (1 << (i & 7))) {
@ -105,7 +105,7 @@ R_TextureAnimation (msurface_t *surf)
texture_t *base = surf->texinfo->texture;
int count, relative;
if (currententity->frame) {
if (currententity->animation.frame) {
if (base->alternate_anims)
base = base->alternate_anims;
}

View file

@ -101,7 +101,7 @@ R_RemoveEfrags (entity_t *ent)
{
efrag_t *ef, *old, *walk, **prev;
ef = ent->efrag;
ef = ent->visibility.efrag;
while (ef) {
prev = &ef->leaf->efrags;
@ -124,7 +124,7 @@ R_RemoveEfrags (entity_t *ent)
r_free_efrags = old;
}
ent->efrag = 0;
ent->visibility.efrag = 0;
}
static void
@ -143,15 +143,15 @@ R_SplitEntityOnNode (mod_brush_t *brush, entity_t *ent,
node_stack = alloca ((brush->depth + 2) * sizeof (mnode_t *));
node_ptr = node_stack;
lastlink = &ent->efrag;
lastlink = &ent->visibility.efrag;
*node_ptr++ = 0;
while (node) {
// add an efrag if the node is a leaf
if (__builtin_expect (node->contents < 0, 0)) {
if (!ent->topnode) {
ent->topnode = node;
if (!ent->visibility.topnode) {
ent->visibility.topnode = node;
}
leaf = (mleaf_t *) node;
@ -177,8 +177,8 @@ R_SplitEntityOnNode (mod_brush_t *brush, entity_t *ent,
if (sides == 3) {
// split on this plane
// if this is the first splitter of this bmodel, remember it
if (!ent->topnode) {
ent->topnode = node;
if (!ent->visibility.topnode) {
ent->visibility.topnode = node;
}
}
// recurse down the contacted sides
@ -202,18 +202,18 @@ R_AddEfrags (mod_brush_t *brush, entity_t *ent)
model_t *entmodel;
vec3_t emins, emaxs;
if (!ent->model || !r_worldentity.model)
if (!ent->renderer.model || !r_worldentity.renderer.model)
return;
if (ent == &r_worldentity)
return; // never add the world
entmodel = ent->model;
entmodel = ent->renderer.model;
VectorAdd (ent->origin, entmodel->mins, emins);
VectorAdd (ent->origin, entmodel->maxs, emaxs);
ent->topnode = 0;
ent->visibility.topnode = 0;
R_SplitEntityOnNode (brush, ent, emins, emaxs);
}
@ -225,17 +225,17 @@ R_StoreEfrags (const efrag_t *efrag)
while (efrag) {
ent = efrag->entity;
model = ent->model;
model = ent->renderer.model;
switch (model->type) {
case mod_alias:
case mod_brush:
case mod_sprite:
case mod_iqm:
if (ent->visframe != r_framecount) {
if (ent->visibility.visframe != r_framecount) {
R_EnqueueEntity (ent);
// mark that we've recorded this entity for this frame
ent->visframe = r_framecount;
ent->visibility.visframe = r_framecount;
}
efrag = efrag->leafnext;
break;

View file

@ -38,6 +38,7 @@
#include <math.h>
#include <stdlib.h>
#include "QF/entity.h"
#include "QF/model.h"
#include "QF/msg.h"
#include "QF/render.h"
@ -70,6 +71,7 @@ R_AllocEntity (void)
if ((ent = free_entities)) {
free_entities = ent->next;
ent->next = 0;
ent->transform = 0;
return ent;
}
@ -78,9 +80,12 @@ R_AllocEntity (void)
*entpool_tail = pool;
entpool_tail = &pool->next;
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++)
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++) {
ent->next = ent + 1;
ent->transform = 0;
}
ent->next = 0;
ent->transform = 0;
free_entities = pool->entities;
return R_AllocEntity ();
@ -94,9 +99,18 @@ R_FreeAllEntities (void)
int i;
for (pool = entity_pools; pool; pool = pool->next) {
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++)
for (ent = pool->entities, i = 0; i < ENT_POOL_SIZE - 1; i++, ent++) {
ent->next = ent + 1;
if (ent->transform) {
Transform_Delete (ent->transform);
ent->transform = 0;
}
}
ent->next = pool->next ? pool->next->entities : 0;
if (ent->transform) {
Transform_Delete (ent->transform);
ent->transform = 0;
}
}
free_entities = entity_pools ? entity_pools->entities : 0;
}
@ -121,27 +135,27 @@ R_EntityBlend (entity_t *ent, int pose, float interval)
{
float blend;
if (ent->pose_model != ent->model) {
ent->pose_model = ent->model;
ent->pose1 = pose;
ent->pose2 = pose;
if (ent->animation.nolerp) {
ent->animation.nolerp = 0;
ent->animation.pose1 = pose;
ent->animation.pose2 = pose;
return 0.0;
}
ent->frame_interval = interval;
if (ent->pose2 != pose) {
ent->frame_start_time = vr_data.realtime;
if (ent->pose2 == -1) {
ent->pose1 = pose;
ent->animation.frame_interval = interval;
if (ent->animation.pose2 != pose) {
ent->animation.frame_start_time = vr_data.realtime;
if (ent->animation.pose2 == -1) {
ent->animation.pose1 = pose;
} else {
ent->pose1 = ent->pose2;
ent->animation.pose1 = ent->animation.pose2;
}
ent->pose2 = pose;
ent->animation.pose2 = pose;
blend = 0.0;
} else if (vr_data.paused) {
blend = 1.0;
} else {
blend = (vr_data.realtime - ent->frame_start_time)
/ ent->frame_interval;
blend = (vr_data.realtime - ent->animation.frame_start_time)
/ ent->animation.frame_interval;
blend = min (blend, 1.0);
}
return blend;

View file

@ -49,7 +49,7 @@
float
R_IQMGetLerpedFrames (entity_t *ent, iqm_t *iqm)
{
int frame = ent->frame;
int frame = ent->animation.frame;
float time, fullinterval;
iqmanim *anim;
@ -62,7 +62,7 @@ R_IQMGetLerpedFrames (entity_t *ent, iqm_t *iqm)
}
anim = &iqm->anims[frame];
fullinterval = anim->num_frames / anim->framerate;
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
time -= ((int) (time / fullinterval)) * fullinterval;
frame = (int) (time * anim->framerate) + anim->first_frame;
return R_EntityBlend (ent, frame, 1.0 / anim->framerate);

View file

@ -328,7 +328,7 @@ R_PushDlights (const vec3_t entorigin)
if (l->die < vr_data.realtime || !l->radius)
continue;
VectorSubtract (l->origin, entorigin, lightorigin);
R_MarkLights (lightorigin, l, i, r_worldentity.model);
R_MarkLights (lightorigin, l, i, r_worldentity.renderer.model);
}
}

View file

@ -30,6 +30,7 @@
#include <stdlib.h>
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
@ -94,8 +95,8 @@ R_AliasCheckBBox (void)
int minz;
// expand, rotate, and translate points into worldspace
currententity->trivial_accept = 0;
pmodel = currententity->model;
currententity->visibility.trivial_accept = 0;
pmodel = currententity->renderer.model;
if (!(pahdr = pmodel->aliashdr))
pahdr = Cache_Get (&pmodel->cache);
pmdl = (mdl_t *) ((byte *) pahdr + pahdr->model);
@ -103,7 +104,7 @@ R_AliasCheckBBox (void)
R_AliasSetUpTransform (0);
// construct the base bounding box for this frame
frame = currententity->frame;
frame = currententity->animation.frame;
// TODO: don't repeat this check when drawing?
if ((frame >= pmdl->numframes) || (frame < 0)) {
Sys_MaskPrintf (SYS_DEV, "No such frame %d %s\n", frame, pmodel->path);
@ -218,11 +219,11 @@ R_AliasCheckBBox (void)
return false; // trivial reject off one side
}
currententity->trivial_accept = !anyclip & !zclipped;
currententity->visibility.trivial_accept = !anyclip & !zclipped;
if (currententity->trivial_accept) {
if (currententity->visibility.trivial_accept) {
if (minz > (r_aliastransition + (pmdl->size * r_resfudge))) {
currententity->trivial_accept |= 2;
currententity->visibility.trivial_accept |= 2;
}
}
@ -355,10 +356,12 @@ R_AliasSetUpTransform (int trivial_accept)
float rotationmatrix[3][4], t2matrix[3][4];
static float tmatrix[3][4];
static float viewmatrix[3][4];
mat4f_t mat;
VectorCopy (currententity->transform + 0, alias_forward);
VectorNegate (currententity->transform + 4, alias_right);
VectorCopy (currententity->transform + 8, alias_up);
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], alias_forward);
VectorNegate (mat[1], alias_right);
VectorCopy (mat[2], alias_up);
tmatrix[0][0] = pmdl->scale[0];
tmatrix[1][1] = pmdl->scale[1];
@ -542,7 +545,7 @@ R_AliasSetupSkin (void)
{
int skinnum;
skinnum = currententity->skinnum;
skinnum = currententity->renderer.skinnum;
if ((skinnum >= pmdl->numskins) || (skinnum < 0)) {
Sys_MaskPrintf (SYS_DEV, "R_AliasSetupSkin: no such skin # %d\n",
skinnum);
@ -559,16 +562,16 @@ R_AliasSetupSkin (void)
r_affinetridesc.skinheight = pmdl->skinheight;
acolormap = vid.colormap8;
if (currententity->skin) {
if (currententity->renderer.skin) {
tex_t *base;
base = currententity->skin->texels;
base = currententity->renderer.skin->texels;
if (base) {
r_affinetridesc.pskin = base->data;
r_affinetridesc.skinwidth = base->width;
r_affinetridesc.skinheight = base->height;
}
acolormap = currententity->skin->colormap;
acolormap = currententity->renderer.skin->colormap;
}
}
@ -611,7 +614,7 @@ R_AliasSetupFrame (void)
{
maliasframedesc_t *frame;
frame = R_AliasGetFramedesc (currententity->frame, paliashdr);
frame = R_AliasGetFramedesc (currententity->animation.frame, paliashdr);
r_apverts = (trivertx_t *) ((byte *) paliashdr + frame->frame);
}
@ -624,8 +627,8 @@ R_AliasDrawModel (alight_t *plighting)
r_amodels_drawn++;
if (!(paliashdr = currententity->model->aliashdr))
paliashdr = Cache_Get (&currententity->model->cache);
if (!(paliashdr = currententity->renderer.model->aliashdr))
paliashdr = Cache_Get (&currententity->renderer.model->cache);
pmdl = (mdl_t *) ((byte *) paliashdr + paliashdr->model);
size = (CACHE_SIZE - 1)
@ -641,12 +644,12 @@ R_AliasDrawModel (alight_t *plighting)
pauxverts = (auxvert_t *) &pfinalverts[pmdl->numverts + 1];
R_AliasSetupSkin ();
R_AliasSetUpTransform (currententity->trivial_accept);
R_AliasSetUpTransform (currententity->visibility.trivial_accept);
R_AliasSetupLighting (plighting);
R_AliasSetupFrame ();
r_affinetridesc.drawtype = (currententity->trivial_accept == 3) &&
r_recursiveaffinetriangles;
r_affinetridesc.drawtype = ((currententity->visibility.trivial_accept == 3)
&& r_recursiveaffinetriangles);
if (!acolormap)
acolormap = vid.colormap8;
@ -664,11 +667,14 @@ R_AliasDrawModel (alight_t *plighting)
else
ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
if (currententity->trivial_accept && pmdl->ident != HEADER_MDL16)
if (currententity->visibility.trivial_accept
&& pmdl->ident != HEADER_MDL16) {
R_AliasPrepareUnclippedPoints ();
else
} else {
R_AliasPreparePoints ();
}
if (!currententity->model->aliashdr)
Cache_Release (&currententity->model->cache);
if (!currententity->renderer.model->aliashdr) {
Cache_Release (&currententity->renderer.model->cache);
}
}

View file

@ -33,6 +33,7 @@
#include "qfalloca.h"
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -77,9 +78,11 @@ R_EntityRotate (vec3_t vec)
void
R_RotateBmodel (void)
{
VectorCopy (currententity->transform + 0, entity_rotation[0]);
VectorCopy (currententity->transform + 4, entity_rotation[1]);
VectorCopy (currententity->transform + 8, entity_rotation[2]);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], entity_rotation[0]);
VectorCopy (mat[1], entity_rotation[1]);
VectorCopy (mat[2], entity_rotation[2]);
// rotate modelorg and the transformation matrix
R_EntityRotate (modelorg);
@ -297,7 +300,8 @@ R_DrawSolidClippedSubmodelPolygons (model_t *model)
pbedge[j - 1].pnext = NULL; // mark end of edges
R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf);
R_RecursiveClipBPoly (pbedge,
currententity->visibility.topnode, psurf);
} else {
Sys_Error ("no edges in bmodel");
}
@ -330,7 +334,7 @@ R_DrawSubmodelPolygons (model_t *model, int clipflags)
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
r_currentkey = ((mleaf_t *) currententity->topnode)->key;
r_currentkey = ((mleaf_t *) currententity->visibility.topnode)->key;
// FIXME: use bounding-box-based frustum clipping info?
R_RenderFace (psurf, clipflags);
@ -511,7 +515,7 @@ R_RenderWorld (void)
currententity = &r_worldentity;
VectorCopy (r_origin, modelorg);
brush = &currententity->model->brush;
brush = &currententity->renderer.model->brush;
r_pcurrentvertbase = brush->vertexes;
R_VisitWorldNodes (brush, 15);

View file

@ -353,7 +353,7 @@ R_RenderFace (msurface_t *fa, int clipflags)
vec3_t p_normal;
medge_t *pedges, tedge;
clipplane_t *pclip;
mod_brush_t *brush = &currententity->model->brush;
mod_brush_t *brush = &currententity->renderer.model->brush;
// skip out if no more surfs
if ((surface_p) >= surf_max) {
@ -624,7 +624,7 @@ R_RenderPoly (msurface_t *fa, int clipflags)
polyvert_t pverts[100]; // FIXME: do real number, safely
int vertpage, newverts, newpage, lastvert;
qboolean visible;
mod_brush_t *brush = &currententity->model->brush;
mod_brush_t *brush = &currententity->renderer.model->brush;
// FIXME: clean this up and make it faster
// FIXME: guard against running out of vertices

View file

@ -40,6 +40,7 @@
#include <stdlib.h>
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
@ -231,9 +232,12 @@ R_IQMSetupLighting (entity_t *ent, alight_t *plighting)
r_shadelight *= VID_GRADES;
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct (plighting->plightvec, ent->transform + 0);
r_plightvec[1] = DotProduct (plighting->plightvec, ent->transform + 4);
r_plightvec[2] = DotProduct (plighting->plightvec, ent->transform + 8);
mat4f_t mat;
Transform_GetWorldMatrix (ent->transform, mat);
//FIXME vectorize
r_plightvec[0] = DotProduct (plighting->plightvec, mat[0]);
r_plightvec[1] = DotProduct (plighting->plightvec, mat[1]);
r_plightvec[2] = DotProduct (plighting->plightvec, mat[2]);
}
static void
@ -244,9 +248,11 @@ R_IQMSetUpTransform (int trivial_accept)
static float viewmatrix[3][4];
vec3_t forward, left, up;
VectorCopy (currententity->transform + 0, forward);
VectorCopy (currententity->transform + 4, left);
VectorCopy (currententity->transform + 8, up);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], forward);
VectorCopy (mat[1], left);
VectorCopy (mat[2], up);
// TODO: can do this with simple matrix rearrangement
@ -293,7 +299,7 @@ void
R_IQMDrawModel (alight_t *plighting)
{
entity_t *ent = currententity;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
swiqm_t *sw = (swiqm_t *) iqm->extra_data;
int size;
@ -304,18 +310,19 @@ R_IQMDrawModel (alight_t *plighting)
+ sizeof (finalvert_t) * (iqm->num_verts + 1)
+ sizeof (auxvert_t) * iqm->num_verts;
blend = R_IQMGetLerpedFrames (ent, iqm);
frame = R_IQMBlendPalette (iqm, ent->pose1, ent->pose2, blend, size,
sw->blend_palette, sw->palette_size);
frame = R_IQMBlendPalette (iqm, ent->animation.pose1, ent->animation.pose2,
blend, size, sw->blend_palette,
sw->palette_size);
pfinalverts = (finalvert_t *) &frame[sw->palette_size];
pfinalverts = (finalvert_t *)
(((intptr_t) &pfinalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
pauxverts = (auxvert_t *) &pfinalverts[iqm->num_verts + 1];
R_IQMSetUpTransform (ent->trivial_accept);
R_IQMSetUpTransform (ent->visibility.trivial_accept);
R_IQMSetupLighting (ent, plighting);
r_affinetridesc.drawtype = (ent->trivial_accept == 3) &&
r_affinetridesc.drawtype = (ent->visibility.trivial_accept == 3) &&
r_recursiveaffinetriangles;
//if (!acolormap)
@ -326,7 +333,7 @@ R_IQMDrawModel (alight_t *plighting)
else
ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
if (ent->trivial_accept)
if (ent->visibility.trivial_accept)
R_IQMPrepareUnclippedPoints (iqm, sw, frame);
else
R_IQMPreparePoints (iqm, sw, frame);

View file

@ -42,6 +42,7 @@
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/locs.h"
#include "QF/mathlib.h"
#include "QF/render.h"
@ -167,7 +168,7 @@ R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
mod_brush_t *brush = &worldmodel->brush;
memset (&r_worldentity, 0, sizeof (r_worldentity));
r_worldentity.model = worldmodel;
r_worldentity.renderer.model = worldmodel;
R_FreeAllEntities ();
@ -362,7 +363,7 @@ R_DrawEntitiesOnList (void)
for (ent = r_ent_queue; ent; ent = ent->next) {
currententity = ent;
switch (currententity->model->type) {
switch (currententity->renderer.model->type) {
case mod_sprite:
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
@ -374,15 +375,16 @@ R_DrawEntitiesOnList (void)
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
minlight = max (currententity->model->min_light, currententity->min_light);
minlight = max (currententity->renderer.model->min_light,
currententity->renderer.min_light);
// see if the bounding box lets us trivially reject, also
// sets trivial accept status
currententity->trivial_accept = 0; //FIXME
if (currententity->model->type == mod_iqm//FIXME
currententity->visibility.trivial_accept = 0; //FIXME
if (currententity->renderer.model->type == mod_iqm//FIXME
|| R_AliasCheckBBox ()) {
// 128 instead of 255 due to clamping below
j = max (R_LightPoint (&r_worldentity.model->brush,
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
currententity->origin), minlight * 128);
lighting.ambientlight = j;
@ -407,7 +409,7 @@ R_DrawEntitiesOnList (void)
if (lighting.ambientlight + lighting.shadelight > 192)
lighting.shadelight = 192 - lighting.ambientlight;
if (currententity->model->type == mod_iqm)
if (currententity->renderer.model->type == mod_iqm)
R_IQMDrawModel (&lighting);
else
R_AliasDrawModel (&lighting);
@ -439,7 +441,7 @@ R_DrawViewModel (void)
return;
currententity = vr_data.view_model;
if (!currententity->model)
if (!currententity->renderer.model)
return;
VectorCopy (currententity->origin, r_entorigin);
@ -448,9 +450,10 @@ R_DrawViewModel (void)
VectorCopy (vup, viewlightvec);
VectorNegate (viewlightvec, viewlightvec);
minlight = max (currententity->min_light, currententity->model->min_light);
minlight = max (currententity->renderer.min_light,
currententity->renderer.model->min_light);
j = max (R_LightPoint (&r_worldentity.model->brush,
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
currententity->origin), minlight * 128);
r_viewlighting.ambientlight = j;
@ -489,11 +492,12 @@ R_BmodelCheckBBox (model_t *clmodel, float *minmaxs)
int i, *pindex, clipflags;
vec3_t acceptpt, rejectpt;
double d;
mat4f_t mat;
clipflags = 0;
if (currententity->transform[0] != 1 || currententity->transform[5] != 1
|| currententity->transform[10] != 1) {
Transform_GetWorldMatrix (currententity->transform, mat);
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
for (i = 0; i < 4; i++) {
d = DotProduct (currententity->origin, view_clipplanes[i].normal);
d -= view_clipplanes[i].dist;
@ -556,9 +560,9 @@ R_DrawBEntitiesOnList (void)
for (ent = r_ent_queue; ent; ent = ent->next) {
currententity = ent;
switch (currententity->model->type) {
switch (currententity->renderer.model->type) {
case mod_brush:
clmodel = currententity->model;
clmodel = currententity->renderer.model;
// see if the bounding box lets us trivially reject, also
// sets trivial accept status
@ -606,8 +610,9 @@ R_DrawBEntitiesOnList (void)
if (r_drawpolys | r_drawculledpolys) {
R_ZDrawSubmodelPolys (clmodel);
} else {
if (currententity->topnode) {
mnode_t *topnode = currententity->topnode;
if (currententity->visibility.topnode) {
mnode_t *topnode
= currententity->visibility.topnode;
if (topnode->contents >= 0) {
// not a leaf; has to be clipped to the world
@ -756,7 +761,7 @@ R_RenderView_ (void)
// done in screen.c
R_LowFPPrecision ();
if (!r_worldentity.model)
if (!r_worldentity.renderer.model)
Sys_Error ("R_RenderView: NULL worldmodel");
if (!r_dspeeds->int_val) {

View file

@ -244,7 +244,7 @@ R_SetupFrame (void)
R_SetFrustum ();
// current viewleaf
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
r_dowarpold = r_dowarp;
r_dowarp = r_waterwarp->int_val && (r_viewleaf->contents <=

View file

@ -83,7 +83,7 @@ R_ReadPointFile_f (void)
const char *name;
char *mapname;
mapname = strdup (r_worldentity.model->path);
mapname = strdup (r_worldentity.renderer.model->path);
if (!mapname)
Sys_Error ("Can't duplicate mapname!");
QFS_StripExtension (mapname, mapname);

View file

@ -37,6 +37,7 @@
#include <math.h>
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -246,7 +247,7 @@ R_GetSpriteframe (msprite_t *psprite)
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
frame = currententity->frame;
frame = currententity->animation.frame;
if ((frame >= psprite->numframes) || (frame < 0)) {
Sys_Printf ("R_DrawSprite: no such frame %d\n", frame);
@ -261,7 +262,7 @@ R_GetSpriteframe (msprite_t *psprite)
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
@ -287,7 +288,7 @@ R_DrawSprite (void)
vec3_t tvec;
float dot, angle, sr, cr;
psprite = currententity->model->cache.data;
psprite = currententity->renderer.model->cache.data;
r_spritedesc.pspriteframe = R_GetSpriteframe (psprite);
@ -361,9 +362,11 @@ R_DrawSprite (void)
} else if (psprite->type == SPR_ORIENTED) {
// generate the sprite's axes, according to the sprite's world
// orientation
VectorCopy (currententity->transform + 0, r_spritedesc.vpn);
VectorNegate (currententity->transform + 4, r_spritedesc.vright);
VectorCopy (currententity->transform + 8, r_spritedesc.vup);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], r_spritedesc.vpn);
VectorNegate (mat[1], r_spritedesc.vright);
VectorCopy (mat[2], r_spritedesc.vup);
} else if (psprite->type == SPR_VP_PARALLEL_ORIENTED) {
// generate the sprite's axes, parallel to the viewplane, but rotated
// in that plane around the center according to the sprite entity's

View file

@ -154,7 +154,7 @@ R_BuildLightMap (void)
size = smax * tmax;
lightmap = surf->samples;
if (!r_worldentity.model->brush.lightdata) {
if (!r_worldentity.renderer.model->brush.lightdata) {
for (i = 0; i < size; i++)
blocklights[i] = 0;
return;

View file

@ -31,6 +31,7 @@
#define NH_DEFINE
#include "namehack.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
@ -97,8 +98,8 @@ sw32_R_AliasCheckBBox (void)
int minz;
// expand, rotate, and translate points into worldspace
currententity->trivial_accept = 0;
pmodel = currententity->model;
currententity->visibility.trivial_accept = 0;
pmodel = currententity->renderer.model;
if (!(pahdr = pmodel->aliashdr))
pahdr = Cache_Get (&pmodel->cache);
pmdl = (mdl_t *) ((byte *) pahdr + pahdr->model);
@ -106,7 +107,7 @@ sw32_R_AliasCheckBBox (void)
sw32_R_AliasSetUpTransform (0);
// construct the base bounding box for this frame
frame = currententity->frame;
frame = currententity->animation.frame;
// TODO: don't repeat this check when drawing?
if ((frame >= pmdl->numframes) || (frame < 0)) {
Sys_MaskPrintf (SYS_DEV, "No such frame %d %s\n", frame, pmodel->path);
@ -221,11 +222,11 @@ sw32_R_AliasCheckBBox (void)
return false; // trivial reject off one side
}
currententity->trivial_accept = !anyclip & !zclipped;
currententity->visibility.trivial_accept = !anyclip & !zclipped;
if (currententity->trivial_accept) {
if (currententity->visibility.trivial_accept) {
if (minz > (sw32_r_aliastransition + (pmdl->size * sw32_r_resfudge))) {
currententity->trivial_accept |= 2;
currententity->visibility.trivial_accept |= 2;
}
}
@ -366,9 +367,11 @@ sw32_R_AliasSetUpTransform (int trivial_accept)
static float tmatrix[3][4];
static float viewmatrix[3][4];
VectorCopy (currententity->transform + 0, alias_forward);
VectorNegate (currententity->transform + 4, alias_right);
VectorCopy (currententity->transform + 8, alias_up);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], alias_forward);
VectorNegate (mat[1], alias_right);
VectorCopy (mat[2], alias_up);
tmatrix[0][0] = pmdl->scale[0];
tmatrix[1][1] = pmdl->scale[1];
@ -543,7 +546,7 @@ R_AliasSetupSkin (void)
{
int skinnum;
skinnum = currententity->skinnum;
skinnum = currententity->renderer.skinnum;
if ((skinnum >= pmdl->numskins) || (skinnum < 0)) {
Sys_MaskPrintf (SYS_DEV, "R_AliasSetupSkin: no such skin # %d\n",
skinnum);
@ -559,16 +562,16 @@ R_AliasSetupSkin (void)
sw32_r_affinetridesc.skinheight = pmdl->skinheight;
sw32_acolormap = vid.colormap8;
if (currententity->skin) {
if (currententity->renderer.skin) {
tex_t *base;
base = currententity->skin->texels;
base = currententity->renderer.skin->texels;
if (base) {
sw32_r_affinetridesc.pskin = base->data;
sw32_r_affinetridesc.skinwidth = base->width;
sw32_r_affinetridesc.skinheight = base->height;
}
sw32_acolormap = currententity->skin->colormap;
sw32_acolormap = currententity->renderer.skin->colormap;
}
}
@ -611,7 +614,7 @@ R_AliasSetupFrame (void)
{
maliasframedesc_t *frame;
frame = R_AliasGetFramedesc (currententity->frame, paliashdr);
frame = R_AliasGetFramedesc (currententity->animation.frame, paliashdr);
sw32_r_apverts = (trivertx_t *) ((byte *) paliashdr + frame->frame);
}
@ -624,8 +627,8 @@ sw32_R_AliasDrawModel (alight_t *plighting)
sw32_r_amodels_drawn++;
if (!(paliashdr = currententity->model->aliashdr))
paliashdr = Cache_Get (&currententity->model->cache);
if (!(paliashdr = currententity->renderer.model->aliashdr))
paliashdr = Cache_Get (&currententity->renderer.model->cache);
pmdl = (mdl_t *) ((byte *) paliashdr + paliashdr->model);
size = (CACHE_SIZE - 1)
@ -641,7 +644,7 @@ sw32_R_AliasDrawModel (alight_t *plighting)
sw32_pauxverts = (auxvert_t *) &pfinalverts[pmdl->numverts + 1];
R_AliasSetupSkin ();
sw32_R_AliasSetUpTransform (currententity->trivial_accept);
sw32_R_AliasSetUpTransform (currententity->visibility.trivial_accept);
R_AliasSetupLighting (plighting);
R_AliasSetupFrame ();
@ -663,11 +666,13 @@ sw32_R_AliasDrawModel (alight_t *plighting)
else
sw32_ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
if (currententity->trivial_accept)
if (currententity->visibility.trivial_accept) {
R_AliasPrepareUnclippedPoints ();
else
} else {
R_AliasPreparePoints ();
}
if (!currententity->model->aliashdr)
Cache_Release (&currententity->model->cache);
if (!currententity->renderer.model->aliashdr) {
Cache_Release (&currententity->renderer.model->cache);
}
}

View file

@ -36,6 +36,7 @@
#include "qfalloca.h"
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -80,9 +81,11 @@ R_EntityRotate (vec3_t vec)
void
sw32_R_RotateBmodel (void)
{
VectorCopy (currententity->transform + 0, entity_rotation[0]);
VectorCopy (currententity->transform + 4, entity_rotation[1]);
VectorCopy (currententity->transform + 8, entity_rotation[2]);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], entity_rotation[0]);
VectorCopy (mat[1], entity_rotation[1]);
VectorCopy (mat[2], entity_rotation[2]);
// rotate modelorg and the transformation matrix
R_EntityRotate (modelorg);
@ -300,7 +303,9 @@ sw32_R_DrawSolidClippedSubmodelPolygons (model_t *model)
pbedge[j - 1].pnext = NULL; // mark end of edges
R_RecursiveClipBPoly (pbedge, currententity->topnode, psurf);
R_RecursiveClipBPoly (pbedge,
currententity->visibility.topnode,
psurf);
} else {
Sys_Error ("no edges in bmodel");
}
@ -333,7 +338,8 @@ sw32_R_DrawSubmodelPolygons (model_t *model, int clipflags)
// draw the polygon
if (((psurf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON)) ||
(!(psurf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
sw32_r_currentkey = ((mleaf_t *) currententity->topnode)->key;
sw32_r_currentkey
= ((mleaf_t *) currententity->visibility.topnode)->key;
// FIXME: use bounding-box-based frustum clipping info?
sw32_R_RenderFace (psurf, clipflags);
@ -514,7 +520,7 @@ sw32_R_RenderWorld (void)
currententity = &r_worldentity;
VectorCopy (r_origin, modelorg);
brush = &currententity->model->brush;
brush = &currententity->renderer.model->brush;
r_pcurrentvertbase = brush->vertexes;
R_VisitWorldNodes (brush, 15);

View file

@ -349,7 +349,7 @@ sw32_R_RenderFace (msurface_t *fa, int clipflags)
vec3_t p_normal;
medge_t *pedges, tedge;
clipplane_t *pclip;
mod_brush_t *brush = &currententity->model->brush;
mod_brush_t *brush = &currententity->renderer.model->brush;
// skip out if no more surfs
if ((sw32_surface_p) >= sw32_surf_max) {
@ -622,7 +622,7 @@ sw32_R_RenderPoly (msurface_t *fa, int clipflags)
polyvert_t pverts[100]; // FIXME: do real number, safely
int vertpage, newverts, newpage, lastvert;
qboolean visible;
mod_brush_t *brush = &currententity->model->brush;
mod_brush_t *brush = &currententity->renderer.model->brush;
// FIXME: clean this up and make it faster
// FIXME: guard against running out of vertices

View file

@ -43,6 +43,7 @@
#include "namehack.h"
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
@ -222,9 +223,12 @@ R_IQMSetupLighting (entity_t *ent, alight_t *plighting)
r_shadelight *= VID_GRADES;
// rotate the lighting vector into the model's frame of reference
r_plightvec[0] = DotProduct (plighting->plightvec, ent->transform + 0);
r_plightvec[1] = DotProduct (plighting->plightvec, ent->transform + 4);
r_plightvec[2] = DotProduct (plighting->plightvec, ent->transform + 8);
mat4f_t mat;
Transform_GetWorldMatrix (ent->transform, mat);
//FIXME vectorize
r_plightvec[0] = DotProduct (plighting->plightvec, mat[0]);
r_plightvec[1] = DotProduct (plighting->plightvec, mat[1]);
r_plightvec[2] = DotProduct (plighting->plightvec, mat[2]);
}
static void
@ -235,9 +239,11 @@ R_IQMSetUpTransform (int trivial_accept)
static float viewmatrix[3][4];
vec3_t forward, left, up;
VectorCopy (currententity->transform + 0, forward);
VectorCopy (currententity->transform + 4, left);
VectorCopy (currententity->transform + 8, up);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], forward);
VectorCopy (mat[1], left);
VectorCopy (mat[2], up);
// TODO: can do this with simple matrix rearrangement
@ -284,7 +290,7 @@ void
sw32_R_IQMDrawModel (alight_t *plighting)
{
entity_t *ent = currententity;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
iqm_t *iqm = (iqm_t *) model->aliashdr;
swiqm_t *sw = (swiqm_t *) iqm->extra_data;
int size;
@ -295,7 +301,8 @@ sw32_R_IQMDrawModel (alight_t *plighting)
+ sizeof (finalvert_t) * (iqm->num_verts + 1)
+ sizeof (auxvert_t) * iqm->num_verts;
blend = R_IQMGetLerpedFrames (ent, iqm);
frame = R_IQMBlendPalette (iqm, ent->pose1, ent->pose2, blend, size,
frame = R_IQMBlendPalette (iqm, ent->animation.pose1, ent->animation.pose2,
blend, size,
sw->blend_palette, sw->palette_size);
pfinalverts = (finalvert_t *) &frame[sw->palette_size];
@ -303,7 +310,7 @@ sw32_R_IQMDrawModel (alight_t *plighting)
(((intptr_t) &pfinalverts[0] + CACHE_SIZE - 1) & ~(CACHE_SIZE - 1));
pauxverts = (auxvert_t *) &pfinalverts[iqm->num_verts + 1];
R_IQMSetUpTransform (ent->trivial_accept);
R_IQMSetUpTransform (ent->visibility.trivial_accept);
R_IQMSetupLighting (ent, plighting);
@ -315,7 +322,7 @@ sw32_R_IQMDrawModel (alight_t *plighting)
else
sw32_ziscale = (float) 0x8000 *(float) 0x10000 *3.0;
if (ent->trivial_accept)
if (ent->visibility.trivial_accept)
R_IQMPrepareUnclippedPoints (iqm, sw, frame);
else
R_IQMPreparePoints (iqm, sw, frame);

View file

@ -42,6 +42,7 @@
#include "QF/cmd.h"
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/locs.h"
#include "QF/mathlib.h"
#include "QF/render.h"
@ -183,7 +184,7 @@ sw32_R_NewMap (model_t *worldmodel, struct model_s **models, int num_models)
mod_brush_t *brush = &worldmodel->brush;
memset (&r_worldentity, 0, sizeof (r_worldentity));
r_worldentity.model = worldmodel;
r_worldentity.renderer.model = worldmodel;
R_FreeAllEntities ();
@ -369,7 +370,7 @@ R_DrawEntitiesOnList (void)
for (ent = r_ent_queue; ent; ent = ent->next) {
currententity = ent;
switch (currententity->model->type) {
switch (currententity->renderer.model->type) {
case mod_sprite:
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
@ -381,15 +382,16 @@ R_DrawEntitiesOnList (void)
VectorCopy (currententity->origin, r_entorigin);
VectorSubtract (r_origin, r_entorigin, modelorg);
minlight = max (currententity->min_light, currententity->model->min_light);
minlight = max (currententity->renderer.min_light,
currententity->renderer.model->min_light);
// see if the bounding box lets us trivially reject, also
// sets trivial accept status
currententity->trivial_accept = 0; //FIXME
if (currententity->model->type == mod_iqm//FIXME
currententity->visibility.trivial_accept = 0; //FIXME
if (currententity->renderer.model->type == mod_iqm//FIXME
|| sw32_R_AliasCheckBBox ()) {
// 128 instead of 255 due to clamping below
j = max (R_LightPoint (&r_worldentity.model->brush,
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
currententity->origin),
minlight * 128);
@ -415,7 +417,7 @@ R_DrawEntitiesOnList (void)
if (lighting.ambientlight + lighting.shadelight > 192)
lighting.shadelight = 192 - lighting.ambientlight;
if (currententity->model->type == mod_iqm)
if (currententity->renderer.model->type == mod_iqm)
sw32_R_IQMDrawModel (&lighting);
else
sw32_R_AliasDrawModel (&lighting);
@ -446,7 +448,7 @@ R_DrawViewModel (void)
return;
currententity = vr_data.view_model;
if (!currententity->model)
if (!currententity->renderer.model)
return;
VectorCopy (currententity->origin, r_entorigin);
@ -455,9 +457,10 @@ R_DrawViewModel (void)
VectorCopy (vup, viewlightvec);
VectorNegate (viewlightvec, viewlightvec);
minlight = max (currententity->min_light, currententity->model->min_light);
minlight = max (currententity->renderer.min_light,
currententity->renderer.model->min_light);
j = max (R_LightPoint (&r_worldentity.model->brush,
j = max (R_LightPoint (&r_worldentity.renderer.model->brush,
currententity->origin), minlight * 128);
r_viewlighting.ambientlight = j;
@ -496,11 +499,12 @@ R_BmodelCheckBBox (model_t *clmodel, float *minmaxs)
int i, *pindex, clipflags;
vec3_t acceptpt, rejectpt;
double d;
mat4f_t mat;
clipflags = 0;
if (currententity->transform[0] != 1 || currententity->transform[5] != 1
|| currententity->transform[10] != 1) {
Transform_GetWorldMatrix (currententity->transform, mat);
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
for (i = 0; i < 4; i++) {
d = DotProduct (currententity->origin, sw32_view_clipplanes[i].normal);
d -= sw32_view_clipplanes[i].dist;
@ -563,9 +567,9 @@ R_DrawBEntitiesOnList (void)
for (ent = r_ent_queue; ent; ent = ent->next) {
currententity = ent;
switch (currententity->model->type) {
switch (currententity->renderer.model->type) {
case mod_brush:
clmodel = currententity->model;
clmodel = currententity->renderer.model;
// see if the bounding box lets us trivially reject, also
// sets trivial accept status
@ -613,8 +617,9 @@ R_DrawBEntitiesOnList (void)
if (sw32_r_drawpolys | sw32_r_drawculledpolys) {
sw32_R_ZDrawSubmodelPolys (clmodel);
} else {
if (currententity->topnode) {
mnode_t *topnode = currententity->topnode;
if (currententity->visibility.topnode) {
mnode_t *topnode
= currententity->visibility.topnode;
if (topnode->contents >= 0) {
// not a leaf; has to be clipped to the world
@ -759,7 +764,7 @@ R_RenderView_ (void)
#endif
R_PushDlights (vec3_origin);
if (!r_worldentity.model)
if (!r_worldentity.renderer.model)
Sys_Error ("R_RenderView: NULL worldmodel");
if (!r_dspeeds->int_val) {

View file

@ -240,7 +240,7 @@ sw32_R_SetupFrame (void)
R_SetFrustum ();
// current viewleaf
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
sw32_r_dowarpold = sw32_r_dowarp;
sw32_r_dowarp = r_waterwarp->int_val && (r_viewleaf->contents <=

View file

@ -88,7 +88,7 @@ sw32_R_ReadPointFile_f (void)
const char *name;
char *mapname;
mapname = strdup (r_worldentity.model->path);
mapname = strdup (r_worldentity.renderer.model->path);
if (!mapname)
Sys_Error ("Can't duplicate mapname!");
QFS_StripExtension (mapname, mapname);

View file

@ -40,6 +40,7 @@
#include <math.h>
#include "QF/entity.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -242,7 +243,7 @@ R_GetSpriteframe (msprite_t *psprite)
int i, numframes, frame;
float *pintervals, fullinterval, targettime, time;
frame = currententity->frame;
frame = currententity->animation.frame;
if ((frame >= psprite->numframes) || (frame < 0)) {
Sys_Printf ("R_DrawSprite: no such frame %d\n", frame);
@ -257,7 +258,7 @@ R_GetSpriteframe (msprite_t *psprite)
numframes = pspritegroup->numframes;
fullinterval = pintervals[numframes - 1];
time = vr_data.realtime + currententity->syncbase;
time = vr_data.realtime + currententity->animation.syncbase;
// when loading in Mod_LoadSpriteGroup, we guaranteed all interval
// values are positive, so we don't have to worry about division by 0
@ -283,7 +284,7 @@ sw32_R_DrawSprite (void)
vec3_t tvec;
float dot, angle, sr, cr;
psprite = currententity->model->cache.data;
psprite = currententity->renderer.model->cache.data;
sw32_r_spritedesc.pspriteframe = R_GetSpriteframe (psprite);
@ -357,9 +358,11 @@ sw32_R_DrawSprite (void)
} else if (psprite->type == SPR_ORIENTED) {
// generate the sprite's axes, according to the sprite's world
// orientation
VectorCopy (currententity->transform + 0, sw32_r_spritedesc.vpn);
VectorNegate (currententity->transform + 4, sw32_r_spritedesc.vright);
VectorCopy (currententity->transform + 8, sw32_r_spritedesc.vup);
mat4f_t mat;
Transform_GetWorldMatrix (currententity->transform, mat);
VectorCopy (mat[0], r_spritedesc.vpn);
VectorNegate (mat[1], r_spritedesc.vright);
VectorCopy (mat[2], r_spritedesc.vup);
} else if (psprite->type == SPR_VP_PARALLEL_ORIENTED) {
// generate the sprite's axes, parallel to the viewplane, but rotated
// in that plane around the center according to the sprite entity's

View file

@ -172,7 +172,7 @@ R_BuildLightMap (void)
size = smax * tmax;
lightmap = surf->samples;
if (!r_worldentity.model->brush.lightdata) {
if (!r_worldentity.renderer.model->brush.lightdata) {
for (i = 0; i < size; i++)
blocklights[i] = 0;
return;

View file

@ -45,7 +45,7 @@
#include "QF/cvar.h"
#include "QF/darray.h"
#include "QF/dstring.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/skin.h"
@ -121,36 +121,41 @@ Vulkan_DrawAlias (entity_t *ent, vulkan_ctx_t *ctx)
{
aliasctx_t *actx = ctx->alias_context;
aliasframe_t *aframe = &actx->frames.a[ctx->curFrame];
model_t *model = ent->model;
model_t *model = ent->renderer.model;
aliashdr_t *hdr;
qfv_alias_skin_t *skin;
float vertex_constants[17];
struct {
mat4f_t mat;
float blend;
} vertex_constants;
byte fragment_constants[3][4];
if (!(hdr = model->aliashdr)) {
hdr = Cache_Get (&model->cache);
}
memcpy (vertex_constants, ent->transform, sizeof (ent->transform));
vertex_constants[16] = R_AliasGetLerpedFrames (ent, hdr);
Transform_GetWorldMatrix (ent->transform, vertex_constants.mat);
vertex_constants.blend = R_AliasGetLerpedFrames (ent, hdr);
if (0/*XXX ent->skin && ent->skin->tex*/) {
//skin = ent->skin->tex;
} else {
maliasskindesc_t *skindesc;
skindesc = R_AliasGetSkindesc (ent->skinnum, hdr);
skindesc = R_AliasGetSkindesc (ent->renderer.skinnum, hdr);
skin = (qfv_alias_skin_t *) ((byte *) hdr + skindesc->skin);
}
QuatScale (ent->colormod, 255, fragment_constants[0]);
QuatScale (ent->renderer.colormod, 255, fragment_constants[0]);
QuatCopy (skin->colora, fragment_constants[1]);
QuatCopy (skin->colorb, fragment_constants[2]);
emit_commands (aframe->cmdSet.a[QFV_aliasDepth], ent->pose1, ent->pose2,
0, vertex_constants, sizeof (vertex_constants),
emit_commands (aframe->cmdSet.a[QFV_aliasDepth],
ent->animation.pose1, ent->animation.pose2,
0, &vertex_constants, 17 * sizeof (float),
fragment_constants, sizeof (fragment_constants),
hdr, ctx);
emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer], ent->pose1, ent->pose2,
skin, vertex_constants, sizeof (vertex_constants),
emit_commands (aframe->cmdSet.a[QFV_aliasGBuffer],
ent->animation.pose1, ent->animation.pose2,
skin, &vertex_constants, 17 * sizeof (float),
fragment_constants, sizeof (fragment_constants),
hdr, ctx);
}

View file

@ -45,7 +45,7 @@
#include "QF/cvar.h"
#include "QF/darray.h"
#include "QF/dstring.h"
#include "QF/entity.h"
#include "QF/image.h"
#include "QF/render.h"
#include "QF/sys.h"
@ -275,7 +275,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
{
int i;
model_t *m;
mod_brush_t *brush = &r_worldentity.model->brush;
mod_brush_t *brush = &r_worldentity.renderer.model->brush;
clear_textures (ctx);
init_surface_chains (brush, ctx);
@ -289,7 +289,7 @@ Vulkan_RegisterTextures (model_t **models, int num_models, vulkan_ctx_t *ctx)
if (*m->path == '*')
continue;
// world has already been done, not interested in non-brush models
if (m == r_worldentity.model || m->type != mod_brush)
if (m == r_worldentity.renderer.model || m->type != mod_brush)
continue;
brush = &m->brush;
brush->numsubmodels = 1; // no support for submodels in non-world model
@ -343,7 +343,7 @@ build_surf_displist (model_t **models, msurface_t *fa, int base,
brush = &models[~fa->ec_index]->brush;
} else {
// main or sub model
brush = &r_worldentity.model->brush;
brush = &r_worldentity.renderer.model->brush;
}
vertices = brush->vertexes;
edges = brush->edges;
@ -448,7 +448,7 @@ Vulkan_BuildDisplayLists (model_t **models, int num_models, vulkan_ctx_t *ctx)
}
surf = brush->surfaces + j;
surf->ec_index = dm - brush->submodels;
if (!surf->ec_index && m != r_worldentity.model)
if (!surf->ec_index && m != r_worldentity.renderer.model)
surf->ec_index = -1 - i; // instanced model
tex = surf->texinfo->texture->render;
// append surf to the texture chain
@ -613,9 +613,12 @@ R_DrawBrushModel (entity_t *e, vulkan_ctx_t *ctx)
vec3_t mins, maxs, org;
mod_brush_t *brush;
model = e->model;
model = e->renderer.model;
brush = &model->brush;
if (e->transform[0] != 1 || e->transform[5] != 1 || e->transform[10] != 1) {
mat4f_t mat;
Transform_GetWorldMatrix (e->transform, mat);
memcpy (e->renderer.full_transform, mat, sizeof (mat));//FIXME
if (mat[0][0] != 1 || mat[1][1] != 1 || mat[2][2] != 1) {
rotated = true;
radius = model->radius;
if (R_CullSphere (e->origin, radius))
@ -633,9 +636,9 @@ R_DrawBrushModel (entity_t *e, vulkan_ctx_t *ctx)
vec3_t temp;
VectorCopy (org, temp);
org[0] = DotProduct (temp, e->transform + 0);
org[1] = DotProduct (temp, e->transform + 4);
org[2] = DotProduct (temp, e->transform + 8);
org[0] = DotProduct (temp, mat[0]);
org[1] = DotProduct (temp, mat[1]);
org[2] = DotProduct (temp, mat[2]);
}
// calculate dynamic lighting for bmodel if it's not an instanced model
@ -664,7 +667,8 @@ R_DrawBrushModel (entity_t *e, vulkan_ctx_t *ctx)
// enqueue the polygon
if (((surf->flags & SURF_PLANEBACK) && (dot < -BACKFACE_EPSILON))
|| (!(surf->flags & SURF_PLANEBACK) && (dot > BACKFACE_EPSILON))) {
chain_surface (brush, surf, e->transform, e->colormod, ctx);
chain_surface (brush, surf, e->renderer.full_transform,
e->renderer.colormod, ctx);
}
}
}
@ -1124,10 +1128,10 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
bframe->index_count = 0;
memset (&worldent, 0, sizeof (worldent));
worldent.model = r_worldentity.model;
brush = &r_worldentity.model->brush;
worldent.renderer.model = r_worldentity.renderer.model;
brush = &r_worldentity.renderer.model->brush;
//vulktex_t *tex = r_worldentity.model->skytexture->render;
//vulktex_t *tex = r_worldentity.renderer.model->skytexture->render;
//bctx->skysheet_tex = tex->tex;
currententity = &worldent;
@ -1136,7 +1140,7 @@ Vulkan_DrawWorld (vulkan_ctx_t *ctx)
if (r_drawentities->int_val) {
entity_t *ent;
for (ent = r_ent_queue; ent; ent = ent->next) {
if (ent->model->type != mod_brush)
if (ent->renderer.model->type != mod_brush)
continue;
currententity = ent;

View file

@ -70,7 +70,7 @@ setup_frame (vulkan_ctx_t *ctx)
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
R_SetFrustum ();
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.model);
r_viewleaf = Mod_PointInLeaf (r_origin, r_worldentity.renderer.model);
}
static void
@ -114,7 +114,7 @@ R_RenderEntities (vulkan_ctx_t *ctx)
entity_t *ent; \
int begun = 0; \
for (ent = r_ent_queue; ent; ent = ent->next) { \
if (ent->model->type != mod_##type_name) \
if (ent->renderer.model->type != mod_##type_name) \
continue; \
if (!begun) { \
Vulkan_##Type##Begin (ctx); \
@ -138,7 +138,7 @@ R_DrawViewModel (void)
if (vr_data.inhibit_viewmodel
|| !r_drawviewmodel->int_val
|| !r_drawentities->int_val
|| !currententity->model)
|| !currententity->renderer.model)
return;
// hack the depth range to prevent view model from poking into walls
@ -207,7 +207,7 @@ Vulkan_NewMap (model_t *worldmodel, struct model_s **models, int num_models,
}
memset (&r_worldentity, 0, sizeof (r_worldentity));
r_worldentity.model = worldmodel;
r_worldentity.renderer.model = worldmodel;
// Force a vis update
r_viewleaf = NULL;

View file

@ -45,6 +45,7 @@ nq_cl_plugin_LIBS= \
@client_static_plugin_libs@
nq_client_LIBFILES= \
libs/entity/libQFentity.la \
libs/video/targets/libQFjs.la \
libs/audio/libQFcd.la \
libs/audio/libQFsound.la

View file

@ -32,6 +32,7 @@
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/input.h"
#include "QF/keys.h"
#include "QF/msg.h"
@ -179,41 +180,40 @@ CL_LerpPoint (void)
void
CL_TransformEntity (entity_t *ent, const vec3_t angles, qboolean force)
{
vec3_t ang;
vec_t *forward, *left, *up;
union {
quat_t q;
vec4f_t v;
} rotation;
vec4f_t position;
vec4f_t scale;
VectorCopy (ent->origin, position);
position[3] = 1;
VectorSet (ent->scale, ent->scale, ent->scale, scale);
scale[3] = 1;
if (VectorIsZero (angles)) {
VectorSet (1, 0, 0, ent->transform + 0);
VectorSet (0, 1, 0, ent->transform + 4);
VectorSet (0, 0, 1, ent->transform + 8);
} else if (force || !VectorCompare (angles, ent->angles)) {
forward = ent->transform + 0;
left = ent->transform + 4;
up = ent->transform + 8;
QuatSet (0, 0, 0, 1, rotation.q);
} else {
vec3_t ang;
VectorCopy (angles, ang);
if (ent->model && ent->model->type == mod_alias) {
if (ent->renderer.model && ent->renderer.model->type == mod_alias) {
// stupid quake bug
// why, oh, why, do alias models pitch in the opposite direction
// to everything else?
ang[PITCH] = -ang[PITCH];
}
AngleVectors (ang, forward, left, up);
VectorNegate (left, left); // AngleVectors is right-handed
AngleQuat (ang, rotation.q);
}
VectorCopy (angles, ent->angles);
ent->transform[3] = 0;
ent->transform[7] = 0;
ent->transform[11] = 0;
VectorCopy (ent->origin, ent->transform + 12);
ent->transform[15] = 1;
Transform_SetLocalTransform (ent->transform, scale, rotation.v, position);
}
static void
CL_ModelEffects (entity_t *ent, int num, int glow_color)
{
dlight_t *dl;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
// add automatic particle trails
if (model->flags & EF_ROCKET) {
dl = r_funcs->R_AllocDlight (num);
if (dl) {
@ -250,11 +250,12 @@ CL_EntityEffects (int num, entity_t *ent, entity_state_t *state)
if (state->effects & EF_BRIGHTFIELD)
r_funcs->particles->R_EntityParticles (ent);
if (state->effects & EF_MUZZLEFLASH) {
vec_t *fv = ent->transform;
dl = r_funcs->R_AllocDlight (num);
if (dl) {
VectorMultAdd (ent->origin, 18, fv, dl->origin);
vec4f_t position = Transform_GetWorldPosition (ent->transform);
vec4f_t fv = Transform_Forward (ent->transform);
position += 18 * fv;
VectorCopy (position, dl->origin);
dl->origin[2] += 16;
dl->radius = 200 + (rand () & 31);
dl->die = cl.time + 0.1;
@ -271,19 +272,24 @@ static void
set_entity_model (entity_t *ent, int modelindex)
{
int i = ent - cl_entities;
ent->model = cl.model_precache[modelindex];
renderer_t *renderer = &ent->renderer;
animation_t *animation = &ent->animation;
renderer->model = cl.model_precache[modelindex];
// automatic animation (torches, etc) can be either all together
// or randomized
if (ent->model) {
if (ent->model->synctype == ST_RAND)
ent->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
else
ent->syncbase = 0.0;
if (renderer->model) {
if (renderer->model->synctype == ST_RAND) {
animation->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
} else {
animation->syncbase = 0.0;
}
} else {
cl_forcelink[i] = true; // hack to make null model players work
}
if (i <= cl.maxclients)
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i);
animation->nolerp = 1; // don't try to lerp when the model has changed
if (i <= cl.maxclients) {
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin, i);
}
}
void
@ -291,6 +297,8 @@ CL_RelinkEntities (void)
{
entity_t *ent;
entity_state_t *new, *old;
renderer_t *renderer;
animation_t *animation;
float bobjrotate, frac, f, d;
int i, j;
int entvalid;
@ -326,6 +334,9 @@ CL_RelinkEntities (void)
new = &nq_entstates.frame[0 + cl.mindex][i];
old = &nq_entstates.frame[1 - cl.mindex][i];
ent = &cl_entities[i];
renderer = &ent->renderer;
animation = &ent->animation;
// if the object wasn't included in the last packet, remove it
entvalid = cl_msgtime[i] == cl.mtime[0];
if (entvalid && !new->modelindex) {
@ -334,10 +345,11 @@ CL_RelinkEntities (void)
entvalid = 0;
}
if (!entvalid) {
ent->model = NULL;
ent->pose1 = ent->pose2 = -1;
if (ent->efrag)
renderer->model = NULL;
animation->pose1 = animation->pose2 = -1;
if (ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (ent); // just became empty
}
continue;
}
@ -348,39 +360,43 @@ CL_RelinkEntities (void)
old->modelindex = new->modelindex;
set_entity_model (ent, new->modelindex);
}
ent->frame = new->frame;
animation->frame = new->frame;
if (cl_forcelink[i] || new->colormap != old->colormap) {
old->colormap = new->colormap;
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, new->colormap);
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin,
new->colormap);
}
if (cl_forcelink[i] || new->skinnum != old->skinnum) {
old->skinnum = new->skinnum;
ent->skinnum = new->skinnum;
renderer->skinnum = new->skinnum;
if (i <= cl.maxclients) {
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i);
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin,
i);
mod_funcs->Skin_SetTranslation (i, cl.scores[i - 1].topcolor,
cl.scores[i - 1].bottomcolor);
}
}
ent->scale = new->scale / 16.0;
VectorCopy (ent_colormod[new->colormod], ent->colormod);
ent->colormod[3] = ENTALPHA_DECODE (new->alpha);
VectorCopy (ent_colormod[new->colormod], renderer->colormod);
renderer->colormod[3] = ENTALPHA_DECODE (new->alpha);
model_flags = 0;
if (ent->model)
model_flags = ent->model->flags;
if (renderer->model) {
model_flags = renderer->model->flags;
}
if (cl_forcelink[i]) {
// The entity was not updated in the last message so move to the
// final spot
ent->pose1 = ent->pose2 = -1;
animation->pose1 = animation->pose2 = -1;
VectorCopy (new->origin, ent->origin);
if (!(model_flags & EF_ROTATE))
CL_TransformEntity (ent, new->angles, true);
if (i != cl.viewentity || chase_active->int_val) {
if (ent->efrag)
if (ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (ent);
}
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
}
VectorCopy (ent->origin, ent->old_origin);
@ -395,7 +411,7 @@ CL_RelinkEntities (void)
VectorCopy (new->origin, ent->origin);
if (!(model_flags & EF_ROTATE))
CL_TransformEntity (ent, new->angles, true);
ent->pose1 = ent->pose2 = -1;
animation->pose1 = animation->pose2 = -1;
} else {
vec3_t angles, d;
// interpolate the origin and angles
@ -413,7 +429,7 @@ CL_RelinkEntities (void)
}
}
if (i != cl.viewentity || chase_active->int_val) {
if (ent->efrag) {
if (ent->visibility.efrag) {
if (!VectorCompare (ent->origin, ent->old_origin)) {
r_funcs->R_RemoveEfrags (ent);
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);

View file

@ -403,12 +403,13 @@ CL_PrintEntities_f (void)
for (i = 0, ent = cl_entities; i < cl.num_entities; i++, ent++) {
Sys_Printf ("%3i:", i);
if (!ent->model) {
if (!ent->renderer.model) {
Sys_Printf ("EMPTY\n");
continue;
}
Sys_Printf ("%s:%2i (%5.1f,%5.1f,%5.1f) [%5.1f %5.1f %5.1f]\n",
ent->model->path, ent->frame, VectorExpand (ent->origin),
ent->renderer.model->path, ent->animation.frame,
VectorExpand (ent->origin),
VectorExpand (ent->angles));
}
}

View file

@ -433,7 +433,7 @@ CL_ParseServerInfo (void)
}
// local state
cl_entities[0].model = cl.worldmodel = cl.model_precache[1];
cl_entities[0].renderer.model = cl.worldmodel = cl.model_precache[1];
if (!centerprint)
centerprint = dstring_newstr ();
else
@ -766,9 +766,9 @@ CL_ParseClientdata (void)
cl.stats[STAT_WEAPONFRAME] |= MSG_ReadByte (net_message) << 8;
if (bits & SU_WEAPONALPHA) {
byte alpha = MSG_ReadByte (net_message);
cl.viewent.colormod[3] = ENTALPHA_DECODE (alpha);
cl.viewent.renderer.colormod[3] = ENTALPHA_DECODE (alpha);
} else {
cl.viewent.colormod[3] = 1.0;
cl.viewent.renderer.colormod[3] = 1.0;
}
}
@ -785,12 +785,12 @@ CL_ParseStatic (int version)
// copy it to the current state
//FIXME alpha & lerp
ent->model = cl.model_precache[baseline.modelindex];
ent->frame = baseline.frame;
ent->skin = 0;
ent->skinnum = baseline.skinnum;
VectorCopy (ent_colormod[baseline.colormod], ent->colormod);
ent->colormod[3] = ENTALPHA_DECODE (baseline.alpha);
ent->renderer.model = cl.model_precache[baseline.modelindex];
ent->animation.frame = baseline.frame;
ent->renderer.skin = 0;
ent->renderer.skinnum = baseline.skinnum;
VectorCopy (ent_colormod[baseline.colormod], ent->renderer.colormod);
ent->renderer.colormod[3] = ENTALPHA_DECODE (baseline.alpha);
ent->scale = baseline.scale / 16.0;
VectorCopy (baseline.origin, ent->origin);
CL_TransformEntity (ent, baseline.angles, true);
@ -1024,7 +1024,9 @@ CL_ParseServerMessage (void)
mod_funcs->Skin_SetTranslation (i + 1, top, bot);
cl.scores[i].topcolor = top;
cl.scores[i].bottomcolor = bot;
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, i + 1);
ent->renderer.skin
= mod_funcs->Skin_SetColormap (ent->renderer.skin,
i + 1);
}
break;

View file

@ -38,6 +38,7 @@
#include <math.h>
#include <stdlib.h>
#include "QF/entity.h"
#include "QF/model.h"
#include "QF/msg.h"
#include "QF/sound.h"
@ -132,12 +133,16 @@ CL_TEnts_Init (void)
void
CL_Init_Entity (entity_t *ent)
{
if (ent->transform) {
Transform_Delete (ent->transform);
}
memset (ent, 0, sizeof (*ent));
ent->skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod);
ent->transform = Transform_New (0);
ent->renderer.skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->renderer.colormod);
ent->scale = 1.0;
ent->pose1 = ent->pose2 = -1;
ent->animation.pose1 = ent->animation.pose2 = -1;
}
static tent_t *
@ -150,8 +155,10 @@ new_temp_entity (void)
temp_entities = malloc (TEMP_BATCH * sizeof (tent_t));
for (i = 0; i < TEMP_BATCH - 1; i++) {
temp_entities[i].next = &temp_entities[i + 1];
temp_entities[i].ent.transform = 0;
}
temp_entities[i].next = 0;
temp_entities[i].ent.transform = 0;
}
tent = temp_entities;
temp_entities = tent->next;
@ -208,7 +215,7 @@ CL_ClearTEnts (void)
for (to = cl_beams; to; to = to->next) {
for (t = to->to.beam.tents; t; t = t->next)
t->ent.efrag = 0;
t->ent.visibility.efrag = 0;
free_temp_entities (to->to.beam.tents);
}
free_tent_objects (cl_beams);
@ -216,7 +223,7 @@ CL_ClearTEnts (void)
for (to = cl_explosions; to; to = to->next) {
for (t = to->to.ex.tent; t; t = t->next)
t->ent.efrag = 0;
t->ent.visibility.efrag = 0;
free_temp_entities (to->to.ex.tent);
}
free_tent_objects (cl_explosions);
@ -231,7 +238,7 @@ beam_clear (beam_t *b)
for (t = b->tents; t; t = t->next) {
r_funcs->R_RemoveEfrags (&t->ent);
t->ent.efrag = 0;
t->ent.visibility.efrag = 0;
}
free_temp_entities (b->tents);
b->tents = 0;
@ -285,7 +292,7 @@ beam_setup (beam_t *b, qboolean transform)
VectorMultAdd (org, d, dist, tent->ent.origin);
d += 1.0;
tent->ent.model = b->model;
tent->ent.renderer.model = b->model;
ang[PITCH] = pitch;
ang[YAW] = yaw;
if (transform) {
@ -428,7 +435,7 @@ CL_ParseTEnt (void)
//FIXME need better model management
if (!cl_spr_explod->cache.data)
cl_spr_explod = Mod_ForName ("progs/s_explod.spr", true);
ex->tent->ent.model = cl_spr_explod;
ex->tent->ent.renderer.model = cl_spr_explod;
CL_TransformEntity (&ex->tent->ent, ex->tent->ent.angles, true);
break;
@ -573,10 +580,10 @@ CL_UpdateExplosions (void)
ex = &(*to)->to.ex;
ent = &ex->tent->ent;
f = 10 * (cl.time - ex->start);
if (f >= ent->model->numframes) {
if (f >= ent->renderer.model->numframes) {
tent_obj_t *_to;
r_funcs->R_RemoveEfrags (ent);
ent->efrag = 0;
ent->visibility.efrag = 0;
free_temp_entities (ex->tent);
_to = *to;
*to = _to->next;
@ -586,8 +593,8 @@ CL_UpdateExplosions (void)
}
to = &(*to)->next;
ent->frame = f;
if (!ent->efrag)
ent->animation.frame = f;
if (!ent->visibility.efrag)
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
}
}

View file

@ -614,7 +614,7 @@ V_CalcIntermissionRefdef (void)
VectorCopy (origin, r_data->refdef->vieworg);
VectorCopy (angles, r_data->refdef->viewangles);
view->model = NULL;
view->renderer.model = NULL;
// always idle in intermission
old = v_idlescale->value;
@ -699,9 +699,9 @@ V_CalcRefdef (void)
else if (r_data->scr_viewsize->int_val == 80)
view->origin[2] += 0.5;
view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
view->frame = cl.stats[STAT_WEAPONFRAME];
view->skin = 0;
view->renderer.model = cl.model_precache[cl.stats[STAT_WEAPON]];
view->animation.frame = cl.stats[STAT_WEAPONFRAME];
view->renderer.skin = 0;
// set up the refresh position
VectorAdd (r_data->refdef->viewangles, cl.punchangle,

View file

@ -87,6 +87,7 @@ qw_cl_plugin_LIBS= \
qw_client_LIBS= \
libs/qw/libqw.a \
libs/net/libnet_chan.la \
libs/entity/libQFentity.la \
libs/console/libQFconsole.la \
libs/video/targets/libQFjs.la \
libs/audio/libQFcd.la \

View file

@ -758,17 +758,19 @@ demo_start_recording (int track)
for (ent = cl_static_entities; ent; ent = ent->unext) {
MSG_WriteByte (&buf, svc_spawnstatic);
for (j = 1; j < cl.nummodels; j++)
if (ent->model == cl.model_precache[j])
for (j = 1; j < cl.nummodels; j++) {
if (ent->renderer.model == cl.model_precache[j]) {
break;
}
}
if (j == cl.nummodels)
MSG_WriteByte (&buf, 0);
else
MSG_WriteByte (&buf, j);
MSG_WriteByte (&buf, ent->frame);
MSG_WriteByte (&buf, ent->animation.frame);
MSG_WriteByte (&buf, 0);
MSG_WriteByte (&buf, ent->skinnum);
MSG_WriteByte (&buf, ent->renderer.skinnum);
MSG_WriteCoordAngleV (&buf, ent->origin, ent->angles);
if (buf.cursize > MAX_MSGLEN / 2) {

View file

@ -482,7 +482,7 @@ CL_ParsePlayerinfo (void)
bits = MSG_ReadByte (net_message);
if (bits & PF_ALPHA) {
val = MSG_ReadByte (net_message);
ent->colormod[3] = val / 255.0;
ent->renderer.colormod[3] = val / 255.0;
}
if (bits & PF_SCALE) {
val = MSG_ReadByte (net_message);
@ -505,7 +505,7 @@ CL_ParsePlayerinfo (void)
g = (float) ((val >> 2) & 7) * (1.0 / 7.0);
b = (float) (val & 3) * (1.0 / 3.0);
}
VectorSet (r, g, b, ent->colormod);
VectorSet (r, g, b, ent->renderer.colormod);
}
if (bits & PF_FRAME2) {
state->pls.frame |= MSG_ReadByte (net_message) << 8;

View file

@ -36,6 +36,7 @@
#endif
#include "QF/cvar.h"
#include "QF/entity.h"
#include "QF/locs.h"
#include "QF/msg.h"
#include "QF/render.h"
@ -172,40 +173,38 @@ is_gib (entity_state_t *s1)
void
CL_TransformEntity (entity_t *ent, const vec3_t angles, qboolean force)
{
vec3_t ang;
vec_t *forward, *left, *up;
union {
quat_t q;
vec4f_t v;
} rotation;
vec4f_t position;
vec4f_t scale;
VectorCopy (ent->origin, position);
position[3] = 1;
VectorSet (ent->scale, ent->scale, ent->scale, scale);
scale[3] = 1;
if (VectorIsZero (angles)) {
VectorSet (1, 0, 0, ent->transform + 0);
VectorSet (0, 1, 0, ent->transform + 4);
VectorSet (0, 0, 1, ent->transform + 8);
} else if (force || !VectorCompare (angles, ent->angles)) {
forward = ent->transform + 0;
left = ent->transform + 4;
up = ent->transform + 8;
QuatSet (0, 0, 0, 1, rotation.q);
} else {
vec3_t ang;
VectorCopy (angles, ang);
if (ent->model && ent->model->type == mod_alias) {
if (ent->renderer.model && ent->renderer.model->type == mod_alias) {
// stupid quake bug
// why, oh, why, do alias models pitch in the opposite direction
// to everything else?
ang[PITCH] = -ang[PITCH];
}
AngleVectors (ang, forward, left, up);
VectorNegate (left, left); // AngleVectors is right-handed
AngleQuat (ang, rotation.q);
}
VectorCopy (angles, ent->angles);
ent->transform[3] = 0;
ent->transform[7] = 0;
ent->transform[11] = 0;
VectorCopy (ent->origin, ent->transform + 12);
ent->transform[15] = 1;
Transform_SetLocalTransform (ent->transform, scale, rotation.v, position);
}
static void
CL_ModelEffects (entity_t *ent, int num, int glow_color)
{
dlight_t *dl;
model_t *model = ent->model;
model_t *model = ent->renderer.model;
// add automatic particle trails
if (model->flags & EF_ROCKET) {
@ -239,14 +238,17 @@ CL_ModelEffects (entity_t *ent, int num, int glow_color)
static void
set_entity_model (entity_t *ent, int modelindex)
{
ent->model = cl.model_precache[modelindex];
renderer_t *renderer = &ent->renderer;
animation_t *animation = &ent->animation;
renderer->model = cl.model_precache[modelindex];
// automatic animation (torches, etc) can be either all together
// or randomized
if (ent->model) {
if (ent->model->synctype == ST_RAND)
ent->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
else
ent->syncbase = 0.0;
if (renderer->model) {
if (renderer->model->synctype == ST_RAND) {
animation->syncbase = (float) (rand () & 0x7fff) / 0x7fff;
} else {
animation->syncbase = 0.0;
}
}
}
@ -257,6 +259,8 @@ CL_LinkPacketEntities (void)
float frac, f;
entity_t *ent;
entity_state_t *new, *old;
renderer_t *renderer;
animation_t *animation;
vec3_t delta;
frac = 1;
@ -264,14 +268,17 @@ CL_LinkPacketEntities (void)
new = &qw_entstates.frame[cl.link_sequence & UPDATE_MASK][i];
old = &qw_entstates.frame[cl.prev_sequence & UPDATE_MASK][i];
ent = &cl_entities[i];
renderer = &ent->renderer;
animation = &ent->animation;
forcelink = cl_entity_valid[0][i] != cl_entity_valid[1][i];
cl_entity_valid[1][i] = cl_entity_valid[0][i];
// if the object wasn't included in the last packet, remove it
if (!cl_entity_valid[0][i]) {
ent->model = NULL;
ent->pose1 = ent->pose2 = -1;
if (ent->efrag)
renderer->model = NULL;
animation->pose1 = animation->pose2 = -1;
if (ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (ent); // just became empty
}
continue;
}
@ -283,8 +290,9 @@ CL_LinkPacketEntities (void)
if (!new->modelindex
|| (cl_deadbodyfilter->int_val && is_dead_body (new))
|| (cl_gibfilter->int_val && is_gib (new))) {
if (ent->efrag)
if (ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (ent);
}
continue;
}
@ -295,46 +303,50 @@ CL_LinkPacketEntities (void)
old->modelindex = new->modelindex;
set_entity_model (ent, new->modelindex);
}
ent->frame = new->frame;
animation->frame = new->frame;
if (forcelink || new->colormap != old->colormap
|| new->skinnum != old->skinnum) {
old->skinnum = new->skinnum;
ent->skinnum = new->skinnum;
renderer->skinnum = new->skinnum;
old->colormap = new->colormap;
if (new->colormap && (new->colormap <= MAX_CLIENTS)
&& cl.players[new->colormap - 1].name
&& cl.players[new->colormap - 1].name->value[0]
&& new->modelindex == cl_playerindex) {
player_info_t *player = &cl.players[new->colormap - 1];
ent->skin = mod_funcs->Skin_SetSkin (ent->skin, new->colormap,
player->skinname->value);
ent->skin = mod_funcs->Skin_SetColormap (ent->skin,
new->colormap);
renderer->skin
= mod_funcs->Skin_SetSkin (renderer->skin, new->colormap,
player->skinname->value);
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin,
new->colormap);
} else {
ent->skin = mod_funcs->Skin_SetColormap (ent->skin, 0);
renderer->skin = mod_funcs->Skin_SetColormap (renderer->skin,
0);
}
}
ent->scale = new->scale / 16.0;
VectorCopy (ent_colormod[new->colormod], ent->colormod);
ent->colormod[3] = new->alpha / 255.0;
VectorCopy (ent_colormod[new->colormod], renderer->colormod);
renderer->colormod[3] = new->alpha / 255.0;
ent->min_light = 0;
ent->fullbright = 0;
renderer->min_light = 0;
renderer->fullbright = 0;
if (new->modelindex == cl_playerindex) {
ent->min_light = min (cl.fbskins, cl_fb_players->value);
if (ent->min_light >= 1.0)
ent->fullbright = 1;
renderer->min_light = min (cl.fbskins, cl_fb_players->value);
if (renderer->min_light >= 1.0) {
renderer->fullbright = 1;
}
}
if (forcelink) {
ent->pose1 = ent->pose2 = -1;
animation->pose1 = animation->pose2 = -1;
VectorCopy (new->origin, ent->origin);
if (!(ent->model->flags & EF_ROTATE))
if (!(renderer->model->flags & EF_ROTATE))
CL_TransformEntity (ent, new->angles, true);
if (i != cl.viewentity || chase_active->int_val) {
if (ent->efrag)
if (ent->visibility.efrag) {
r_funcs->R_RemoveEfrags (ent);
}
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
}
VectorCopy (ent->origin, ent->old_origin);
@ -347,14 +359,15 @@ CL_LinkPacketEntities (void)
|| fabs (delta[2]) > 100) {
// assume a teleportation, not a motion
VectorCopy (new->origin, ent->origin);
if (!(ent->model->flags & EF_ROTATE))
if (!(renderer->model->flags & EF_ROTATE)) {
CL_TransformEntity (ent, new->angles, true);
ent->pose1 = ent->pose2 = -1;
}
animation->pose1 = animation->pose2 = -1;
} else {
vec3_t angles, d;
// interpolate the origin and angles
VectorMultAdd (old->origin, f, delta, ent->origin);
if (!(ent->model->flags & EF_ROTATE)) {
if (!(renderer->model->flags & EF_ROTATE)) {
VectorSubtract (new->angles, old->angles, d);
for (j = 0; j < 3; j++) {
if (d[j] > 180)
@ -367,7 +380,7 @@ CL_LinkPacketEntities (void)
}
}
if (i != cl.viewentity || chase_active->int_val) {
if (ent->efrag) {
if (ent->visibility.efrag) {
if (!VectorCompare (ent->origin, ent->old_origin)) {
r_funcs->R_RemoveEfrags (ent);
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
@ -377,11 +390,12 @@ CL_LinkPacketEntities (void)
}
}
}
if (!ent->efrag)
if (!ent->visibility.efrag) {
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
}
// rotate binary objects locally
if (ent->model->flags & EF_ROTATE) {
if (renderer->model->flags & EF_ROTATE) {
vec3_t angles;
angles[PITCH] = 0;
angles[YAW] = anglemod (100 * cl.time);
@ -392,8 +406,9 @@ CL_LinkPacketEntities (void)
//CL_NewDlight (i, ent->origin, new->effects, 0, 0);
if (VectorDistance_fast (old->origin, ent->origin) > (256 * 256))
VectorCopy (ent->origin, old->origin);
if (ent->model->flags & ~EF_ROTATE)
if (renderer->model->flags & ~EF_ROTATE) {
CL_ModelEffects (ent, -new->number, new->glow_color);
}
}
}
@ -414,36 +429,40 @@ CL_AddFlagModels (entity_t *ent, int team, int key)
};
float f;
entity_t *fent;
vec_t *v_forward, *v_left;
vec3_t ang;
if (cl_flagindex == -1)
return;
f = 14.0;
if (ent->frame >= 29 && ent->frame <= 40) {
f = flag_offsets[ent->frame - 29];
} else if (ent->frame >= 103 && ent->frame <= 118) {
if (ent->frame <= 106) // 103-104 nailattack
f = 20.0; // 105-106 light
else // 107-112 rocketattack
f = 21.0; // 112-118 shotattack
}
fent = &cl_flag_ents[key];
fent->model = cl.model_precache[cl_flagindex];
fent->skinnum = team;
v_forward = ent->transform + 0;
v_left = ent->transform + 4;
if (cl_flagindex == -1) {
fent->active = 0;
return;
}
VectorMultAdd (ent->origin, -f, v_forward, fent->origin);
VectorMultAdd (fent->origin, -22, v_left, fent->origin);
fent->origin[2] -= 16.0;
fent->active = 1;
f = 14.0;
if (ent->animation.frame >= 29 && ent->animation.frame <= 40) {
f = flag_offsets[ent->animation.frame - 29];
} else if (ent->animation.frame >= 103 && ent->animation.frame <= 118) {
if (ent->animation.frame <= 106) { // 103-104 nailattack
f = 20.0; // 105-106 light
} else { // 107-112 rocketattack
f = 21.0; // 112-118 shotattack
}
}
VectorCopy (ent->angles, ang);
ang[2] -= 45.0;
CL_TransformEntity (fent, ang, false);
vec4f_t position = { 22, -f, -16, 1};
if (!Transform_GetParent (fent->transform)) {
vec4f_t scale = { 1, 1, 1, 1 };
// -45 degree roll (x is forward)
vec4f_t rotation = { -0.382683432, 0, 0, 0.923879533 };
Transform_SetParent (fent->transform, ent->transform);
Transform_SetLocalTransform (fent->transform, scale, rotation,
position);
} else {
Transform_SetLocalPosition (fent->transform, position);
}
fent->renderer.model = cl.model_precache[cl_flagindex];
fent->renderer.skinnum = team;
r_funcs->R_EnqueueEntity (fent);//FIXME should use efrag (needs smarter
// handling //in the player code)
@ -477,7 +496,7 @@ CL_LinkPlayers (void)
for (j = 0, info = cl.players, state = frame->playerstate; j < MAX_CLIENTS;
j++, info++, state++) {
ent = &cl_player_ents[j];
if (ent->efrag)
if (ent->visibility.efrag)
r_funcs->R_RemoveEfrags (ent);
if (state->messagenum != cl.parsecount)
continue; // not present this frame
@ -544,26 +563,27 @@ CL_LinkPlayers (void)
}
ang[ROLL] = V_CalcRoll (ang, state->pls.velocity) * 4.0;
ent->model = cl.model_precache[state->pls.modelindex];
ent->frame = state->pls.frame;
ent->skinnum = state->pls.skinnum;
ent->renderer.model = cl.model_precache[state->pls.modelindex];
ent->animation.frame = state->pls.frame;
ent->renderer.skinnum = state->pls.skinnum;
CL_TransformEntity (ent, ang, false);
ent->min_light = 0;
ent->fullbright = 0;
ent->renderer.min_light = 0;
ent->renderer.fullbright = 0;
if (state->pls.modelindex == cl_playerindex) { //XXX
// use custom skin
ent->skin = info->skin;
ent->renderer.skin = info->skin;
ent->min_light = min (cl.fbskins, cl_fb_players->value);
ent->renderer.min_light = min (cl.fbskins, cl_fb_players->value);
if (ent->min_light >= 1.0)
ent->fullbright = 1;
if (ent->renderer.min_light >= 1.0) {
ent->renderer.fullbright = 1;
}
} else {
// FIXME no team colors on nonstandard player models
ent->skin = 0;
ent->renderer.skin = 0;
}
// stuff entity in map

View file

@ -979,9 +979,9 @@ CL_ParseStatic (void)
cl_static_tail = &ent->unext;
// copy it to the current state
ent->model = cl.model_precache[es.modelindex];
ent->frame = es.frame;
ent->skinnum = es.skinnum;
ent->renderer.model = cl.model_precache[es.modelindex];
ent->animation.frame = es.frame;
ent->renderer.skinnum = es.skinnum;
VectorCopy (es.origin, ent->origin);
CL_TransformEntity (ent, es.angles, true);

View file

@ -39,6 +39,7 @@
#include <stdlib.h>
#include "QF/console.h"
#include "QF/entity.h"
#include "QF/model.h"
#include "QF/msg.h"
#include "QF/sound.h"
@ -136,12 +137,16 @@ CL_TEnts_Init (void)
void
CL_Init_Entity (entity_t *ent)
{
if (ent->transform) {
Transform_Delete (ent->transform);
}
memset (ent, 0, sizeof (*ent));
ent->skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->colormod);
ent->transform = Transform_New (0);
ent->renderer.skin = 0;
QuatSet (1.0, 1.0, 1.0, 1.0, ent->renderer.colormod);
ent->scale = 1.0;
ent->pose1 = ent->pose2 = -1;
ent->animation.pose1 = ent->animation.pose2 = -1;
}
static tent_t *
@ -154,8 +159,10 @@ new_temp_entity (void)
temp_entities = malloc (TEMP_BATCH * sizeof (tent_t));
for (i = 0; i < TEMP_BATCH - 1; i++) {
temp_entities[i].next = &temp_entities[i + 1];
temp_entities[i].ent.transform = 0;
}
temp_entities[i].next = 0;
temp_entities[i].ent.transform = 0;
}
tent = temp_entities;
temp_entities = tent->next;
@ -211,16 +218,18 @@ CL_ClearTEnts (void)
tent_obj_t *to;
for (to = cl_beams; to; to = to->next) {
for (t = to->to.beam.tents; t; t = t->next)
t->ent.efrag = 0;
for (t = to->to.beam.tents; t; t = t->next) {
t->ent.visibility.efrag = 0;
}
free_temp_entities (to->to.beam.tents);
}
free_tent_objects (cl_beams);
cl_beams = 0;
for (to = cl_explosions; to; to = to->next) {
for (t = to->to.ex.tent; t; t = t->next)
t->ent.efrag = 0;
for (t = to->to.ex.tent; t; t = t->next) {
t->ent.visibility.efrag = 0;
}
free_temp_entities (to->to.ex.tent);
}
free_tent_objects (cl_explosions);
@ -235,7 +244,7 @@ beam_clear (beam_t *b)
for (t = b->tents; t; t = t->next) {
r_funcs->R_RemoveEfrags (&t->ent);
t->ent.efrag = 0;
t->ent.visibility.efrag = 0;
}
free_temp_entities (b->tents);
b->tents = 0;
@ -289,7 +298,7 @@ beam_setup (beam_t *b, qboolean transform)
VectorMultAdd (org, d, dist, tent->ent.origin);
d += 1.0;
tent->ent.model = b->model;
tent->ent.renderer.model = b->model;
ang[PITCH] = pitch;
ang[YAW] = yaw;
if (transform) {
@ -432,7 +441,7 @@ CL_ParseTEnt (void)
//FIXME need better model management
if (!cl_spr_explod->cache.data)
cl_spr_explod = Mod_ForName ("progs/s_explod.spr", true);
ex->tent->ent.model = cl_spr_explod;
ex->tent->ent.renderer.model = cl_spr_explod;
CL_TransformEntity (&ex->tent->ent, ex->tent->ent.angles, true);
break;
@ -580,10 +589,10 @@ CL_UpdateExplosions (void)
ex = &(*to)->to.ex;
ent = &ex->tent->ent;
f = 10 * (cl.time - ex->start);
if (f >= ent->model->numframes) {
if (f >= ent->renderer.model->numframes) {
tent_obj_t *_to;
r_funcs->R_RemoveEfrags (ent);
ent->efrag = 0;
ent->visibility.efrag = 0;
free_temp_entities (ex->tent);
_to = *to;
*to = _to->next;
@ -593,9 +602,10 @@ CL_UpdateExplosions (void)
}
to = &(*to)->next;
ent->frame = f;
if (!ent->efrag)
ent->animation.frame = f;
if (!ent->visibility.efrag) {
r_funcs->R_AddEfrags (&cl.worldmodel->brush, ent);
}
}
}
@ -613,7 +623,7 @@ CL_ClearProjectiles (void)
for (tent = cl_projectiles; tent; tent = tent->next) {
r_funcs->R_RemoveEfrags (&tent->ent);
tent->ent.efrag = 0;
tent->ent.visibility.efrag = 0;
}
free_temp_entities (cl_projectiles);
cl_projectiles = 0;
@ -648,8 +658,8 @@ CL_ParseProjectiles (qboolean nail2)
tail = &tent->next;
pr = &tent->ent;
pr->model = cl.model_precache[cl_spikeindex];
pr->skin = 0;
pr->renderer.model = cl.model_precache[cl_spikeindex];
pr->renderer.skin = 0;
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;

View file

@ -617,7 +617,7 @@ V_CalcIntermissionRefdef (void)
VectorCopy (origin, r_data->refdef->vieworg);
VectorCopy (angles, r_data->refdef->viewangles);
view->model = NULL;
view->renderer.model = NULL;
// always idle in intermission
old = v_idlescale->value;
@ -700,12 +700,13 @@ V_CalcRefdef (void)
else if (r_data->scr_viewsize->int_val == 80)
view->origin[2] += 0.5;
if (view_message->pls.flags & (PF_GIB | PF_DEAD))
view->model = NULL;
else
view->model = cl.model_precache[cl.stats[STAT_WEAPON]];
view->frame = view_message->pls.weaponframe;
view->skin = 0;
if (view_message->pls.flags & (PF_GIB | PF_DEAD)) {
view->renderer.model = NULL;
} else {
view->renderer.model = cl.model_precache[cl.stats[STAT_WEAPON]];
}
view->animation.frame = view_message->pls.weaponframe;
view->renderer.skin = 0;
// set up the refresh position
VectorAdd (r_data->refdef->viewangles, cl.punchangle,

View file

@ -65,6 +65,7 @@ qwaq_cl_plugin_libs= \
@client_static_plugin_libs@
qwaq_client_libs= \
$(top_builddir)/libs/entity/libQFentity.la \
$(top_builddir)/libs/console/libQFconsole.la \
$(top_builddir)/libs/video/targets/libQFjs.la \
$(top_builddir)/libs/audio/libQFcd.la \