Cumulative patch:
authorvortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 21 Dec 2011 15:20:10 +0000 (15:20 +0000)
committervortex <vortex@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 21 Dec 2011 15:20:10 +0000 (15:20 +0000)
Fix RF_MODELLIGHT (was broken and dont work same way engine does it).
Fix bug in physics_ode_constantstep 1 (integer division, huh).
Added new geomtype field for ODE physics - sets collision shape, SOLID_PHYSICS_ are not deprecated (but keeped for compatibility reasons), as geomtype is a more correct way to set collision shape (allows to set both SOLID_CORPSE and trimesh collisions for instance).
Fixed support of custinfoparms.txt as some recent change in shader code seemed to broke it.

git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11620 d7cf8633-e32d-0410-b094-e92efae38249

csprogs.c
dpdefs/dpextensions.qc
gl_rmain.c
model_shared.c
model_shared.h
progs.h
prvm_offsets.h
server.h
world.c

index 289f678..b935841 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -357,6 +357,15 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
        if (renderflags & RF_USETRANSPARENTOFFSET)
                entrender->transparent_offset = PRVM_clientglobalfloat(transparent_offset);
 
+       // model light
+       if (renderflags & RF_MODELLIGHT)
+       {
+               if (PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->modellight_ambient); else VectorClear(entrender->modellight_ambient);
+               if (PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->modellight_diffuse); else VectorClear(entrender->modellight_diffuse);
+               if (PRVM_clientedictvector(ed, modellight_dir))     VectorCopy(PRVM_clientedictvector(ed, modellight_dir), entrender->modellight_lightdir);    else VectorClear(entrender->modellight_lightdir);
+               entrender->flags |= RENDER_CUSTOMIZEDMODELLIGHT;
+       }
+
        if(renderflags)
        {
                if(renderflags & RF_VIEWMODEL) entrender->flags |= RENDER_VIEWMODEL | RENDER_NODEPTHTEST;
@@ -405,18 +414,6 @@ qboolean CSQC_AddRenderEdict(prvm_edict_t *ed, int edictnum)
        memcpy(entrender->framegroupblend, ed->priv.server->framegroupblend, sizeof(ed->priv.server->framegroupblend));
        CL_UpdateRenderEntity(entrender);
 
-       // model light
-       if (renderflags & RF_MODELLIGHT)
-       {
-               if(PRVM_clientedictvector(ed, modellight_ambient)) VectorCopy(PRVM_clientedictvector(ed, modellight_ambient), entrender->modellight_ambient);
-               if(PRVM_clientedictvector(ed, modellight_diffuse)) VectorCopy(PRVM_clientedictvector(ed, modellight_diffuse), entrender->modellight_diffuse);
-               if(PRVM_clientedictvector(ed, modellight_dir))     Matrix4x4_Transform3x3(&entrender->matrix, PRVM_clientedictvector(ed, modellight_dir), entrender->modellight_lightdir);
-               if (VectorLength2(entrender->modellight_lightdir) == 0)
-                       VectorSet(entrender->modellight_lightdir, 0, 0, 1); // have to set SOME valid vector here
-               VectorNormalize(entrender->modellight_lightdir);
-               entrender->flags |= RENDER_CUSTOMIZEDMODELLIGHT;
-       }
-
        // override animation data with full control
        memcpy(entrender->frameblend, ed->priv.server->frameblend, sizeof(ed->priv.server->frameblend));
        if (ed->priv.server->skeleton.relativetransforms)
index caa9b62..b340bae 100644 (file)
@@ -1665,12 +1665,19 @@ void(float effectnum, vector org, vector vel, float howmany) pointparticles = #3
 //globals:
 //new movetypes:
 const float MOVETYPE_PHYSICS = 32; // need to be set before any physics_* builtins applied
-//new solid types:
+//new solid types (deprecated):
 const float SOLID_PHYSICS_BOX = 32;
 const float SOLID_PHYSICS_SPHERE = 33;
 const float SOLID_PHYSICS_CAPSULE = 34;
 const float SOLID_PHYSICS_TRIMESH = 35;
 const float SOLID_PHYSICS_CYLINDER = 36;
+//geometry types:
+const float GEOMTYPE_NULL = 0;
+const float GEOMTYPE_BOX = 1;
+const float GEOMTYPE_SPHERE = 2;
+const float GEOMTYPE_CAPSULE = 3;
+const float GEOMTYPE_TRIMESH = 4;
+const float GEOMTYPE_CYLINDER = 5;
 //SOLID_BSP;
 //joint types:
 const float JOINTTYPE_POINT = 1;
@@ -1692,6 +1699,7 @@ const float JOINTTYPE_FIXED = -1;
 //     movedir_z = stop position (+/-), set to 0 for no stop
 //   note that ODE does not support both in one anyway
 //field definitions:
+.float geomtype; // see GEOMTYPE_*, a more correct way to set collision shape, allows to set SOLID_CORPSE and trimesh collisions
 .float mass; // ODE mass, standart value is 1
 .vector massofs; // offsets a mass center out of object center, if not set a center of model bounds is used
 .float friction;
index 8c88310..cb376db 100644 (file)
@@ -4731,8 +4731,8 @@ static void R_View_UpdateEntityLighting (void)
        {
                ent = r_refdef.scene.entities[i];
 
-               // skip unseen models and models that updated by CSQC
-               if ((!r_refdef.viewcache.entityvisible[i] && skipunseen) || ent->flags & RENDER_CUSTOMIZEDMODELLIGHT)
+               // skip unseen models
+               if ((!r_refdef.viewcache.entityvisible[i] && skipunseen))
                        continue;
 
                // skip bsp models
@@ -4744,74 +4744,83 @@ static void R_View_UpdateEntityLighting (void)
                        VectorSet(ent->modellight_lightdir, 0, 0, 1);
                        continue;
                }
-
-               // fetch the lighting from the worldmodel data
-               VectorClear(ent->modellight_ambient);
-               VectorClear(ent->modellight_diffuse);
-               VectorClear(tempdiffusenormal);
-               if (ent->flags & RENDER_LIGHT)
+               
+               if (ent->flags & RENDER_CUSTOMIZEDMODELLIGHT)
                {
-                       vec3_t org;
-                       Matrix4x4_OriginFromMatrix(&ent->matrix, org);
-
-                       // complete lightning for lit sprites
-                       // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
-                       if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
+                       // aleady updated by CSQC
+                       // TODO: force modellight on BSP models in this case?
+                       VectorCopy(ent->modellight_lightdir, tempdiffusenormal); 
+               }
+               else
+               {
+                       // fetch the lighting from the worldmodel data
+                       VectorClear(ent->modellight_ambient);
+                       VectorClear(ent->modellight_diffuse);
+                       VectorClear(tempdiffusenormal);
+                       if (ent->flags & RENDER_LIGHT)
                        {
-                               if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
-                                       org[2] = org[2] + r_overheadsprites_pushback.value;
-                               R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
-                       }
-                       else
-                               R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
+                               vec3_t org;
+                               Matrix4x4_OriginFromMatrix(&ent->matrix, org);
 
-                       if(ent->flags & RENDER_EQUALIZE)
-                       {
-                               // first fix up ambient lighting...
-                               if(r_equalize_entities_minambient.value > 0)
+                               // complete lightning for lit sprites
+                               // todo: make a EF_ field so small ents could be lit purely by modellight and skipping real rtlight pass (like EF_NORTLIGHT)?
+                               if (ent->model->type == mod_sprite && !(ent->model->data_textures[0].basematerialflags & MATERIALFLAG_FULLBRIGHT))
+                               {
+                                       if (ent->model->sprite.sprnum_type == SPR_OVERHEAD) // apply offset for overhead sprites
+                                               org[2] = org[2] + r_overheadsprites_pushback.value;
+                                       R_LightPoint(ent->modellight_ambient, org, LP_LIGHTMAP | LP_RTWORLD | LP_DYNLIGHT);
+                               }
+                               else
+                                       R_CompleteLightPoint(ent->modellight_ambient, ent->modellight_diffuse, tempdiffusenormal, org, LP_LIGHTMAP);
+
+                               if(ent->flags & RENDER_EQUALIZE)
                                {
-                                       fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
-                                       if(fd > 0)
+                                       // first fix up ambient lighting...
+                                       if(r_equalize_entities_minambient.value > 0)
                                        {
-                                               fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
-                                               if(fa < r_equalize_entities_minambient.value * fd)
+                                               fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
+                                               if(fd > 0)
                                                {
-                                                       // solve:
-                                                       //   fa'/fd' = minambient
-                                                       //   fa'+0.25*fd' = fa+0.25*fd
-                                                       //   ...
-                                                       //   fa' = fd' * minambient
-                                                       //   fd'*(0.25+minambient) = fa+0.25*fd
-                                                       //   ...
-                                                       //   fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
-                                                       //   fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
-                                                       //   ...
-                                                       fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
-                                                       f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
-                                                       VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
-                                                       VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
+                                                       fa = (0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2]);
+                                                       if(fa < r_equalize_entities_minambient.value * fd)
+                                                       {
+                                                               // solve:
+                                                               //   fa'/fd' = minambient
+                                                               //   fa'+0.25*fd' = fa+0.25*fd
+                                                               //   ...
+                                                               //   fa' = fd' * minambient
+                                                               //   fd'*(0.25+minambient) = fa+0.25*fd
+                                                               //   ...
+                                                               //   fd' = (fa+0.25*fd) * 1 / (0.25+minambient)
+                                                               //   fa' = (fa+0.25*fd) * minambient / (0.25+minambient)
+                                                               //   ...
+                                                               fdd = (fa + 0.25f * fd) / (0.25f + r_equalize_entities_minambient.value);
+                                                               f = fdd / fd; // f>0 because all this is additive; f<1 because fdd<fd because this follows from fa < r_equalize_entities_minambient.value * fd
+                                                               VectorMA(ent->modellight_ambient, (1-f)*0.25f, ent->modellight_diffuse, ent->modellight_ambient);
+                                                               VectorScale(ent->modellight_diffuse, f, ent->modellight_diffuse);
+                                                       }
                                                }
                                        }
-                               }
 
-                               if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
-                               {
-                                       fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
-                                       fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
-                                       f = fa + 0.25 * fd;
-                                       if(f > 0)
+                                       if(r_equalize_entities_to.value > 0 && r_equalize_entities_by.value != 0)
                                        {
-                                               // adjust brightness and saturation to target
-                                               avg[0] = avg[1] = avg[2] = fa / f;
-                                               VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
-                                               avg[0] = avg[1] = avg[2] = fd / f;
-                                               VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
+                                               fa = 0.299f * ent->modellight_ambient[0] + 0.587f * ent->modellight_ambient[1] + 0.114f * ent->modellight_ambient[2];
+                                               fd = 0.299f * ent->modellight_diffuse[0] + 0.587f * ent->modellight_diffuse[1] + 0.114f * ent->modellight_diffuse[2];
+                                               f = fa + 0.25 * fd;
+                                               if(f > 0)
+                                               {
+                                                       // adjust brightness and saturation to target
+                                                       avg[0] = avg[1] = avg[2] = fa / f;
+                                                       VectorLerp(ent->modellight_ambient, r_equalize_entities_by.value, avg, ent->modellight_ambient);
+                                                       avg[0] = avg[1] = avg[2] = fd / f;
+                                                       VectorLerp(ent->modellight_diffuse, r_equalize_entities_by.value, avg, ent->modellight_diffuse);
+                                               }
                                        }
                                }
                        }
+                       else // highly rare
+                               VectorSet(ent->modellight_ambient, 1, 1, 1);
                }
