From e941f7fbf97a98b3c0796ed834f580e0138c31b1 Mon Sep 17 00:00:00 2001 From: divverent Date: Sat, 7 Nov 2009 12:47:29 +0000 Subject: [PATCH] try fixing gettaginfo in client with frameblend etc. stuff git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@9448 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_main.c | 29 +++++++-------------- clvm_cmds.c | 16 +++++++++--- csprogs.c | 72 +++++++++++++++++++++++++++++++++++++---------------- csprogs.h | 3 +++ 4 files changed, 75 insertions(+), 45 deletions(-) diff --git a/cl_main.c b/cl_main.c index 8f11bad9..c369a436 100644 --- a/cl_main.c +++ b/cl_main.c @@ -873,10 +873,9 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat { const matrix4x4_t *matrix; matrix4x4_t blendmatrix, tempmatrix, matrix2; - int j, k, l, frame; - float origin[3], angles[3], lerp, d; + int frame; + float origin[3], angles[3], lerp; entity_t *t; - dp_model_t *model; //entity_persistent_t *p = &e->persistent; //entity_render_t *r = &e->render; // skip inactive entities and world @@ -919,23 +918,15 @@ void CL_UpdateNetworkEntity(entity_t *e, int recursionlimit, qboolean interpolat e->render.flags |= t->render.flags & (RENDER_EXTERIORMODEL | RENDER_VIEWMODEL); // if a valid tagindex is used, make it relative to that tag instead // FIXME: use a model function to get tag info (need to handle skeletal) - if (e->state_current.tagentity && e->state_current.tagindex >= 1 && (model = t->render.model)) + if (e->state_current.tagentity && e->state_current.tagindex >= 1) { - // blend the matrices - memset(&blendmatrix, 0, sizeof(blendmatrix)); - for (j = 0;j < MAX_FRAMEBLENDS && t->render.frameblend[j].lerp > 0;j++) + if(CL_BlendTagMatrix(&t->render, e->state_current.tagindex - 1, &blendmatrix)) { - matrix4x4_t tagmatrix; - Mod_Alias_GetTagMatrix(model, t->render.frameblend[j].subframe, e->state_current.tagindex - 1, &tagmatrix); - d = t->render.frameblend[j].lerp; - for (l = 0;l < 4;l++) - for (k = 0;k < 4;k++) - blendmatrix.m[l][k] += d * tagmatrix.m[l][k]; + // concat the tag matrices onto the entity matrix + Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix); + // use the constructed tag matrix + matrix = &tempmatrix; } - // concat the tag matrices onto the entity matrix - Matrix4x4_Concat(&tempmatrix, &t->render.matrix, &blendmatrix); - // use the constructed tag matrix - matrix = &tempmatrix; } } else if (e->render.flags & RENDER_VIEWMODEL) @@ -1881,9 +1872,7 @@ static void CL_Fog_f (void) Con_Printf("\"fog\" is \"%f %f %f %f %f %f %f %f %f\"\n", r_refdef.fog_density, r_refdef.fog_red, r_refdef.fog_green, r_refdef.fog_blue, r_refdef.fog_alpha, r_refdef.fog_start, r_refdef.fog_end, r_refdef.fog_height, r_refdef.fog_fadedepth); return; } - r_refdef.fog_start = 0; - r_refdef.fog_end = 16384; - r_refdef.fog_alpha = 1; + FOG_clear(); // so missing values get good defaults if(Cmd_Argc() > 1) r_refdef.fog_density = atof(Cmd_Argv(1)); if(Cmd_Argc() > 2) diff --git a/clvm_cmds.c b/clvm_cmds.c index 71cbb33a..0e408f4f 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -2273,11 +2273,11 @@ void CL_GetEntityMatrix (prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatri } } - int CL_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out) { int frame; dp_model_t *model; + entity_render_t cheatentity; if (tagindex >= 0 && (model = CL_GetModelFromEdict(ent)) && model->animscenes) @@ -2286,10 +2286,20 @@ int CL_GetEntityLocalTagMatrix(prvm_edict_t *ent, int tagindex, matrix4x4_t *out frame = (int)ent->fields.client->frame; if (frame < 0 || frame >= model->numframes) frame = 0; - return Mod_Alias_GetTagMatrix(model, model->animscenes[frame].firstframe, tagindex, out); + // now we'll do some CHEATING + memset(&cheatentity, 0, sizeof(cheatentity)); + cheatentity.model = model; + CL_LoadFrameGroupBlend(ent, &cheatentity); + R_LerpAnimation(&cheatentity); + if(!CL_BlendTagMatrix(&cheatentity, tagindex, out)) + { + *out = identitymatrix; + return false; + } + return true; } *out = identitymatrix; - return 0; + return false; } // Warnings/errors code: diff --git a/csprogs.c b/csprogs.c index 75e7f106..5791e9ea 100644 --- a/csprogs.c +++ b/csprogs.c @@ -219,28 +219,7 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) } // set up the animation data - // self.frame is the interpolation target (new frame) - // self.frame1time is the animation base time for the interpolation target - // self.frame2 is the interpolation start (previous frame) - // self.frame2time is the animation base time for the interpolation start - // self.lerpfrac is the interpolation strength for self.frame - // 3+ are for additional blends (the main use for this feature is lerping - // pitch angle on a player model where the animator set up 5 sets of - // animations and the csqc simply lerps between sets) - entrender->framegroupblend[0].frame = entrender->framegroupblend[1].frame = (int) ed->fields.client->frame; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) entrender->framegroupblend[1].frame = (int) val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3))) entrender->framegroupblend[2].frame = (int) val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4))) entrender->framegroupblend[3].frame = (int) val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) entrender->framegroupblend[0].start = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) entrender->framegroupblend[1].start = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3time))) entrender->framegroupblend[2].start = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4time))) entrender->framegroupblend[3].start = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) entrender->framegroupblend[0].lerp = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac3))) entrender->framegroupblend[2].lerp = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac4))) entrender->framegroupblend[3].lerp = val->_float; - if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.shadertime))) entrender->shadertime = val->_float; - // assume that the (missing) lerpfrac2 is whatever remains after lerpfrac+lerpfrac3+lerpfrac4 are summed - entrender->framegroupblend[1].lerp = 1 - entrender->framegroupblend[0].lerp - entrender->framegroupblend[2].lerp - entrender->framegroupblend[3].lerp; + CL_LoadFrameGroupBlend(ed, entrender); // concat the matrices to make the entity relative to its tag Matrix4x4_Concat(&entrender->matrix, &tagmatrix, &matrix2); @@ -1024,3 +1003,52 @@ qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out) return r; } + +void CL_LoadFrameGroupBlend(prvm_edict_t *ed, entity_render_t *entrender) +{ + prvm_eval_t *val; + // self.frame is the interpolation target (new frame) + // self.frame1time is the animation base time for the interpolation target + // self.frame2 is the interpolation start (previous frame) + // self.frame2time is the animation base time for the interpolation start + // self.lerpfrac is the interpolation strength for self.frame + // 3+ are for additional blends (the main use for this feature is lerping + // pitch angle on a player model where the animator set up 5 sets of + // animations and the csqc simply lerps between sets) + entrender->framegroupblend[0].frame = entrender->framegroupblend[1].frame = (int) ed->fields.client->frame; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2))) entrender->framegroupblend[1].frame = (int) val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3))) entrender->framegroupblend[2].frame = (int) val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4))) entrender->framegroupblend[3].frame = (int) val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame1time))) entrender->framegroupblend[0].start = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame2time))) entrender->framegroupblend[1].start = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame3time))) entrender->framegroupblend[2].start = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.frame4time))) entrender->framegroupblend[3].start = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac))) entrender->framegroupblend[0].lerp = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac3))) entrender->framegroupblend[2].lerp = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.lerpfrac4))) entrender->framegroupblend[3].lerp = val->_float; + if ((val = PRVM_EDICTFIELDVALUE(ed, prog->fieldoffsets.shadertime))) entrender->shadertime = val->_float; + // assume that the (missing) lerpfrac2 is whatever remains after lerpfrac+lerpfrac3+lerpfrac4 are summed + entrender->framegroupblend[1].lerp = 1 - entrender->framegroupblend[0].lerp - entrender->framegroupblend[2].lerp - entrender->framegroupblend[3].lerp; +} + +qboolean CL_BlendTagMatrix(entity_render_t *entrender, int tagindex, matrix4x4_t *blendmatrix) +{ + int j, l, k; + float d; + dp_model_t *model = entrender->model; + if(!model) + return false; + // blend the matrices + memset(&blendmatrix, 0, sizeof(blendmatrix)); + for (j = 0;j < MAX_FRAMEBLENDS && entrender->frameblend[j].lerp > 0;j++) + { + matrix4x4_t tagmatrix; + if(!Mod_Alias_GetTagMatrix(model, entrender->frameblend[j].subframe, tagindex, &tagmatrix)) + return false; + d = entrender->frameblend[j].lerp; + for (l = 0;l < 4;l++) + for (k = 0;k < 4;k++) + blendmatrix->m[l][k] += d * tagmatrix.m[l][k]; + } + return true; +} diff --git a/csprogs.h b/csprogs.h index e4a3e897..1cd41deb 100644 --- a/csprogs.h +++ b/csprogs.h @@ -61,4 +61,7 @@ qboolean MakeDownloadPacket(const char *filename, unsigned char *data, unsigned qboolean CL_VM_GetEntitySoundOrigin(int entnum, vec3_t out); +void CL_LoadFrameGroupBlend(prvm_edict_t *ed, entity_render_t *entrender); +qboolean CL_BlendTagMatrix(entity_render_t *entrender, int tagindex, matrix4x4_t *blendmatrix); + #endif -- 2.39.2