]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - model_brush.c
changed some prints to dprints
[xonotic/darkplaces.git] / model_brush.c
index 0e7e0485199ed1f417e6c10c00933fa2613bfaac..6cc700f199ebffd1fe2b9ee64e3100fe919392dc 100644 (file)
@@ -43,7 +43,7 @@ cvar_t r_subdivisions_collision_maxvertices = {0, "r_subdivisions_collision_maxv
 cvar_t mod_q3bsp_curves_collisions = {0, "mod_q3bsp_curves_collisions", "1", "enables collisions with curves (SLOW)"};
 cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "1", "whether to use optimized traceline code for line traces (as opposed to tracebox code)"};
 cvar_t mod_q3bsp_debugtracebrush = {0, "mod_q3bsp_debugtracebrush", "0", "selects different tracebrush bsp recursion algorithms (for debugging purposes only)"};
-cvar_t mod_q3bsp_lightmapmergepower = {CVAR_SAVE, "mod_q3bsp_lightmapmergepower", "5", "merges the quake3 128x128 lightmap textures into larger lightmap group textures to speed up rendering, 1 = 256x256, 2 = 512x512, 3 = 1024x1024, 4 = 2048x2048, 5 = 4096x4096, ..."};
+cvar_t mod_q3bsp_lightmapmergepower = {CVAR_SAVE, "mod_q3bsp_lightmapmergepower", "4", "merges the quake3 128x128 lightmap textures into larger lightmap group textures to speed up rendering, 1 = 256x256, 2 = 512x512, 3 = 1024x1024, 4 = 2048x2048, 5 = 4096x4096, ..."};
 
 static texture_t mod_q1bsp_texture_solid;
 static texture_t mod_q1bsp_texture_sky;
@@ -1193,9 +1193,17 @@ middle sample (the one which was requested)
 
 void Mod_Q1BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal)
 {
-       Mod_Q1BSP_LightPoint_RecursiveBSPNode(model, ambientcolor, diffusecolor, diffusenormal, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2] + 0.125, p[2] - 65536);
        // pretend lighting is coming down from above (due to lack of a lightgrid to know primary lighting direction)
        VectorSet(diffusenormal, 0, 0, 1);
+
+       if (!model->brushq1.lightdata)
+       {
+               VectorSet(ambientcolor, 1, 1, 1);
+               VectorSet(diffusecolor, 0, 0, 0);
+               return;
+       }
+
+       Mod_Q1BSP_LightPoint_RecursiveBSPNode(model, ambientcolor, diffusecolor, diffusenormal, model->brush.data_nodes + model->brushq1.hulls[0].firstclipnode, p[0], p[1], p[2] + 0.125, p[2] - 65536);
 }
 
 static void Mod_Q1BSP_DecompressVis(const unsigned char *in, const unsigned char *inend, unsigned char *out, unsigned char *outend)
@@ -3406,9 +3414,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer, void *bufferend)
        // check if the map supports transparent water rendering
        loadmodel->brush.supportwateralpha = Mod_Q1BSP_CheckWaterAlphaSupport();
 
-       if (!mod->brushq1.lightdata)
-               mod->brush.LightPoint = NULL;
-
        if (mod->brushq1.data_compressedpvs)
                Mem_Free(mod->brushq1.data_compressedpvs);
        mod->brushq1.data_compressedpvs = NULL;
@@ -4398,8 +4403,11 @@ static void Mod_Q3BSP_LoadShaders(void)
                        // identify if this is a blended terrain shader or similar
                        if (shader->numlayers)
                        {
+                               shader->backgroundlayer = NULL;
                                shader->primarylayer = shader->layers + 0;
-                               if ((shader->layers[1].blendfunc[0] == GL_SRC_ALPHA && shader->layers[1].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA) || shader->layers[1].alphatest)
+                               if ((shader->layers[0].blendfunc[0] == GL_ONE       && shader->layers[0].blendfunc[1] == GL_ZERO                && !shader->layers[0].alphatest)
+                               && ((shader->layers[1].blendfunc[0] == GL_SRC_ALPHA && shader->layers[1].blendfunc[1] == GL_ONE_MINUS_SRC_ALPHA && !shader->layers[0].alphatest)
+                               ||  (shader->layers[1].blendfunc[0] == GL_ONE       && shader->layers[1].blendfunc[1] == GL_ZERO                &&  shader->layers[1].alphatest)))
                                {
                                        // terrain blending or other effects
                                        shader->backgroundlayer = shader->layers + 0;
@@ -4407,7 +4415,10 @@ static void Mod_Q3BSP_LoadShaders(void)
                                }
                                // now see if the lightmap came first, and if so choose the second texture instead
                                if (!strcasecmp(shader->primarylayer->texturename[0], "$lightmap"))
+                               {
+                                       shader->backgroundlayer = NULL;
                                        shader->primarylayer = shader->layers + 1;
+                               }
                        }
                }
                Mem_Free(f);