-               else // highly rare
-                       VectorSet(ent->modellight_ambient, 1, 1, 1);
 
                // move the light direction into modelspace coordinates for lighting code
                Matrix4x4_Transform3x3(&ent->inversematrix, tempdiffusenormal, ent->modellight_lightdir);
index 5f95777..096634d 100644 (file)
@@ -1665,8 +1665,8 @@ void Mod_LoadQ3Shaders(void)
        int numparameters;
        char parameter[TEXTURE_MAXFRAMES + 4][Q3PATHLENGTH];
        char *custsurfaceparmnames[256]; // VorteX: q3map2 has 64 but well, someone will need more
-       unsigned long custsurfaceparms[256]; 
-       int numcustsurfaceparms;
+       unsigned long custsurfaceflags[256]; 
+       int numcustsurfaceflags;
        qboolean dpshaderkill;
 
        Mod_FreeQ3Shaders();
@@ -1680,7 +1680,7 @@ void Mod_LoadQ3Shaders(void)
                q3shaders_mem, sizeof (char**), 256);
 
        // parse custinfoparms.txt
-       numcustsurfaceparms = 0;
+       numcustsurfaceflags = 0;
        if ((text = f = (char *)FS_LoadFile("scripts/custinfoparms.txt", tempmempool, false, NULL)) != NULL)
        {
                if (!COM_ParseToken_QuakeC(&text, false) || strcasecmp(com_token, "{"))
@@ -1700,21 +1700,21 @@ void Mod_LoadQ3Shaders(void)
                                        if (!strcasecmp(com_token, "}"))
                                                break;  
                                        // register surfaceflag
-                                       if (numcustsurfaceparms >= 256)
+                                       if (numcustsurfaceflags >= 256)
                                        {
                                                Con_Printf("scripts/custinfoparms.txt: surfaceflags section parsing error - max 256 surfaceflags exceeded\n");
                                                break;
                                        }
                                        // name
                                        j = strlen(com_token)+1;
-                                       custsurfaceparmnames[numcustsurfaceparms] = (char *)Mem_Alloc(tempmempool, j);
-                                       strlcpy(custsurfaceparmnames[numcustsurfaceparms], com_token, j+1);
+                                       custsurfaceparmnames[numcustsurfaceflags] = (char *)Mem_Alloc(tempmempool, j);
+                                       strlcpy(custsurfaceparmnames[numcustsurfaceflags], com_token, j+1);
                                        // value
                                        if (COM_ParseToken_QuakeC(&text, false))
-                                               custsurfaceparms[numcustsurfaceparms] = strtol(com_token, NULL, 0);
+                                               custsurfaceflags[numcustsurfaceflags] = strtol(com_token, NULL, 0);
                                        else
-                                               custsurfaceparms[numcustsurfaceparms] = 0;
-                                       numcustsurfaceparms++;
+                                               custsurfaceflags[numcustsurfaceflags] = 0;
+                                       numcustsurfaceflags++;
                                }
                        }
                }
