From 806c02c0cfc72021fe8d60f10158d2d0e0e53800 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 12 Feb 2007 16:44:09 +0000 Subject: [PATCH] fixed problems with network entity viewmodels not following csqc_origin (as set by csqc) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6832 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 87 +++++++++++++++++++++++++++++++---------------------- clvm_cmds.c | 18 +++++++++-- 2 files changed, 67 insertions(+), 38 deletions(-) diff --git a/cl_main.c b/cl_main.c index 9d5c7932..f7c5ecab 100644 --- a/cl_main.c +++ b/cl_main.c @@ -762,16 +762,15 @@ static const vec3_t muzzleflashorigin = {18, 0, 0}; extern void V_DriftPitch(void); extern void V_FadeViewFlashs(void); extern void V_CalcViewBlend(void); - extern void V_CalcRefdef(void); -// note this is a recursive function, but it can never get in a runaway loop (because of the delayedlink flags) -void CL_UpdateNetworkEntity(entity_t *e) + +// note this is a recursive function, recursionlimit should be 32 or so on the initial call +void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit) { const matrix4x4_t *matrix; matrix4x4_t blendmatrix, tempmatrix, matrix2; //matrix4x4_t dlightmatrix; int j, k, l; - effectnameindex_t trailtype; float origin[3], angles[3], delta[3], lerp, d; entity_t *t; model_t *model; @@ -780,6 +779,8 @@ void CL_UpdateNetworkEntity(entity_t *e) // skip inactive entities and world if (!e->state_current.active || e == cl.entities) return; + if (recursionlimit < 1) + return; e->render.alpha = e->state_current.alpha * (1.0f / 255.0f); // FIXME: interpolate? e->render.scale = e->state_current.scale * (1.0f / 16.0f); // FIXME: interpolate? e->render.flags = e->state_current.flags; @@ -835,7 +836,7 @@ void CL_UpdateNetworkEntity(entity_t *e) if (!t->state_current.active) return; // update the parent first - CL_UpdateNetworkEntity(t); + CL_UpdateNetworkEntity(t, recursionlimit - 1); // make relative to the entity matrix = &t->render.matrix; // some properties of the tag entity carry over @@ -965,6 +966,39 @@ void CL_UpdateNetworkEntity(entity_t *e) Matrix4x4_CreateFromQuakeEntity(&e->render.matrix, origin[0], origin[1], origin[2], angles[0], angles[1], angles[2], e->render.scale); } + // make the other useful stuff + CL_UpdateRenderEntity(&e->render); + + // tenebrae's sprites are all additive mode (weird) + if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite) + e->render.effects |= EF_ADDITIVE; + // player model is only shown with chase_active on + if (e->state_current.number == cl.viewentity) + e->render.flags |= RENDER_EXTERIORMODEL; + // transparent stuff can't be lit during the opaque stage + if (e->render.effects & (EF_ADDITIVE | EF_NODEPTHTEST) || e->render.alpha < 1) + e->render.flags |= RENDER_TRANSPARENT; + // double sided rendering mode causes backfaces to be visible + // (mostly useful on transparent stuff) + if (e->render.effects & EF_DOUBLESIDED) + e->render.flags |= RENDER_NOCULLFACE; + // either fullbright or lit + if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) + e->render.flags |= RENDER_LIGHT; + // hide player shadow during intermission or nehahra movie + if (!(e->render.effects & EF_NOSHADOW) + && !(e->render.flags & (RENDER_VIEWMODEL | RENDER_TRANSPARENT)) + && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer))) + e->render.flags |= RENDER_SHADOW; +} + +// creates light and trails from an entity +void CL_UpdateNetworkEntityTrail(entity_t *e) +{ + //matrix4x4_t dlightmatrix; + effectnameindex_t trailtype; + vec3_t origin; + // bmodels are treated specially since their origin is usually '0 0 0' and // their actual geometry is far from '0 0 0' if (e->render.model && e->render.model->soundfromcenter) @@ -974,9 +1008,6 @@ void CL_UpdateNetworkEntity(entity_t *e) Matrix4x4_Transform(&e->render.matrix, o, origin); } - // make the other useful stuff - CL_UpdateRenderEntity(&e->render); - // handle particle trails and such effects now that we know where this // entity is in the world... trailtype = EFFECT_NONE; @@ -1039,29 +1070,6 @@ void CL_UpdateNetworkEntity(entity_t *e) CL_ParticleTrail(trailtype, 1, e->persistent.trail_origin, origin, vel, vel, e, e->state_current.glowcolor, false, true); } VectorCopy(origin, e->persistent.trail_origin); - // tenebrae's sprites are all additive mode (weird) - if (gamemode == GAME_TENEBRAE && e->render.model && e->render.model->type == mod_sprite) - e->render.effects |= EF_ADDITIVE; - // player model is only shown with chase_active on - if (e->state_current.number == cl.viewentity) - e->render.flags |= RENDER_EXTERIORMODEL; - // transparent stuff can't be lit during the opaque stage - if (e->render.effects & (EF_ADDITIVE | EF_NODEPTHTEST) || e->render.alpha < 1) - e->render.flags |= RENDER_TRANSPARENT; - // double sided rendering mode causes backfaces to be visible - // (mostly useful on transparent stuff) - if (e->render.effects & EF_DOUBLESIDED) - e->render.flags |= RENDER_NOCULLFACE; - // either fullbright or lit - if (!(e->render.effects & EF_FULLBRIGHT) && !r_fullbright.integer) - e->render.flags |= RENDER_LIGHT; - // hide player shadow during intermission or nehahra movie - if (!(e->render.effects & EF_NOSHADOW) - && !(e->render.flags & (RENDER_VIEWMODEL | RENDER_TRANSPARENT)) - && (!(e->render.flags & RENDER_EXTERIORMODEL) || (!cl.intermission && cls.protocol != PROTOCOL_NEHAHRAMOVIE && !cl_noplayershadow.integer))) - e->render.flags |= RENDER_SHADOW; - if (e->render.model && e->render.model->name[0] == '*' && e->render.model->TraceBox) - cl.brushmodel_entities[cl.num_brushmodel_entities++] = e->state_current.number; } @@ -1077,7 +1085,7 @@ void CL_UpdateEntities(void) // process network entities // first link the player - CL_UpdateNetworkEntity(cl.entities + cl.viewentity); + CL_UpdateNetworkEntity(cl.entities + cl.viewentity, 32); // set up the view V_CalcRefdef(); @@ -1086,11 +1094,18 @@ void CL_UpdateEntities(void) // skip the player entity because it was already processed for (i = 1;i < cl.num_entities;i++) { - if (cl.entities_active[i] && i != cl.viewentity) + if (cl.entities_active[i]) { ent = cl.entities + i; if (ent->state_current.active) - CL_UpdateNetworkEntity(ent); + { + CL_UpdateNetworkEntity(ent, 32); + // view models should never create light/trails + if (!(ent->render.flags & RENDER_VIEWMODEL)) + CL_UpdateNetworkEntityTrail(ent); + if (ent->render.model && ent->render.model->name[0] == '*' && ent->render.model->TraceBox) + cl.brushmodel_entities[cl.num_brushmodel_entities++] = ent->state_current.number; + } else cl.entities_active[i] = false; } @@ -1124,7 +1139,7 @@ void CL_UpdateEntities(void) ent->render.frame1time = ent->render.frame2time = cl.time; ent->render.framelerp = 1; } - CL_UpdateNetworkEntity(ent); + CL_UpdateNetworkEntity(ent, 32); } // note this is a recursive function, but it can never get in a runaway loop (because of the delayedlink flags) @@ -1641,7 +1656,7 @@ int CL_ReadFromServer(void) V_DriftPitch(); V_FadeViewFlashs(); - // now update all the network entities + // now update all the network entities and the view matrix CL_UpdateEntities(); CL_RelinkLightFlashes(); diff --git a/clvm_cmds.c b/clvm_cmds.c index d814234b..dfa53575 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -766,8 +766,6 @@ qboolean csqc_usecsqclistener = false;//[515]: per-frame static void CSQC_R_RecalcView (void) { extern matrix4x4_t viewmodelmatrix; - viewmodelmatrix = identitymatrix; - r_view.matrix = identitymatrix; Matrix4x4_CreateFromQuakeEntity(&r_view.matrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], 1); Matrix4x4_CreateFromQuakeEntity(&viewmodelmatrix, csqc_origin[0], csqc_origin[1], csqc_origin[2], csqc_angles[0], csqc_angles[1], csqc_angles[2], cl_viewmodel_scale.value); } @@ -915,10 +913,26 @@ void VM_R_SetView (void) PRVM_G_FLOAT(OFS_RETURN) = 1; } +extern void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit); //#304 void() renderscene (EXT_CSQC) void VM_R_RenderScene (void) //#134 { + int i; VM_SAFEPARMCOUNT(0, VM_R_RenderScene); + // we need to update any RENDER_VIEWMODEL entities at this point because + // csqc supplies its own view matrix + for (i = 1;i < cl.num_entities;i++) + { + if (cl.entities_active[i]) + { + entity_t *ent = cl.entities + i; + if ((ent->render.flags & RENDER_VIEWMODEL) || ent->state_current.tagentity) + CL_UpdateNetworkEntity(ent, 32); + } + } + // and of course the engine viewmodel needs updating as well + CL_UpdateNetworkEntity(&cl.viewent, 32); + // now draw stuff! R_RenderView(); } -- 2.39.2