@@ -4475,7 +4486,9 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l)
                                out->basematerialflags |= MATERIALFLAG_WALL;
                        if (shader->layers[0].alphatest)
                                out->basematerialflags |= MATERIALFLAG_ALPHATEST | MATERIALFLAG_TRANSPARENT | MATERIALFLAG_NOSHADOW;
-                       if (shader->textureflags & (Q3TEXTUREFLAG_TWOSIDED | Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
+                       if (shader->textureflags & Q3TEXTUREFLAG_TWOSIDED)
+                               out->basematerialflags |= MATERIALFLAG_NOSHADOW | MATERIALFLAG_NOCULLFACE;
+                       if (shader->textureflags & (Q3TEXTUREFLAG_AUTOSPRITE | Q3TEXTUREFLAG_AUTOSPRITE2))
                                out->basematerialflags |= MATERIALFLAG_NOSHADOW;
                        out->customblendfunc[0] = GL_ONE;
                        out->customblendfunc[1] = GL_ZERO;
@@ -4525,7 +4538,7 @@ Q3 shader blendfuncs actually used in the game (* = supported by DP)
                                out->skinframerate = shader->primarylayer->framerate;
                                for (j = 0;j < shader->primarylayer->numframes;j++)
                                        if (!Mod_LoadSkinFrame(&out->skinframes[j], shader->primarylayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP) | (shader->primarylayer->clampmap ? TEXF_CLAMP : 0), false, true))
-                                               Con_Printf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->primarylayer->texturename[j], j, out->name);
+                                               Con_DPrintf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->primarylayer->texturename[j], j, out->name);
                        }
                        if (shader->backgroundlayer && cls.state != ca_dedicated)
                        {
@@ -4534,7 +4547,7 @@ Q3 shader blendfuncs actually used in the game (* = supported by DP)
                                out->backgroundskinframerate = shader->backgroundlayer->framerate;
                                for (j = 0;j < shader->backgroundlayer->numframes;j++)
                                        if (!Mod_LoadSkinFrame(&out->backgroundskinframes[j], shader->backgroundlayer->texturename[j], ((shader->surfaceparms & Q3SURFACEPARM_NOMIPMAPS) ? 0 : TEXF_MIPMAP) | TEXF_ALPHA | TEXF_PRECACHE | (shader->textureflags & Q3TEXTUREFLAG_NOPICMIP ? 0 : TEXF_PICMIP) | (shader->backgroundlayer->clampmap ? TEXF_CLAMP : 0), false, true))
-                                               Con_Printf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->backgroundlayer->texturename[j], j, out->name);
+                                               Con_DPrintf("%s: could not load texture \"%s\" (frame %i) for shader \"%s\"\n", loadmodel->name, shader->backgroundlayer->texturename[j], j, out->name);
                        }
                }
                else if (!strcmp(out->name, "noshader"))
@@ -4560,7 +4573,7 @@ Q3 shader blendfuncs actually used in the game (* = supported by DP)
                        //      out->surfaceparms |= Q3SURFACEPARM_TRANS;
                        if (cls.state != ca_dedicated)
                                if (!Mod_LoadSkinFrame(&out->skinframes[0], out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE | TEXF_PICMIP, false, true))
-                                       Con_Printf("%s: could not load texture for missing shader \"%s\"\n", loadmodel->name, out->name);
+                                       Con_DPrintf("%s: could not load texture for missing shader \"%s\"\n", loadmodel->name, out->name);
                }
                // init the animation variables
                out->currentframe = out;