@@ -2134,16 +2134,16 @@ void Mod_LoadQ3Shaders(void)
                                        else
                                        {
                                                // try custom surfaceparms
-                                               for (j = 0; j < numcustsurfaceparms; j++)
+                                               for (j = 0; j < numcustsurfaceflags; j++)
                                                {
                                                        if (!strcasecmp(custsurfaceparmnames[j], parameter[1]))
                                                        {
-                                                               shader.surfaceparms |= custsurfaceparms[j];
+                                                               shader.surfaceflags |= custsurfaceflags[j];
                                                                break;
                                                        }
                                                }
                                                // failed all
-                                               if (j == numcustsurfaceparms)
+                                               if (j == numcustsurfaceflags)
                                                        Con_DPrintf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[fileindex], parameter[1]);
                                        }
                                }
@@ -2390,7 +2390,7 @@ void Mod_LoadQ3Shaders(void)
        }
        FS_FreeSearch(search);
        // free custinfoparm values
-       for (j = 0; j < numcustsurfaceparms; j++)
+       for (j = 0; j < numcustsurfaceflags; j++)
                Mem_Free(custsurfaceparmnames[j]);
 }
 
@@ -2637,7 +2637,7 @@ nothing                GL_ZERO GL_ONE
        //      if (shader->surfaceparms & Q3SURFACEPARM_LIGHTGRID    ) texture->supercontents |= SUPERCONTENTS_LIGHTGRID    ;
        //      if (shader->surfaceparms & Q3SURFACEPARM_ANTIPORTAL   ) texture->supercontents |= SUPERCONTENTS_ANTIPORTAL   ;
 
