diff --git a/include/QF/entity.h b/include/QF/entity.h index 9bf676190..032db67a2 100644 --- a/include/QF/entity.h +++ b/include/QF/entity.h @@ -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)); diff --git a/include/QF/render.h b/include/QF/render.h index 607b8b800..d6a871865 100644 --- a/include/QF/render.h +++ b/include/QF/render.h @@ -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 diff --git a/include/r_local.h b/include/r_local.h index 9e56b7343..37d5308c1 100644 --- a/include/r_local.h +++ b/include/r_local.h @@ -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); diff --git a/libs/entity/transform.c b/libs/entity/transform.c index 18382e56c..0e274f83a 100644 --- a/libs/entity/transform.c +++ b/libs/entity/transform.c @@ -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 diff --git a/libs/video/renderer/gl/gl_dyn_part.c b/libs/video/renderer/gl/gl_dyn_part.c index 5f510b26c..5aa093813 100644 --- a/libs/video/renderer/gl/gl_dyn_part.c +++ b/libs/video/renderer/gl/gl_dyn_part.c @@ -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); diff --git a/libs/video/renderer/gl/gl_lightmap.c b/libs/video/renderer/gl/gl_lightmap.c index c6270f5d4..d46c35014 100644 --- a/libs/video/renderer/gl/gl_lightmap.c +++ b/libs/video/renderer/gl/gl_lightmap.c @@ -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)) diff --git a/libs/video/renderer/gl/gl_mod_alias.c b/libs/video/renderer/gl/gl_mod_alias.c index d47a1504f..4b90ba54a 100644 --- a/libs/video/renderer/gl/gl_mod_alias.c +++ b/libs/video/renderer/gl/gl_mod_alias.c @@ -43,6 +43,7 @@ #include #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); + } } diff --git a/libs/video/renderer/gl/gl_mod_iqm.c b/libs/video/renderer/gl/gl_mod_iqm.c index 4c50795b7..601a76fbf 100644 --- a/libs/video/renderer/gl/gl_mod_iqm.c +++ b/libs/video/renderer/gl/gl_mod_iqm.c @@ -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); diff --git a/libs/video/renderer/gl/gl_mod_sprite.c b/libs/video/renderer/gl/gl_mod_sprite.c index c5b484ed7..b6ce25f22 100644 --- a/libs/video/renderer/gl/gl_mod_sprite.c +++ b/libs/video/renderer/gl/gl_mod_sprite.c @@ -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; diff --git a/libs/video/renderer/gl/gl_rmain.c b/libs/video/renderer/gl/gl_rmain.c index 1f9b30696..23d7f7be4 100644 --- a/libs/video/renderer/gl/gl_rmain.c +++ b/libs/video/renderer/gl/gl_rmain.c @@ -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 (); diff --git a/libs/video/renderer/gl/gl_rmisc.c b/libs/video/renderer/gl/gl_rmisc.c index 5c61fd70d..d9a1c6797 100644 --- a/libs/video/renderer/gl/gl_rmisc.c +++ b/libs/video/renderer/gl/gl_rmisc.c @@ -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); } } diff --git a/libs/video/renderer/gl/gl_rsurf.c b/libs/video/renderer/gl/gl_rsurf.c index acd9f4ad3..b954fc066 100644 --- a/libs/video/renderer/gl/gl_rsurf.c +++ b/libs/video/renderer/gl/gl_rsurf.c @@ -45,6 +45,7 @@ #include #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); diff --git a/libs/video/renderer/glsl/glsl_alias.c b/libs/video/renderer/glsl/glsl_alias.c index 3cbf4f89d..e0c29cfe4 100644 --- a/libs/video/renderer/glsl/glsl_alias.c +++ b/libs/video/renderer/glsl/glsl_alias.c @@ -43,6 +43,7 @@ #include #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); diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index 3b5ed0cd4..3fc716cf8 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -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; diff --git a/libs/video/renderer/glsl/glsl_iqm.c b/libs/video/renderer/glsl/glsl_iqm.c index ce2c2f31d..76a9ae85e 100644 --- a/libs/video/renderer/glsl/glsl_iqm.c +++ b/libs/video/renderer/glsl/glsl_iqm.c @@ -43,6 +43,7 @@ #include #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); diff --git a/libs/video/renderer/glsl/glsl_main.c b/libs/video/renderer/glsl/glsl_main.c index 32688b2ae..ba8c2dce7 100644 --- a/libs/video/renderer/glsl/glsl_main.c +++ b/libs/video/renderer/glsl/glsl_main.c @@ -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; diff --git a/libs/video/renderer/glsl/glsl_particles.c b/libs/video/renderer/glsl/glsl_particles.c index 139423bb7..eb7eccb6d 100644 --- a/libs/video/renderer/glsl/glsl_particles.c +++ b/libs/video/renderer/glsl/glsl_particles.c @@ -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; diff --git a/libs/video/renderer/glsl/glsl_sprite.c b/libs/video/renderer/glsl/glsl_sprite.c index c0acdc078..7582e9db3 100644 --- a/libs/video/renderer/glsl/glsl_sprite.c +++ b/libs/video/renderer/glsl/glsl_sprite.c @@ -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 diff --git a/libs/video/renderer/r_alias.c b/libs/video/renderer/r_alias.c index aa1541ca2..b956f0500 100644 --- a/libs/video/renderer/r_alias.c +++ b/libs/video/renderer/r_alias.c @@ -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); } diff --git a/libs/video/renderer/r_bsp.c b/libs/video/renderer/r_bsp.c index 47b78a643..03af6696b 100644 --- a/libs/video/renderer/r_bsp.c +++ b/libs/video/renderer/r_bsp.c @@ -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; } diff --git a/libs/video/renderer/r_efrag.c b/libs/video/renderer/r_efrag.c index cbfd0d2c8..86d494b6d 100644 --- a/libs/video/renderer/r_efrag.c +++ b/libs/video/renderer/r_efrag.c @@ -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; diff --git a/libs/video/renderer/r_ent.c b/libs/video/renderer/r_ent.c index e72d10399..5a20bcb1f 100644 --- a/libs/video/renderer/r_ent.c +++ b/libs/video/renderer/r_ent.c @@ -38,6 +38,7 @@ #include #include +#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; diff --git a/libs/video/renderer/r_iqm.c b/libs/video/renderer/r_iqm.c index 224182a79..71dc47b3a 100644 --- a/libs/video/renderer/r_iqm.c +++ b/libs/video/renderer/r_iqm.c @@ -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); diff --git a/libs/video/renderer/r_light.c b/libs/video/renderer/r_light.c index 8d3294c37..96899621e 100644 --- a/libs/video/renderer/r_light.c +++ b/libs/video/renderer/r_light.c @@ -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); } } diff --git a/libs/video/renderer/sw/sw_ralias.c b/libs/video/renderer/sw/sw_ralias.c index d28e41b04..1fcd1ce12 100644 --- a/libs/video/renderer/sw/sw_ralias.c +++ b/libs/video/renderer/sw/sw_ralias.c @@ -30,6 +30,7 @@ #include +#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 (¤tentity->model->cache); + if (!(paliashdr = currententity->renderer.model->aliashdr)) + paliashdr = Cache_Get (¤tentity->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 (¤tentity->model->cache); + if (!currententity->renderer.model->aliashdr) { + Cache_Release (¤tentity->renderer.model->cache); + } } diff --git a/libs/video/renderer/sw/sw_rbsp.c b/libs/video/renderer/sw/sw_rbsp.c index 7cf001b87..e9b3fde8a 100644 --- a/libs/video/renderer/sw/sw_rbsp.c +++ b/libs/video/renderer/sw/sw_rbsp.c @@ -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 = ¤tentity->model->brush; + brush = ¤tentity->renderer.model->brush; r_pcurrentvertbase = brush->vertexes; R_VisitWorldNodes (brush, 15); diff --git a/libs/video/renderer/sw/sw_rdraw.c b/libs/video/renderer/sw/sw_rdraw.c index 3f460643d..67c298187 100644 --- a/libs/video/renderer/sw/sw_rdraw.c +++ b/libs/video/renderer/sw/sw_rdraw.c @@ -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 = ¤tentity->model->brush; + mod_brush_t *brush = ¤tentity->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 = ¤tentity->model->brush; + mod_brush_t *brush = ¤tentity->renderer.model->brush; // FIXME: clean this up and make it faster // FIXME: guard against running out of vertices diff --git a/libs/video/renderer/sw/sw_riqm.c b/libs/video/renderer/sw/sw_riqm.c index 285342b3f..8674e3ca6 100644 --- a/libs/video/renderer/sw/sw_riqm.c +++ b/libs/video/renderer/sw/sw_riqm.c @@ -40,6 +40,7 @@ #include #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); diff --git a/libs/video/renderer/sw/sw_rmain.c b/libs/video/renderer/sw/sw_rmain.c index 573827bda..7cf5416c0 100644 --- a/libs/video/renderer/sw/sw_rmain.c +++ b/libs/video/renderer/sw/sw_rmain.c @@ -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) { diff --git a/libs/video/renderer/sw/sw_rmisc.c b/libs/video/renderer/sw/sw_rmisc.c index b2272ff14..dee5c780e 100644 --- a/libs/video/renderer/sw/sw_rmisc.c +++ b/libs/video/renderer/sw/sw_rmisc.c @@ -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 <= diff --git a/libs/video/renderer/sw/sw_rpart.c b/libs/video/renderer/sw/sw_rpart.c index a5be06453..d154ad739 100644 --- a/libs/video/renderer/sw/sw_rpart.c +++ b/libs/video/renderer/sw/sw_rpart.c @@ -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); diff --git a/libs/video/renderer/sw/sw_rsprite.c b/libs/video/renderer/sw/sw_rsprite.c index 4ee5d74c3..8eb4151e7 100644 --- a/libs/video/renderer/sw/sw_rsprite.c +++ b/libs/video/renderer/sw/sw_rsprite.c @@ -37,6 +37,7 @@ #include +#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 diff --git a/libs/video/renderer/sw/sw_rsurf.c b/libs/video/renderer/sw/sw_rsurf.c index 5133118cb..1dded8c00 100644 --- a/libs/video/renderer/sw/sw_rsurf.c +++ b/libs/video/renderer/sw/sw_rsurf.c @@ -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; diff --git a/libs/video/renderer/sw32/sw32_ralias.c b/libs/video/renderer/sw32/sw32_ralias.c index 4ead8055a..1dacb5bc7 100644 --- a/libs/video/renderer/sw32/sw32_ralias.c +++ b/libs/video/renderer/sw32/sw32_ralias.c @@ -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 (¤tentity->model->cache); + if (!(paliashdr = currententity->renderer.model->aliashdr)) + paliashdr = Cache_Get (¤tentity->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 (¤tentity->model->cache); + if (!currententity->renderer.model->aliashdr) { + Cache_Release (¤tentity->renderer.model->cache); + } } diff --git a/libs/video/renderer/sw32/sw32_rbsp.c b/libs/video/renderer/sw32/sw32_rbsp.c index 521e70cd5..1f62b381e 100644 --- a/libs/video/renderer/sw32/sw32_rbsp.c +++ b/libs/video/renderer/sw32/sw32_rbsp.c @@ -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 = ¤tentity->model->brush; + brush = ¤tentity->renderer.model->brush; r_pcurrentvertbase = brush->vertexes; R_VisitWorldNodes (brush, 15); diff --git a/libs/video/renderer/sw32/sw32_rdraw.c b/libs/video/renderer/sw32/sw32_rdraw.c index b106ab63a..7c1e696be 100644 --- a/libs/video/renderer/sw32/sw32_rdraw.c +++ b/libs/video/renderer/sw32/sw32_rdraw.c @@ -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 = ¤tentity->model->brush; + mod_brush_t *brush = ¤tentity->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 = ¤tentity->model->brush; + mod_brush_t *brush = ¤tentity->renderer.model->brush; // FIXME: clean this up and make it faster // FIXME: guard against running out of vertices diff --git a/libs/video/renderer/sw32/sw32_riqm.c b/libs/video/renderer/sw32/sw32_riqm.c index b53186bd9..1db5fbbdc 100644 --- a/libs/video/renderer/sw32/sw32_riqm.c +++ b/libs/video/renderer/sw32/sw32_riqm.c @@ -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); diff --git a/libs/video/renderer/sw32/sw32_rmain.c b/libs/video/renderer/sw32/sw32_rmain.c index 67c59e2f9..812a43205 100644 --- a/libs/video/renderer/sw32/sw32_rmain.c +++ b/libs/video/renderer/sw32/sw32_rmain.c @@ -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) { diff --git a/libs/video/renderer/sw32/sw32_rmisc.c b/libs/video/renderer/sw32/sw32_rmisc.c index 1b329b54f..753268993 100644 --- a/libs/video/renderer/sw32/sw32_rmisc.c +++ b/libs/video/renderer/sw32/sw32_rmisc.c @@ -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 <= diff --git a/libs/video/renderer/sw32/sw32_rpart.c b/libs/video/renderer/sw32/sw32_rpart.c index 1364f5d1b..fc640bc8e 100644 --- a/libs/video/renderer/sw32/sw32_rpart.c +++ b/libs/video/renderer/sw32/sw32_rpart.c @@ -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); diff --git a/libs/video/renderer/sw32/sw32_rsprite.c b/libs/video/renderer/sw32/sw32_rsprite.c index 92be9b51e..9c6cb7221 100644 --- a/libs/video/renderer/sw32/sw32_rsprite.c +++ b/libs/video/renderer/sw32/sw32_rsprite.c @@ -40,6 +40,7 @@ #include +#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 diff --git a/libs/video/renderer/sw32/sw32_rsurf.c b/libs/video/renderer/sw32/sw32_rsurf.c index decd8c3a7..dfc9c31cc 100644 --- a/libs/video/renderer/sw32/sw32_rsurf.c +++ b/libs/video/renderer/sw32/sw32_rsurf.c @@ -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; diff --git a/libs/video/renderer/vulkan/vulkan_alias.c b/libs/video/renderer/vulkan/vulkan_alias.c index cc1905c4a..25a2d9d13 100644 --- a/libs/video/renderer/vulkan/vulkan_alias.c +++ b/libs/video/renderer/vulkan/vulkan_alias.c @@ -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); } diff --git a/libs/video/renderer/vulkan/vulkan_bsp.c b/libs/video/renderer/vulkan/vulkan_bsp.c index 046ba6c0a..38aa57ee9 100644 --- a/libs/video/renderer/vulkan/vulkan_bsp.c +++ b/libs/video/renderer/vulkan/vulkan_bsp.c @@ -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; diff --git a/libs/video/renderer/vulkan/vulkan_main.c b/libs/video/renderer/vulkan/vulkan_main.c index 69916682e..e63ff0b03 100644 --- a/libs/video/renderer/vulkan/vulkan_main.c +++ b/libs/video/renderer/vulkan/vulkan_main.c @@ -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; diff --git a/nq/source/Makemodule.am b/nq/source/Makemodule.am index 2157cd42b..2da0c7fb4 100644 --- a/nq/source/Makemodule.am +++ b/nq/source/Makemodule.am @@ -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 diff --git a/nq/source/cl_ents.c b/nq/source/cl_ents.c index ce76ebf71..933097913 100644 --- a/nq/source/cl_ents.c +++ b/nq/source/cl_ents.c @@ -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); diff --git a/nq/source/cl_main.c b/nq/source/cl_main.c index 739e4a61c..f31256138 100644 --- a/nq/source/cl_main.c +++ b/nq/source/cl_main.c @@ -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)); } } diff --git a/nq/source/cl_parse.c b/nq/source/cl_parse.c index 3b076b43f..10ac2d4f5 100644 --- a/nq/source/cl_parse.c +++ b/nq/source/cl_parse.c @@ -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; diff --git a/nq/source/cl_tent.c b/nq/source/cl_tent.c index 2286d829a..3a8a1b899 100644 --- a/nq/source/cl_tent.c +++ b/nq/source/cl_tent.c @@ -38,6 +38,7 @@ #include #include +#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); } } diff --git a/nq/source/cl_view.c b/nq/source/cl_view.c index 71383ff08..132df122f 100644 --- a/nq/source/cl_view.c +++ b/nq/source/cl_view.c @@ -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, diff --git a/qw/source/Makemodule.am b/qw/source/Makemodule.am index 553a32f65..739789020 100644 --- a/qw/source/Makemodule.am +++ b/qw/source/Makemodule.am @@ -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 \ diff --git a/qw/source/cl_demo.c b/qw/source/cl_demo.c index 6151b6bd0..d063211d4 100644 --- a/qw/source/cl_demo.c +++ b/qw/source/cl_demo.c @@ -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) { diff --git a/qw/source/cl_entparse.c b/qw/source/cl_entparse.c index 6fc04a4c4..2d130574d 100644 --- a/qw/source/cl_entparse.c +++ b/qw/source/cl_entparse.c @@ -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; diff --git a/qw/source/cl_ents.c b/qw/source/cl_ents.c index 7c95040ed..d294f9981 100644 --- a/qw/source/cl_ents.c +++ b/qw/source/cl_ents.c @@ -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 diff --git a/qw/source/cl_parse.c b/qw/source/cl_parse.c index f38b30537..2523f8feb 100644 --- a/qw/source/cl_parse.c +++ b/qw/source/cl_parse.c @@ -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); diff --git a/qw/source/cl_tent.c b/qw/source/cl_tent.c index c24f1f0bc..e44ec9b3a 100644 --- a/qw/source/cl_tent.c +++ b/qw/source/cl_tent.c @@ -39,6 +39,7 @@ #include #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; diff --git a/qw/source/cl_view.c b/qw/source/cl_view.c index 4ad5da14f..59e7920cd 100644 --- a/qw/source/cl_view.c +++ b/qw/source/cl_view.c @@ -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, diff --git a/ruamoko/qwaq/Makemodule.am b/ruamoko/qwaq/Makemodule.am index bcb97af94..781db5c76 100644 --- a/ruamoko/qwaq/Makemodule.am +++ b/ruamoko/qwaq/Makemodule.am @@ -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 \