From: havoc Date: Wed, 15 Nov 2006 09:33:22 +0000 (+0000) Subject: fixed view location bugs in csqc; it was reading the player entity's render.origin... X-Git-Tag: xonotic-v0.1.0preview~3776 X-Git-Url: https://git.rm.cloudns.org/?a=commitdiff_plain;h=6f77dd97d9abe654f6a7c7a5a872a4ddc79b5737;p=xonotic%2Fdarkplaces.git fixed view location bugs in csqc; it was reading the player entity's render.origin field, which was broken... removed the origin and angles fields from entity_render_t and eliminated all references renamed CL_BoundingBoxForEntity to CL_UpdateRenderEntity and made it update the entity_render_t inversematrix and scale according to the matrix, and also calls R_LerpAnimation, this reduced code elsewhere git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6619 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/cl_main.c b/cl_main.c index 6782cc95..012de0db 100644 --- a/cl_main.c +++ b/cl_main.c @@ -188,13 +188,11 @@ void CL_ClearState(void) // entire entity array was cleared, so just fill in a few fields ent->state_current.active = true; ent->render.model = cl.worldmodel = NULL; // no world model yet - ent->render.scale = 1; // some of the renderer still relies on scale ent->render.alpha = 1; ent->render.colormap = -1; // no special coloring ent->render.flags = RENDER_SHADOW | RENDER_LIGHT; Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, 0, 0, 0, 0, 0, 0, 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); // noclip is turned off at start noclip_anglehack = false; @@ -441,7 +439,6 @@ static void CL_PrintEntities_f(void) entity_t *ent; int i, j; char name[32]; - vec3_t org; for (i = 0, ent = cl.entities;i < cl.num_entities;i++, ent++) { @@ -457,18 +454,25 @@ static void CL_PrintEntities_f(void) strlcpy(name, modelname, 25); for (j = (int)strlen(name);j < 25;j++) name[j] = ' '; - Matrix4x4_OriginFromMatrix(&ent->render.matrix, org); - Con_Printf("%3i: %s:%4i (%5i %5i %5i) [%3i %3i %3i] %4.2f %5.3f\n", i, name, ent->render.frame, (int) org[0], (int) org[1], (int) org[2], (int) ent->render.angles[0] % 360, (int) ent->render.angles[1] % 360, (int) ent->render.angles[2] % 360, ent->render.scale, ent->render.alpha); + Con_Printf("%3i: %s:%4i (%5i %5i %5i) [%3i %3i %3i] %4.2f %5.3f\n", i, name, ent->render.frame, (int) ent->state_current.origin[0], (int) ent->state_current.origin[1], (int) ent->state_current.origin[2], (int) ent->state_current.angles[0] % 360, (int) ent->state_current.angles[1] % 360, (int) ent->state_current.angles[2] % 360, ent->render.scale, ent->render.alpha); } } //static const vec3_t nomodelmins = {-16, -16, -16}; //static const vec3_t nomodelmaxs = {16, 16, 16}; -void CL_BoundingBoxForEntity(entity_render_t *ent) +void CL_UpdateRenderEntity(entity_render_t *ent) { vec3_t org; + vec_t scale; model_t *model = ent->model; + // update the inverse matrix for the renderer + Matrix4x4_Invert_Simple(&ent->inversematrix, &ent->matrix); + // update the animation blend state + R_LerpAnimation(ent); + // we need the matrix origin to center the box Matrix4x4_OriginFromMatrix(&ent->matrix, org); + // update entity->render.scale because the renderer needs it + ent->scale = scale = Matrix4x4_ScaleFromMatrix(&ent->matrix); if (model) { // NOTE: this directly extracts vector components from the matrix, which relies on the matrix orientation! @@ -479,12 +483,8 @@ void CL_BoundingBoxForEntity(entity_render_t *ent) #endif { // pitch or roll - ent->mins[0] = org[0] + model->rotatedmins[0]; - ent->mins[1] = org[1] + model->rotatedmins[1]; - ent->mins[2] = org[2] + model->rotatedmins[2]; - ent->maxs[0] = org[0] + model->rotatedmaxs[0]; - ent->maxs[1] = org[1] + model->rotatedmaxs[1]; - ent->maxs[2] = org[2] + model->rotatedmaxs[2]; + VectorMA(org, scale, model->rotatedmins, ent->mins); + VectorMA(org, scale, model->rotatedmaxs, ent->maxs); } #ifdef MATRIX4x4_OPENGLORIENTATION else if (ent->matrix.m[1][0] != 0 || ent->matrix.m[0][1] != 0) @@ -493,21 +493,13 @@ void CL_BoundingBoxForEntity(entity_render_t *ent) #endif { // yaw - ent->mins[0] = org[0] + model->yawmins[0]; - ent->mins[1] = org[1] + model->yawmins[1]; - ent->mins[2] = org[2] + model->yawmins[2]; - ent->maxs[0] = org[0] + model->yawmaxs[0]; - ent->maxs[1] = org[1] + model->yawmaxs[1]; - ent->maxs[2] = org[2] + model->yawmaxs[2]; + VectorMA(org, scale, model->yawmins, ent->mins); + VectorMA(org, scale, model->yawmaxs, ent->maxs); } else { - ent->mins[0] = org[0] + model->normalmins[0]; - ent->mins[1] = org[1] + model->normalmins[1]; - ent->mins[2] = org[2] + model->normalmins[2]; - ent->maxs[0] = org[0] + model->normalmaxs[0]; - ent->maxs[1] = org[1] + model->normalmaxs[1]; - ent->maxs[2] = org[2] + model->normalmaxs[2]; + VectorMA(org, scale, model->normalmins, ent->mins); + VectorMA(org, scale, model->normalmaxs, ent->maxs); } } else @@ -569,7 +561,6 @@ entity_t *CL_NewTempEntity(void) r_refdef.entities[r_refdef.numentities++] = &ent->render; ent->render.colormap = -1; // no special coloring - ent->render.scale = 1; ent->render.alpha = 1; VectorSet(ent->render.colormod, 1, 1, 1); return ent; @@ -776,9 +767,7 @@ void CL_AddQWCTFFlagModel(entity_t *player, int skin) // attach the flag to the player matrix Matrix4x4_CreateFromQuakeEntity(&flagmatrix, -f, -22, 0, 0, 0, -45, 1); Matrix4x4_Concat(&flag->render.matrix, &player->render.matrix, &flagmatrix); - Matrix4x4_Invert_Simple(&flag->render.inversematrix, &flag->render.matrix); - R_LerpAnimation(&flag->render); - CL_BoundingBoxForEntity(&flag->render); + CL_UpdateRenderEntity(&flag->render); } #define MAXVIEWMODELS 32 @@ -995,7 +984,6 @@ void CL_UpdateNetworkEntity(entity_t *e) e->render.frame2time = cl.time; e->render.framelerp = 0; } - R_LerpAnimation(&e->render); // set up the render matrix // FIXME: e->render.scale should go away @@ -1003,8 +991,7 @@ void CL_UpdateNetworkEntity(entity_t *e) // concat the matrices to make the entity relative to its tag Matrix4x4_Concat(&e->render.matrix, matrix, &matrix2); // make the other useful stuff - Matrix4x4_Invert_Simple(&e->render.inversematrix, &e->render.matrix); - CL_BoundingBoxForEntity(&e->render); + CL_UpdateRenderEntity(&e->render); // handle effects now that we know where this entity is in the world... if (e->render.model && e->render.model->soundfromcenter) @@ -1287,9 +1274,7 @@ void CL_RelinkWorld(void) cl.brushmodel_entities[cl.num_brushmodel_entities++] = 0; // FIXME: this should be done at load ent->render.matrix = identitymatrix; - ent->render.inversematrix = identitymatrix; - R_LerpAnimation(&ent->render); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); ent->render.flags = RENDER_SHADOW; if (!r_fullbright.integer) ent->render.flags |= RENDER_LIGHT; @@ -1396,9 +1381,7 @@ static void CL_RelinkEffects(void) VectorSet(ent->render.colormod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, e->origin[0], e->origin[1], e->origin[2], 0, 0, 0, 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - R_LerpAnimation(&ent->render); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); } } } @@ -1510,9 +1493,7 @@ void CL_RelinkBeams(void) //ent->render.angles[1] = yaw; //ent->render.angles[2] = rand()%360; Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, org[0], org[1], org[2], -pitch, yaw, lhrandom(0, 360), 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - R_LerpAnimation(&ent->render); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); VectorMA(org, 30, dist, org); d -= 30; } @@ -1544,9 +1525,7 @@ static void CL_RelinkQWNails(void) VectorSet(ent->render.colormod, 1, 1, 1); Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, v[0], v[1], v[2], v[3], v[4], v[5], 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - R_LerpAnimation(&ent->render); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); } } diff --git a/cl_parse.c b/cl_parse.c index e921abf3..b1cf5c21 100644 --- a/cl_parse.c +++ b/cl_parse.c @@ -492,7 +492,7 @@ static void QW_CL_RequestNextDownload(void) // now that we have a world model, set up the world entity, renderer // modules and csqc cl.entities[0].render.model = cl.worldmodel = cl.model_precache[1]; - CL_BoundingBoxForEntity(&cl.entities[0].render); + CL_UpdateRenderEntity(&cl.entities[0].render); R_Modules_NewMap(); @@ -1158,7 +1158,7 @@ void CL_ParseServerInfo (void) // we now have the worldmodel so we can set up the game world cl.entities[0].render.model = cl.worldmodel = cl.model_precache[1]; - CL_BoundingBoxForEntity(&cl.entities[0].render); + CL_UpdateRenderEntity(&cl.entities[0].render); R_Modules_NewMap(); } @@ -1441,14 +1441,12 @@ void CL_ParseStatic (int large) ent->render.skinnum = ent->state_baseline.skin; ent->render.effects = ent->state_baseline.effects; ent->render.alpha = 1; - //ent->render.scale = 1; //VectorCopy (ent->state_baseline.origin, ent->render.origin); //VectorCopy (ent->state_baseline.angles, ent->render.angles); Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, ent->state_baseline.origin[0], ent->state_baseline.origin[1], ent->state_baseline.origin[2], ent->state_baseline.angles[0], ent->state_baseline.angles[1], ent->state_baseline.angles[2], 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); // This is definitely cheating... if (ent->render.model == NULL) diff --git a/client.h b/client.h index e4494391..e725a11f 100644 --- a/client.h +++ b/client.h @@ -207,9 +207,9 @@ frameblend_t; typedef struct entity_render_s { // location - vec3_t origin; + //vec3_t origin; // orientation - vec3_t angles; + //vec3_t angles; // transform matrix for model to world matrix4x4_t matrix; // transform matrix for world to model @@ -603,7 +603,7 @@ typedef struct particle_s float airfriction; // how much air friction affects this object (objects with a low mass/size ratio tend to get more air friction) float liquidfriction; // how much liquid friction affects this object (objects with a low mass/size ratio tend to get more liquid friction) unsigned char color[4]; - unsigned short owner; // decal stuck to this entity + unsigned int owner; // decal stuck to this entity model_t *ownermodel; // model the decal is stuck to (used to make sure the entity is still alive) vec3_t relativeorigin; // decal at this location in entity's coordinate space vec3_t relativedirection; // decal oriented this way relative to entity's coordinate space @@ -992,7 +992,7 @@ void CL_EstablishConnection(const char *host); void CL_Disconnect (void); void CL_Disconnect_f (void); -void CL_BoundingBoxForEntity(entity_render_t *ent); +void CL_UpdateRenderEntity(entity_render_t *ent); // // cl_input diff --git a/csprogs.c b/csprogs.c index 9974dd9e..b77940cb 100644 --- a/csprogs.c +++ b/csprogs.c @@ -132,7 +132,7 @@ static void CSQC_SetGlobals (void) prog->globals.client->input_buttons = csqc_buttons; VectorSet(prog->globals.client->input_movevalues, cl.cmd.forwardmove, cl.cmd.sidemove, cl.cmd.upmove); //VectorCopy(cl.movement_origin, csqc_origin); - VectorCopy(cl.entities[cl.viewentity].render.origin, csqc_origin); + Matrix4x4_OriginFromMatrix(&cl.entities[cl.viewentity].render.matrix, csqc_origin); VectorCopy(csqc_origin, prog->globals.client->pmove_org); prog->globals.client->maxclients = cl.maxclients; //VectorCopy(cl.movement_velocity, prog->globals.client->pmove_vel); @@ -234,17 +234,15 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed) Matrix4x4_CreateFromQuakeEntity(&matrix2, ed->fields.client->origin[0], ed->fields.client->origin[1], ed->fields.client->origin[2], angles[0], angles[1], angles[2], e->render.scale); } - // concat the matrices to make the entity relative to its tag - Matrix4x4_Concat(&e->render.matrix, &tagmatrix, &matrix2); - // make the other useful stuff - Matrix4x4_Invert_Simple(&e->render.inversematrix, &e->render.matrix); - CL_BoundingBoxForEntity(&e->render); - // FIXME: csqc has frame1/frame2/frame1time/frame2time/lerpfrac but this implementation's cl_entvars_t lacks those fields e->render.frame1 = e->render.frame = ed->fields.client->frame; e->render.frame1time = e->render.frame2time = 0; e->render.framelerp = 0; - R_LerpAnimation(&e->render); + + // concat the matrices to make the entity relative to its tag + Matrix4x4_Concat(&e->render.matrix, &tagmatrix, &matrix2); + // make the other useful stuff + CL_UpdateRenderEntity(&e->render); i = 0; if((val = PRVM_GETEDICTFIELDVALUE(ed, csqc_fieldoff_renderflags)) && val->_float) @@ -357,7 +355,6 @@ void CL_VM_Parse_StuffCmd (const char *msg) if(msg[2] == 'q') if(msg[3] == 'c') { - Cvar_SetQuick(&csqc_progcrc, "0"); csqc_progcrc.flags = 0; Cmd_ExecuteString (msg, src_command); csqc_progcrc.flags = CVAR_READONLY; @@ -484,33 +481,42 @@ void Cmd_ClearCsqcFuncs (void); void CL_VM_Init (void) { + unsigned char *csprogsdata; + fs_offset_t csprogsdatasize; + unsigned int csprogsdatacrc; entity_t *ent; csqc_loaded = false; memset(cl.csqc_model_precache, 0, sizeof(cl.csqc_model_precache)); memset(&cl.csqc_vidvars, true, sizeof(csqc_vidvars_t)); - if(!FS_FileExists(csqc_progname.string)) + // if the server is not requesting a csprogs, then we're done here + if (!csqc_progcrc.integer) + return; + + // see if there is a csprogs.dat installed, and if so, set the csqc_progcrc accordingly, this will be sent to connecting clients to tell them to only load a matching csprogs.dat file + csprogsdatacrc = 0; + csprogsdata = FS_LoadFile(csqc_progname.string, tempmempool, true, &csprogsdatasize); + if (csprogsdata) { - if(!sv.active && csqc_progcrc.integer) + csprogsdatacrc = CRC_Block(csprogsdata, csprogsdatasize); + Mem_Free(csprogsdata); + if(csprogsdatacrc != (unsigned short)csqc_progcrc.integer && !sv.active && !cls.demoplayback) { - Con_Printf("CL_VM_Init: server requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string); + Con_Printf("^1Your %s is not the same version as the server (CRC is %i but should be %i)\n", csqc_progname.string, prog->filecrc, csqc_progcrc.integer); + PRVM_ResetProg(); CL_Disconnect(); + return; } - return; } else { - if (developer.integer < 100) - { - Con_DPrintf("CL_VM_Init: CSQC is broken, and is not being loaded because developer is less than 100.\n"); - return; - } - if(!sv.active && !csqc_progcrc.integer) //[515]: because cheaters may use csqc while server didn't allowed it ! + if(!sv.active && csqc_progcrc.integer) { - Con_Printf("CL_VM_Init: server didn't sent CSQC crc, so CSQC is disabled\n"); - return; + Con_Printf("CL_VM_Init: server requires CSQC, but \"%s\" wasn't found\n", csqc_progname.string); + CL_Disconnect(); } + return; } PRVM_Begin; @@ -543,10 +549,7 @@ void CL_VM_Init (void) } if(prog->loaded) - { - Cvar_SetValueQuick(&csqc_progcrc, prog->filecrc); Con_Printf("CSQC ^5loaded (crc=%i)\n", csqc_progcrc.integer); - } else { CL_VM_Error("CSQC ^2failed to load\n"); @@ -582,12 +585,10 @@ void CL_VM_Init (void) // entire entity array was cleared, so just fill in a few fields ent->state_current.active = true; ent->render.model = cl.worldmodel = cl.model_precache[1]; - ent->render.scale = 1; // some of the renderer still relies on scale ent->render.alpha = 1; ent->render.flags = RENDER_SHADOW | RENDER_LIGHT; Matrix4x4_CreateFromQuakeEntity(&ent->render.matrix, 0, 0, 0, 0, 0, 0, 1); - Matrix4x4_Invert_Simple(&ent->render.inversematrix, &ent->render.matrix); - CL_BoundingBoxForEntity(&ent->render); + CL_UpdateRenderEntity(&ent->render); } void CL_VM_ShutDown (void) diff --git a/gl_rmain.c b/gl_rmain.c index 405c9aa1..c0f20c71 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1138,7 +1138,11 @@ static void R_UpdateEntityLighting(entity_render_t *ent) VectorClear(ent->modellight_diffuse); VectorClear(ent->modellight_lightdir); if ((ent->flags & RENDER_LIGHT) && r_refdef.worldmodel && r_refdef.worldmodel->brush.LightPoint) - r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, ent->origin, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal); + { + vec3_t org; + Matrix4x4_OriginFromMatrix(&ent->matrix, org); + r_refdef.worldmodel->brush.LightPoint(r_refdef.worldmodel, org, ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal); + } else // highly rare VectorSet(ent->modellight_ambient, 1, 1, 1); Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir); @@ -1780,10 +1784,6 @@ void R_UpdateVariables(void) for (i = 0;i < r_refdef.numentities;i++) { entity_render_t *ent = r_refdef.entities[i]; - // some of the renderer still relies on origin... - Matrix4x4_OriginFromMatrix(&ent->matrix, ent->origin); - // some of the renderer still relies on scale... - ent->scale = Matrix4x4_ScaleFromMatrix(&ent->matrix); R_UpdateEntityLighting(ent); } } @@ -2069,9 +2069,11 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight R_Mesh_VertexPointer(nomodelvertex3f); if (r_refdef.fogenabled) { + vec3_t org; memcpy(color4f, nomodelcolor4f, sizeof(float[6*4])); R_Mesh_ColorPointer(color4f); - f2 = VERTEXFOGTABLE(VectorDistance(ent->origin, r_view.origin)); + Matrix4x4_OriginFromMatrix(&ent->matrix, org); + f2 = VERTEXFOGTABLE(VectorDistance(org, r_view.origin)); f1 = 1 - f2; for (i = 0, c = color4f;i < 6;i++, c += 4) { @@ -2096,8 +2098,10 @@ void R_DrawNoModel_TransparentCallback(const entity_render_t *ent, const rtlight void R_DrawNoModel(entity_render_t *ent) { + vec3_t org; + Matrix4x4_OriginFromMatrix(&ent->matrix, org); //if ((ent->effects & EF_ADDITIVE) || (ent->alpha < 1)) - R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : ent->origin, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight); + R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, r_shadow_rtlight); //else // R_DrawNoModelCallback(ent, 0); } diff --git a/r_shadow.c b/r_shadow.c index a3376ad2..1e696613 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -2378,7 +2378,9 @@ void R_DrawRTLight(rtlight_t *rtlight, qboolean visible) && (r_refdef.worldmodel == NULL || r_refdef.worldmodel->brush.BoxTouchingLeafPVS == NULL || r_refdef.worldmodel->brush.BoxTouchingLeafPVS(r_refdef.worldmodel, leafpvs, ent->mins, ent->maxs))) { // about the VectorDistance2 - light emitting entities should not cast their own shadow - if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(ent->origin, rtlight->shadoworigin) > 0.1) + vec3_t org; + Matrix4x4_OriginFromMatrix(&ent->matrix, org); + if ((ent->flags & RENDER_SHADOW) && model->DrawShadowVolume && VectorDistance2(org, rtlight->shadoworigin) > 0.1) shadowentities[numshadowentities++] = ent; if (r_viewcache.entityvisible[i] && (ent->flags & RENDER_LIGHT) && model->DrawLight) lightentities[numlightentities++] = ent; diff --git a/r_sprites.c b/r_sprites.c index 87c06b74..2f59f1c7 100644 --- a/r_sprites.c +++ b/r_sprites.c @@ -71,7 +71,9 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r color[0] = color[1] = color[2] = 1; else { - R_CompleteLightPoint(color, diffusecolor, diffusenormal, ent->origin, true); + vec3_t org; + Matrix4x4_OriginFromMatrix(&ent->matrix, org); + R_CompleteLightPoint(color, diffusecolor, diffusenormal, org, true); VectorMA(color, 0.5f, diffusecolor, color); } color[0] *= ent->colormod[0]; @@ -92,9 +94,11 @@ void R_Model_Sprite_Draw_TransparentCallback(const entity_render_t *ent, const r void R_Model_Sprite_Draw(entity_render_t *ent) { + vec3_t org; if (ent->frameblend[0].frame < 0) return; - R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : ent->origin, R_Model_Sprite_Draw_TransparentCallback, ent, 0, r_shadow_rtlight); + Matrix4x4_OriginFromMatrix(&ent->matrix, org); + R_MeshQueue_AddTransparent(ent->effects & EF_NODEPTHTEST ? r_view.origin : org, R_Model_Sprite_Draw_TransparentCallback, ent, 0, r_shadow_rtlight); }