-               texture->surfaceflags = 0;
+               texture->surfaceflags = shader->surfaceflags;
                if (shader->surfaceparms & Q3SURFACEPARM_ALPHASHADOW  ) texture->surfaceflags |= Q3SURFACEFLAG_ALPHASHADOW  ;
        //      if (shader->surfaceparms & Q3SURFACEPARM_AREAPORTAL   ) texture->surfaceflags |= Q3SURFACEFLAG_AREAPORTAL   ;
        //      if (shader->surfaceparms & Q3SURFACEPARM_CLUSTERPORTAL) texture->surfaceflags |= Q3SURFACEFLAG_CLUSTERPORTAL;
index bd292ab..e1969ee 100644 (file)
@@ -432,6 +432,7 @@ typedef struct q3shaderinfo_s
        char name[Q3PATHLENGTH];
 #define Q3SHADERINFO_COMPARE_START surfaceparms
        int surfaceparms;
+       int surfaceflags;
        int textureflags;
        int numlayers;
        qboolean lighting;
diff --git a/progs.h b/progs.h
index 72813bb..62c71ea 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -25,6 +25,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 #define ENTITYGRIDAREAS 16
 #define MAX_ENTITYCLUSTERS 16
 
+#define        GEOMTYPE_BOX            1
+#define        GEOMTYPE_SPHERE         2
+#define        GEOMTYPE_CAPSULE        3
+#define        GEOMTYPE_TRIMESH        4
+#define        GEOMTYPE_CYLINDER       5
+
 #define JOINTTYPE_POINT 1
 #define JOINTTYPE_HINGE 2
 #define JOINTTYPE_SLIDER 3