@@ -4776,10 +4789,13 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
 
        if (!l->filelen)
                return;
+       if (cls.state == ca_dedicated)
+               return;
        in = (q3dlightmap_t *)(mod_base + l->fileofs);
        if (l->filelen % sizeof(*in))
                Host_Error("Mod_Q3BSP_LoadLightmaps: funny lump size in %s",loadmodel->name);
        count = l->filelen / sizeof(*in);
+       loadmodel->brushq3.num_originallightmaps = count;
 
        // now check the surfaces to see if any of them index an odd numbered
        // lightmap, if so this is not a deluxemapped bsp file
@@ -4790,6 +4806,8 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
        // reason when only one lightmap is used, which can throw off the
        // deluxemapping detection method, so check 2-lightmap bsp's specifically
        // to see if the second lightmap is blank, if so it is not deluxemapped.
+       loadmodel->brushq3.deluxemapping = !(count & 1);
+       loadmodel->brushq3.deluxemapping_modelspace = true;
        endlightmap = 0;
        if (loadmodel->brushq3.deluxemapping)
        {
@@ -4837,18 +4855,18 @@ static void Mod_Q3BSP_LoadLightmaps(lump_t *l, lump_t *faceslump)
                loadmodel->brushq3.num_lightmapmergepower = power;
        loadmodel->brushq3.num_lightmapmerge = 1 << loadmodel->brushq3.num_lightmapmergepower;
 
-       loadmodel->brushq3.num_lightmaps = ((count >> loadmodel->brushq3.deluxemapping) + (1 << (loadmodel->brushq3.num_lightmapmergepower * 2)) - 1) >> (loadmodel->brushq3.num_lightmapmergepower * 2);
-       loadmodel->brushq3.data_lightmaps = (rtexture_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brushq3.num_lightmaps * sizeof(rtexture_t *));
+       loadmodel->brushq3.num_mergedlightmaps = ((count >> loadmodel->brushq3.deluxemapping) + (1 << (loadmodel->brushq3.num_lightmapmergepower * 2)) - 1) >> (loadmodel->brushq3.num_lightmapmergepower * 2);
+       loadmodel->brushq3.data_lightmaps = (rtexture_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brushq3.num_mergedlightmaps * sizeof(rtexture_t *));
        if (loadmodel->brushq3.deluxemapping)
-               loadmodel->brushq3.data_deluxemaps = (rtexture_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brushq3.num_lightmaps * sizeof(rtexture_t *));
+               loadmodel->brushq3.data_deluxemaps = (rtexture_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brushq3.num_mergedlightmaps * sizeof(rtexture_t *));
 
        j = 128 << loadmodel->brushq3.num_lightmapmergepower;
        if (loadmodel->brushq3.data_lightmaps)
-               for (i = 0;i < loadmodel->brushq3.num_lightmaps;i++)
+               for (i = 0;i < loadmodel->brushq3.num_mergedlightmaps;i++)
                        loadmodel->brushq3.data_lightmaps[i] = R_LoadTexture2D(loadmodel->texturepool, va("lightmap%04i", i), j, j, NULL, TEXTYPE_RGB, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
 
        if (loadmodel->brushq3.data_deluxemaps)
-               for (i = 0;i < loadmodel->brushq3.num_lightmaps;i++)
+               for (i = 0;i < loadmodel->brushq3.num_mergedlightmaps;i++)
                        loadmodel->brushq3.data_deluxemaps[i] = R_LoadTexture2D(loadmodel->texturepool, va("deluxemap%04i", i), j, j, NULL, TEXTYPE_RGB, TEXF_FORCELINEAR | TEXF_PRECACHE, NULL);
 
        power = loadmodel->brushq3.num_lightmapmergepower;
@@ -4928,21 +4946,24 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                else
                        out->effect = loadmodel->brushq3.data_effects + n;
 
-               out->lightmaptexture = NULL;
-               out->deluxemaptexture = r_texture_blanknormalmap;
-               n = LittleLong(in->lightmapindex);
-               if (n < 0)
-                       n = -1;
-               else if (n >= (loadmodel->brushq3.num_lightmaps << (loadmodel->brushq3.num_lightmapmergepower * 2)))
-               {
-                       Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->texture->name, n, loadmodel->brushq3.num_lightmaps);
-                       n = -1;
-               }
-               else
+               if (cls.state != ca_dedicated)
                {
-                       out->lightmaptexture = loadmodel->brushq3.data_lightmaps[n >> (loadmodel->brushq3.num_lightmapmergepower * 2 + loadmodel->brushq3.deluxemapping)];
-                       if (loadmodel->brushq3.deluxemapping)
-                               out->deluxemaptexture = loadmodel->brushq3.data_deluxemaps[n >> (loadmodel->brushq3.num_lightmapmergepower * 2 + loadmodel->brushq3.deluxemapping)];
+                       out->lightmaptexture = NULL;
+                       out->deluxemaptexture = r_texture_blanknormalmap;
+                       n = LittleLong(in->lightmapindex);
+                       if (n < 0)
+                               n = -1;
+                       else if (n >= loadmodel->brushq3.num_originallightmaps)
+                       {
+                               Con_Printf("Mod_Q3BSP_LoadFaces: face #%i (texture \"%s\"): invalid lightmapindex %i (%i lightmaps)\n", i, out->texture->name, n, loadmodel->brushq3.num_originallightmaps);
+                               n = -1;
+                       }
+                       else
+                       {
+                               out->lightmaptexture = loadmodel->brushq3.data_lightmaps[n >> (loadmodel->brushq3.num_lightmapmergepower * 2 + loadmodel->brushq3.deluxemapping)];
+                               if (loadmodel->brushq3.deluxemapping)
+                                       out->deluxemaptexture = loadmodel->brushq3.data_deluxemaps[n >> (loadmodel->brushq3.num_lightmapmergepower * 2 + loadmodel->brushq3.deluxemapping)];
+                       }
                }
 
                firstvertex = LittleLong(in->firstvertex);
@@ -5164,7 +5185,7 @@ static void Mod_Q3BSP_LoadFaces(lump_t *l)
                if (out->num_vertices)
                {
                        int lightmapindex = LittleLong(in->lightmapindex);
-                       if (lightmapindex >= 0)
+                       if (lightmapindex >= 0 && cls.state != ca_dedicated)
                        {
                                lightmapindex >>= loadmodel->brushq3.deluxemapping;
                                lightmaptcscale = 1.0f / loadmodel->brushq3.num_lightmapmerge;
@@ -6076,3 +6097,39 @@ void Mod_MAP_Load(model_t *mod, void *buffer, void *bufferend)
        Host_Error("Mod_MAP_Load: not yet implemented");
 }
 
+qboolean Mod_CanSeeBox_Trace(int numsamples, float t, model_t *model, vec3_t eye, vec3_t minsX, vec3_t maxsX)
+{
+       // we already have done PVS culling at this point...
+       // so we don't need to do it again.
+
+       int i;
+       vec3_t testorigin, mins, maxs;
+
+       testorigin[0] = (minsX[0] + maxsX[0]) * 0.5;
+       testorigin[1] = (minsX[1] + maxsX[1]) * 0.5;
+       testorigin[2] = (minsX[2] + maxsX[2]) * 0.5;
+
+       if(model->brush.TraceLineOfSight(model, eye, testorigin))
+               return 1;
+
+       // expand the box a little
+       mins[0] = (t+1) * minsX[0] - t * maxsX[0];
+       maxs[0] = (t+1) * maxsX[0] - t * minsX[0];
+       mins[1] = (t+1) * minsX[1] - t * maxsX[1];
+       maxs[1] = (t+1) * maxsX[1] - t * minsX[1];
+       mins[2] = (t+1) * minsX[2] - t * maxsX[2];
+       maxs[2] = (t+1) * maxsX[2] - t * minsX[2];
+
+       for(i = 0; i != numsamples; ++i)
+       {
+               testorigin[0] = lhrandom(mins[0], maxs[0]);
+               testorigin[1] = lhrandom(mins[1], maxs[1]);
+               testorigin[2] = lhrandom(mins[2], maxs[2]);
+
+               if(model->brush.TraceLineOfSight(model, eye, testorigin))
+                       return 1;
+       }
+
+       return 0;
+}
+