index d194b1f..03cac11 100644 (file)
@@ -24,6 +24,7 @@ PRVM_DECLARE_clientfieldfloat(frame4time)
 PRVM_DECLARE_clientfieldfloat(gravity)
 PRVM_DECLARE_clientfieldfloat(ideal_yaw)
 PRVM_DECLARE_clientfieldfloat(idealpitch)
+PRVM_DECLARE_clientfieldfloat(geomtype)
 PRVM_DECLARE_clientfieldfloat(jointtype)
 PRVM_DECLARE_clientfieldfloat(lerpfrac)
 PRVM_DECLARE_clientfieldfloat(lerpfrac3)
@@ -31,6 +32,7 @@ PRVM_DECLARE_clientfieldfloat(lerpfrac4)
 PRVM_DECLARE_clientfieldfloat(mass)
 PRVM_DECLARE_clientfieldvector(massofs)
 PRVM_DECLARE_clientfieldfloat(friction)
+PRVM_DECLARE_clientfieldfloat(maxcontacts)
 PRVM_DECLARE_clientfieldfloat(erp)
 PRVM_DECLARE_clientfieldfloat(modelindex)
 PRVM_DECLARE_clientfieldfloat(movetype)
@@ -303,6 +305,7 @@ PRVM_DECLARE_field(idealpitch)
 PRVM_DECLARE_field(impulse)
 PRVM_DECLARE_field(items)
 PRVM_DECLARE_field(items2)
+PRVM_DECLARE_field(geomtype)
 PRVM_DECLARE_field(jointtype)
 PRVM_DECLARE_field(lerpfrac)
 PRVM_DECLARE_field(lerpfrac3)
@@ -312,6 +315,7 @@ PRVM_DECLARE_field(ltime)
 PRVM_DECLARE_field(mass)
 PRVM_DECLARE_field(massofs)
 PRVM_DECLARE_field(friction)
+PRVM_DECLARE_field(maxcontacts)
 PRVM_DECLARE_field(erp)
 PRVM_DECLARE_field(max_health)
 PRVM_DECLARE_field(maxs)
@@ -663,6 +667,7 @@ PRVM_DECLARE_serverfieldfloat(idealpitch)
 PRVM_DECLARE_serverfieldfloat(impulse)
 PRVM_DECLARE_serverfieldfloat(items)
 PRVM_DECLARE_serverfieldfloat(items2)
+PRVM_DECLARE_serverfieldfloat(geomtype)
 PRVM_DECLARE_serverfieldfloat(jointtype)
 PRVM_DECLARE_serverfieldfloat(lerpfrac)
 PRVM_DECLARE_serverfieldfloat(lerpfrac3)
@@ -672,6 +677,7 @@ PRVM_DECLARE_serverfieldfloat(ltime)
 PRVM_DECLARE_serverfieldfloat(mass)
 PRVM_DECLARE_serverfieldvector(massofs)
 PRVM_DECLARE_serverfieldfloat(friction)
+PRVM_DECLARE_serverfieldfloat(maxcontacts)
 PRVM_DECLARE_serverfieldfloat(erp)
 PRVM_DECLARE_serverfieldfloat(max_health)
 PRVM_DECLARE_serverfieldfloat(modelflags)
index 5d39960..18352ee 100644 (file)
--- a/server.h
+++ b/server.h
@@ -334,6 +334,7 @@ typedef struct client_s
 // LordHavoc: corpse code
 #define        SOLID_CORPSE                    5               ///< same as SOLID_BBOX, except it behaves as SOLID_NOT against SOLID_SLIDEBOX objects (players/monsters)
 // LordHavoc: physics
+// VorteX: now these fields are deprecated, as geomtype is more flexible
 #define        SOLID_PHYSICS_BOX               32              ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)
 #define        SOLID_PHYSICS_SPHERE    33              ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)
 #define        SOLID_PHYSICS_CAPSULE   34              ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)
diff --git a/world.c b/world.c
index fa1ccbc..e31a681 100644 (file)
--- a/world.c
+++ b/world.c
@@ -2045,7 +2045,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
        int movetype = MOVETYPE_NONE;
        int numtriangles;
        int numvertices;
-       int solid = SOLID_NOT;
+       int solid = SOLID_NOT, geomtype = 0;
        int triangleindex;
        int vertexindex;
        mempool_t *mempool;
@@ -2078,16 +2078,32 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
 #endif
        VectorClear(entmins);
        VectorClear(entmaxs);
+
        solid = (int)PRVM_gameedictfloat(ed, solid);
+       geomtype = (int)PRVM_gameedictfloat(ed, geomtype);
        movetype = (int)PRVM_gameedictfloat(ed, movetype);
        scale = PRVM_gameedictfloat(ed, scale);if (!scale) scale = 1.0f;
        modelindex = 0;
        mempool = prog->progs_mempool;
        model = NULL;
-       switch(solid)
+       if (!geomtype)
+       {
+               // VorteX: keep support for deprecated solid fields to not break mods
+               if (solid == SOLID_PHYSICS_TRIMESH || solid == SOLID_BSP)
+                       geomtype = GEOMTYPE_TRIMESH;
+               else if (solid == SOLID_PHYSICS_SPHERE)
+                       geomtype = GEOMTYPE_SPHERE;
+               else if (solid == SOLID_PHYSICS_CAPSULE)
+                       geomtype = GEOMTYPE_CAPSULE;
+               else if (solid == SOLID_PHYSICS_CYLINDER)
+                       geomtype = GEOMTYPE_CYLINDER;
+               else if (solid == SOLID_PHYSICS_BOX)
+                       geomtype = GEOMTYPE_BOX;
+               else
+                       geomtype = GEOMTYPE_BOX;
+       }
+       if (geomtype == GEOMTYPE_TRIMESH)
        {
-       case SOLID_BSP:
-       case SOLID_PHYSICS_TRIMESH:
                modelindex = (int)PRVM_gameedictfloat(ed, modelindex);
                if (world == &sv.world)
                        model = SV_GetModelByIndex(modelindex);
@@ -2106,18 +2122,16 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                        modelindex = 0;
                        massval = 1.0f;
                }
-               break;
-       case SOLID_BBOX:
-       //case SOLID_SLIDEBOX:
-       case SOLID_CORPSE:
-       case SOLID_PHYSICS_BOX:
-       case SOLID_PHYSICS_SPHERE:
-       case SOLID_PHYSICS_CAPSULE:
+       }
+       else if (geomtype)
+       {
                VectorCopy(PRVM_gameedictvector(ed, mins), entmins);
                VectorCopy(PRVM_gameedictvector(ed, maxs), entmaxs);
                massval = PRVM_gameedictfloat(ed, mass);
-               break;
-       default:
+       }
+       else
+       {
+               // geometry type not set, falling back
                if (ed->priv.server->ode_physics)
                        World_Physics_RemoveFromEntity(world, ed);
                return;
@@ -2169,10 +2183,9 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                        VectorSet(geomsize, 1.0f, 1.0f, 1.0f);
                }
 
-               switch(solid)
+               switch(geomtype)
                {
-               case SOLID_BSP:
-               case SOLID_PHYSICS_TRIMESH:
+               case GEOMTYPE_TRIMESH:
                        ed->priv.server->ode_offsetmatrix = identitymatrix;
                        if (!model)
                        {
@@ -2216,22 +2229,19 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, prvm_edict_t *ed)
                        ed->priv.server->ode_geom = (void *)dCreateTriMesh((dSpaceID)world->physics.ode_space, (dTriMeshDataID)dataID, NULL, NULL, NULL);
                        dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
                        break;
-               case SOLID_BBOX:
-               case SOLID_SLIDEBOX:
-               case SOLID_CORPSE:
-               case SOLID_PHYSICS_BOX:
+               case GEOMTYPE_BOX:
 treatasbox:
                        Matrix4x4_CreateTranslate(&ed->priv.server->ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
                        ed->priv.server->ode_geom = (void *)dCreateBox((dSpaceID)world->physics.ode_space, geomsize[0], geomsize[1], geomsize[2]);
                        dMassSetBoxTotal(&mass, massval, geomsize[0], geomsize[1], geomsize[2]);
                        break;
-               case SOLID_PHYSICS_SPHERE:
+               case GEOMTYPE_SPHERE:
                        Matrix4x4_CreateTranslate(&ed->priv.server->ode_offsetmatrix, geomcenter[0], geomcenter[1], geomcenter[2]);
                        ed->priv.server->ode_geom = (void *)dCreateSphere((dSpaceID)world->physics.ode_space, geomsize[0] * 0.5f);
                        dMassSetSphereTotal(&mass, massval, geomsize[0] * 0.5f);
                        break;
-               case SOLID_PHYSICS_CAPSULE:
-               case SOLID_PHYSICS_CYLINDER:
+               case GEOMTYPE_CAPSULE:
+               case GEOMTYPE_CYLINDER:
                        axisindex = 0;
                        if (geomsize[axisindex] < geomsize[1])
                                axisindex = 1;
@@ -2253,7 +2263,7 @@ treatasbox:
                        // because we want to support more than one axisindex, we have to
                        // create a transform, and turn on its cleanup setting (which will
                        // cause the child to be destroyed when it is destroyed)
-                       if (solid == SOLID_PHYSICS_CAPSULE)
+                       if (geomtype == GEOMTYPE_CYLINDER)
                        {
                                ed->priv.server->ode_geom = (void *)dCreateCapsule((dSpaceID)world->physics.ode_space, radius, length);
                                dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
@@ -2265,7 +2275,7 @@ treatasbox:
                        }
                        break;
                default:
-                       Sys_Error("World_Physics_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
+                       Sys_Error("World_Physics_BodyFromEntity: unrecognized geomtype value %i was accepted by filter\n", solid);
                        // this goto only exists to prevent warnings from the compiler
                        // about uninitialized variables (mass), while allowing it to
                        // catch legitimate uninitialized variable warnings
@@ -2443,9 +2453,9 @@ treatasbox:
                r[0][2] = up[0];
                r[1][2] = up[1];
                r[2][2] = up[2];
-               if(body)
+               if (body)
                {
-                       if(movetype == MOVETYPE_PHYSICS)
+                       if (movetype == MOVETYPE_PHYSICS)
                        {
                                dGeomSetBody((dGeomID)ed->priv.server->ode_geom, body);
                                dBodySetPosition(body, origin[0], origin[1], origin[2]);
@@ -2474,7 +2484,7 @@ treatasbox:
                }
        }
 
-       if(body)
+       if (body)
        {
 
                // limit movement speed to prevent missed collisions at high speed
@@ -2548,7 +2558,7 @@ static void nearCallback (void *data, dGeomID o1, dGeomID o2)
        // at least one object has to be using MOVETYPE_PHYSICS or we just don't care
        if (!b1 && !b2)
                return;
-
+       
        // exit without doing anything if the two bodies are connected by a joint
        if (b1 && b2 && dAreConnectedExcluding(b1, b2, dJointTypeContact))
                return;