X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;ds=sidebyside;f=model_brush.c;h=1ede5d8c588036458d08f2c9c4e1d5f299ddfe28;hb=40c576f6525015d3b5bebfd6a155ad0e989ed55e;hp=bf061151edbf31ec013cdce9dfbb932f2e4e1434;hpb=318f23befc1acd4cf7326a929738d37e1677da25;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.c b/model_brush.c index bf061151..1ede5d8c 100644 --- a/model_brush.c +++ b/model_brush.c @@ -36,8 +36,9 @@ cvar_t r_lightmaprgba = {0, "r_lightmaprgba", "1"}; cvar_t r_nosurftextures = {0, "r_nosurftextures", "0"}; cvar_t mod_q3bsp_curves_subdivide_level = {0, "mod_q3bsp_curves_subdivide_level", "2"}; cvar_t mod_q3bsp_curves_collisions = {0, "mod_q3bsp_curves_collisions", "1"}; -cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "1"}; +cvar_t mod_q3bsp_optimizedtraceline = {0, "mod_q3bsp_optimizedtraceline", "0"}; +static void Mod_Q1BSP_Collision_Init (void); void Mod_BrushInit(void) { // Cvar_RegisterVariable(&r_subdivide_size); @@ -50,6 +51,7 @@ void Mod_BrushInit(void) Cvar_RegisterVariable(&mod_q3bsp_curves_collisions); Cvar_RegisterVariable(&mod_q3bsp_optimizedtraceline); memset(mod_q1bsp_novis, 0xff, sizeof(mod_q1bsp_novis)); + Mod_Q1BSP_Collision_Init(); } static mleaf_t *Mod_Q1BSP_PointInLeaf(model_t *model, const vec3_t p) @@ -416,11 +418,17 @@ loc0: // if the first leaf is solid, set startsolid if (t->trace->allsolid) t->trace->startsolid = true; +#if COLLISIONPARANOID >= 3 + Con_Printf("S"); +#endif return HULLCHECKSTATE_SOLID; } else { t->trace->allsolid = false; +#if COLLISIONPARANOID >= 3 + Con_Printf("E"); +#endif return HULLCHECKSTATE_EMPTY; } } @@ -444,6 +452,9 @@ loc0: { if (t2 < 0) { +#if COLLISIONPARANOID >= 3 + Con_Printf("<"); +#endif num = node->children[1]; goto loc0; } @@ -453,6 +464,9 @@ loc0: { if (t2 >= 0) { +#if COLLISIONPARANOID >= 3 + Con_Printf(">"); +#endif num = node->children[0]; goto loc0; } @@ -461,6 +475,9 @@ loc0: // the line intersects, find intersection point // LordHavoc: this uses the original trace for maximum accuracy +#if COLLISIONPARANOID >= 3 + Con_Printf("M"); +#endif if (plane->type < 3) { t1 = t->start[plane->type] - plane->dist; @@ -506,10 +523,37 @@ loc0: midf = t1 / (t1 - t2); t->trace->fraction = bound(0.0f, midf, 1.0); +#if COLLISIONPARANOID >= 3 + Con_Printf("D"); +#endif return HULLCHECKSTATE_DONE; } -static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask) +#if COLLISIONPARANOID < 2 +static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, int num) +{ + while (num >= 0) + num = t->hull->clipnodes[num].children[(t->hull->planes[t->hull->clipnodes[num].planenum].type < 3 ? t->start[t->hull->planes[t->hull->clipnodes[num].planenum].type] : DotProduct(t->hull->planes[t->hull->clipnodes[num].planenum].normal, t->start)) < t->hull->planes[t->hull->clipnodes[num].planenum].dist]; + num = Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num); + t->trace->startsupercontents |= num; + if (num & SUPERCONTENTS_LIQUIDSMASK) + t->trace->inwater = true; + if (num == 0) + t->trace->inopen = true; + if (num & t->trace->hitsupercontentsmask) + { + t->trace->allsolid = t->trace->startsolid = true; + return HULLCHECKSTATE_SOLID; + } + else + { + t->trace->allsolid = t->trace->startsolid = false; + return HULLCHECKSTATE_EMPTY; + } +} +#endif + +static void Mod_Q1BSP_TraceBox(struct model_s *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask) { // this function currently only supports same size start and end double boxsize[3]; @@ -526,7 +570,9 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3 rhc.hull = &model->brushq1.hulls[0]; // 0x0x0 else if (model->brush.ishlbsp) { - if (boxsize[0] <= 32) + // LordHavoc: this has to have a minor tolerance (the .1) because of + // minor float precision errors from the box being transformed around + if (boxsize[0] < 32.1) { if (boxsize[2] < 54) // pick the nearest of 36 or 72 rhc.hull = &model->brushq1.hulls[3]; // 32x32x36 @@ -538,7 +584,9 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3 } else { - if (boxsize[0] <= 32) + // LordHavoc: this has to have a minor tolerance (the .1) because of + // minor float precision errors from the box being transformed around + if (boxsize[0] < 32.1) rhc.hull = &model->brushq1.hulls[1]; // 32x32x56 else rhc.hull = &model->brushq1.hulls[2]; // 64x64x88 @@ -546,7 +594,113 @@ static void Mod_Q1BSP_TraceBox(struct model_s *model, trace_t *trace, const vec3 VectorSubtract(boxstartmins, rhc.hull->clip_mins, rhc.start); VectorSubtract(boxendmins, rhc.hull->clip_mins, rhc.end); VectorSubtract(rhc.end, rhc.start, rhc.dist); +#if COLLISIONPARANOID >= 2 + Con_Printf("t(%f %f %f,%f %f %f,%i %f %f %f)", rhc.start[0], rhc.start[1], rhc.start[2], rhc.end[0], rhc.end[1], rhc.end[2], rhc.hull - model->brushq1.hulls, rhc.hull->clip_mins[0], rhc.hull->clip_mins[1], rhc.hull->clip_mins[2]); + Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end); + Con_Printf("\n"); +#else + if (DotProduct(rhc.dist, rhc.dist)) + Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end); + else + Mod_Q1BSP_RecursiveHullCheckPoint(&rhc, rhc.hull->firstclipnode); +#endif +} + +static hull_t box_hull; +static dclipnode_t box_clipnodes[6]; +static mplane_t box_planes[6]; + +static void Mod_Q1BSP_Collision_Init (void) +{ + int i; + int side; + + //Set up the planes and clipnodes so that the six floats of a bounding box + //can just be stored out and get a proper hull_t structure. + + box_hull.clipnodes = box_clipnodes; + box_hull.planes = box_planes; + box_hull.firstclipnode = 0; + box_hull.lastclipnode = 5; + + for (i = 0;i < 6;i++) + { + box_clipnodes[i].planenum = i; + + side = i&1; + + box_clipnodes[i].children[side] = CONTENTS_EMPTY; + if (i != 5) + box_clipnodes[i].children[side^1] = i + 1; + else + box_clipnodes[i].children[side^1] = CONTENTS_SOLID; + + box_planes[i].type = i>>1; + box_planes[i].normal[i>>1] = 1; + } +} + +void Collision_ClipTrace_Box(trace_t *trace, const vec3_t cmins, const vec3_t cmaxs, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int hitsupercontentsmask, int boxsupercontents) +{ +#if 1 + colbrushf_t cbox; + colplanef_t cbox_planes[6]; + cbox.supercontents = boxsupercontents; + cbox.numplanes = 6; + cbox.numpoints = 0; + cbox.numtriangles = 0; + cbox.planes = cbox_planes; + cbox.points = NULL; + cbox.elements = NULL; + cbox.markframe = 0; + cbox.mins[0] = 0; + cbox.mins[1] = 0; + cbox.mins[2] = 0; + cbox.maxs[0] = 0; + cbox.maxs[1] = 0; + cbox.maxs[2] = 0; + cbox_planes[0].normal[0] = 1;cbox_planes[0].normal[1] = 0;cbox_planes[0].normal[2] = 0;cbox_planes[0].dist = cmaxs[0] - mins[0]; + cbox_planes[1].normal[0] = -1;cbox_planes[1].normal[1] = 0;cbox_planes[1].normal[2] = 0;cbox_planes[1].dist = maxs[0] - cmins[0]; + cbox_planes[2].normal[0] = 0;cbox_planes[2].normal[1] = 1;cbox_planes[2].normal[2] = 0;cbox_planes[2].dist = cmaxs[1] - mins[1]; + cbox_planes[3].normal[0] = 0;cbox_planes[3].normal[1] = -1;cbox_planes[3].normal[2] = 0;cbox_planes[3].dist = maxs[1] - cmins[1]; + cbox_planes[4].normal[0] = 0;cbox_planes[4].normal[1] = 0;cbox_planes[4].normal[2] = 1;cbox_planes[4].dist = cmaxs[2] - mins[2]; + cbox_planes[5].normal[0] = 0;cbox_planes[5].normal[1] = 0;cbox_planes[5].normal[2] = -1;cbox_planes[5].dist = maxs[2] - cmins[2]; + memset(trace, 0, sizeof(trace_t)); + trace->hitsupercontentsmask = hitsupercontentsmask; + trace->fraction = 1; + Collision_TraceLineBrushFloat(trace, start, end, &cbox, &cbox); +#else + RecursiveHullCheckTraceInfo_t rhc; + // fill in a default trace + memset(&rhc, 0, sizeof(rhc)); + memset(trace, 0, sizeof(trace_t)); + //To keep everything totally uniform, bounding boxes are turned into small + //BSP trees instead of being compared directly. + // create a temp hull from bounding box sizes + box_planes[0].dist = cmaxs[0] - mins[0]; + box_planes[1].dist = cmins[0] - maxs[0]; + box_planes[2].dist = cmaxs[1] - mins[1]; + box_planes[3].dist = cmins[1] - maxs[1]; + box_planes[4].dist = cmaxs[2] - mins[2]; + box_planes[5].dist = cmins[2] - maxs[2]; +#if COLLISIONPARANOID >= 3 + Con_Printf("box_planes %f:%f %f:%f %f:%f\ncbox %f %f %f:%f %f %f\nbox %f %f %f:%f %f %f\n", box_planes[0].dist, box_planes[1].dist, box_planes[2].dist, box_planes[3].dist, box_planes[4].dist, box_planes[5].dist, cmins[0], cmins[1], cmins[2], cmaxs[0], cmaxs[1], cmaxs[2], mins[0], mins[1], mins[2], maxs[0], maxs[1], maxs[2]); +#endif + // trace a line through the generated clipping hull + //rhc.boxsupercontents = boxsupercontents; + rhc.hull = &box_hull; + rhc.trace = trace; + rhc.trace->hitsupercontentsmask = hitsupercontentsmask; + rhc.trace->fraction = 1; + rhc.trace->allsolid = true; + VectorCopy(start, rhc.start); + VectorCopy(end, rhc.end); + VectorSubtract(rhc.end, rhc.start, rhc.dist); Mod_Q1BSP_RecursiveHullCheck(&rhc, rhc.hull->firstclipnode, 0, 1, rhc.start, rhc.end); + VectorMA(rhc.start, rhc.trace->fraction, rhc.dist, rhc.trace->endpos); + if (rhc.trace->startsupercontents) + rhc.trace->startsupercontents = boxsupercontents; +#endif } static int Mod_Q1BSP_LightPoint_RecursiveBSPNode(vec3_t ambientcolor, vec3_t diffusecolor, vec3_t diffusenormal, const mnode_t *node, float x, float y, float startz, float endz) @@ -709,6 +863,11 @@ static void Mod_Q1BSP_DecompressVis(const qbyte *in, const qbyte *inend, qbyte * *out++ = c; else { + if (in == inend) + { + Con_DPrintf("Mod_Q1BSP_DecompressVis: input underrun on model \"%s\"\n", loadmodel->name); + return; + } for (c = *in++;c > 0;c--) { if (out == outend) @@ -1840,7 +1999,7 @@ static void Mod_Q1BSP_LoadLeafs(lump_t *l) pvs += pvschainbytes; p = LittleLong(in->visofs); - if (p >= 0) + if (p >= 0 && i > 0) // ignore visofs errors on leaf 0 (solid) { if (p >= loadmodel->brushq1.num_compressedpvs) Con_Printf("Mod_Q1BSP_LoadLeafs: invalid visofs\n"); @@ -2660,6 +2819,8 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) Host_Error("Mod_Q1BSP_Load: %s has wrong version number(%i should be %i(Quake) or 30(HalfLife))", mod->name, i, BSPVERSION); mod->brush.ishlbsp = i == 30; + mod->soundfromcenter = true; + mod->TraceBox = Mod_Q1BSP_TraceBox; mod->brush.SuperContentsFromNativeContents = Mod_Q1BSP_SuperContentsFromNativeContents; mod->brush.NativeContentsFromSuperContents = Mod_Q1BSP_NativeContentsFromSuperContents; mod->brush.GetPVS = Mod_Q1BSP_GetPVS; @@ -2667,7 +2828,6 @@ void Mod_Q1BSP_Load(model_t *mod, void *buffer) mod->brush.BoxTouchingPVS = Mod_Q1BSP_BoxTouchingPVS; mod->brush.LightPoint = Mod_Q1BSP_LightPoint; mod->brush.FindNonSolidLocation = Mod_Q1BSP_FindNonSolidLocation; - mod->brush.TraceBox = Mod_Q1BSP_TraceBox; mod->brush.AmbientSoundLevelsForPoint = Mod_Q1BSP_AmbientSoundLevelsForPoint; mod->brush.RoundUpToHullSize = Mod_Q1BSP_RoundUpToHullSize; mod->brushq1.PointInLeaf = Mod_Q1BSP_PointInLeaf; @@ -3303,6 +3463,12 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) q3dtexture_t *in; q3mtexture_t *out; int i, count; + int j, c; + fssearch_t *search; + char *f; + const char *text; + int flags; + char shadername[Q3PATHLENGTH]; in = (void *)(mod_base + l->fileofs); if (l->filelen % sizeof(*in)) @@ -3315,19 +3481,157 @@ static void Mod_Q3BSP_LoadTextures(lump_t *l) for (i = 0;i < count;i++, in++, out++) { + out->number = i; strlcpy (out->name, in->name, sizeof (out->name)); out->surfaceflags = LittleLong(in->surfaceflags); out->nativecontents = LittleLong(in->contents); out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents); - out->renderflags = 0; - if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk")) - out->renderflags |= Q3MTEXTURERENDERFLAGS_NODRAW; - if (!strncmp(out->name, "textures/skies/", 15)) - out->renderflags |= Q3MTEXTURERENDERFLAGS_SKY; - - out->number = i; Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true); + out->surfaceparms = -1; + } + + // do a quick parse of shader files to get surfaceparms + if ((search = FS_Search("scripts/*.shader", true, false))) + { + for (i = 0;i < search->numfilenames;i++) + { + if ((f = FS_LoadFile(search->filenames[i], false))) + { + text = f; + while (COM_ParseToken(&text, false)) + { + snprintf(shadername, sizeof(shadername), "%s", com_token); + flags = 0; + if (COM_ParseToken(&text, false) && !strcmp(com_token, "{")) + { + while (COM_ParseToken(&text, false)) + { + if (!strcmp(com_token, "}")) + break; + else if (!strcmp(com_token, "{")) + { + while (COM_ParseToken(&text, false)) + { + if (!strcmp(com_token, "}")) + break; + } + } + else if (!strcmp(com_token, "surfaceparm")) + { + if (COM_ParseToken(&text, true) && strcmp(com_token, "\n")) + { + if (!strcmp(com_token, "alphashadow")) + flags |= Q3SURFACEPARM_ALPHASHADOW; + else if (!strcmp(com_token, "areaportal")) + flags |= Q3SURFACEPARM_AREAPORTAL; + else if (!strcmp(com_token, "clusterportal")) + flags |= Q3SURFACEPARM_CLUSTERPORTAL; + else if (!strcmp(com_token, "detail")) + flags |= Q3SURFACEPARM_DETAIL; + else if (!strcmp(com_token, "donotenter")) + flags |= Q3SURFACEPARM_DONOTENTER; + else if (!strcmp(com_token, "fog")) + flags |= Q3SURFACEPARM_FOG; + else if (!strcmp(com_token, "lava")) + flags |= Q3SURFACEPARM_LAVA; + else if (!strcmp(com_token, "lightfilter")) + flags |= Q3SURFACEPARM_LIGHTFILTER; + else if (!strcmp(com_token, "metalsteps")) + flags |= Q3SURFACEPARM_METALSTEPS; + else if (!strcmp(com_token, "nodamage")) + flags |= Q3SURFACEPARM_NODAMAGE; + else if (!strcmp(com_token, "nodlight")) + flags |= Q3SURFACEPARM_NODLIGHT; + else if (!strcmp(com_token, "nodraw")) + flags |= Q3SURFACEPARM_NODRAW; + else if (!strcmp(com_token, "nodrop")) + flags |= Q3SURFACEPARM_NODROP; + else if (!strcmp(com_token, "noimpact")) + flags |= Q3SURFACEPARM_NOIMPACT; + else if (!strcmp(com_token, "nolightmap")) + flags |= Q3SURFACEPARM_NOLIGHTMAP; + else if (!strcmp(com_token, "nomarks")) + flags |= Q3SURFACEPARM_NOMARKS; + else if (!strcmp(com_token, "nomipmaps")) + flags |= Q3SURFACEPARM_NOMIPMAPS; + else if (!strcmp(com_token, "nonsolid")) + flags |= Q3SURFACEPARM_NONSOLID; + else if (!strcmp(com_token, "origin")) + flags |= Q3SURFACEPARM_ORIGIN; + else if (!strcmp(com_token, "playerclip")) + flags |= Q3SURFACEPARM_PLAYERCLIP; + else if (!strcmp(com_token, "sky")) + flags |= Q3SURFACEPARM_SKY; + else if (!strcmp(com_token, "slick")) + flags |= Q3SURFACEPARM_SLICK; + else if (!strcmp(com_token, "slime")) + flags |= Q3SURFACEPARM_SLIME; + else if (!strcmp(com_token, "structural")) + flags |= Q3SURFACEPARM_STRUCTURAL; + else if (!strcmp(com_token, "trans")) + flags |= Q3SURFACEPARM_TRANS; + else if (!strcmp(com_token, "water")) + flags |= Q3SURFACEPARM_WATER; + else + Con_Printf("%s parsing warning: unknown surfaceparm \"%s\"\n", search->filenames[i], com_token); + if (!COM_ParseToken(&text, true) || strcmp(com_token, "\n")) + { + Con_Printf("%s parsing error: surfaceparm only takes one parameter.\n", search->filenames[i]); + goto parseerror; + } + } + else + { + Con_Printf("%s parsing error: surfaceparm expects a parameter.\n", search->filenames[i]); + goto parseerror; + } + } + else + { + // look for linebreak or } + while(COM_ParseToken(&text, true) && strcmp(com_token, "\n") && strcmp(com_token, "}")); + // break out to top level if it was } + if (!strcmp(com_token, "}")) + break; + } + } + // add shader to list (shadername and flags) + // actually here we just poke into the texture settings + for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + if (!strcmp(out->name, shadername)) + out->surfaceparms = flags; + } + else + { + Con_Printf("%s parsing error - expected \"{\", found \"%s\"\n", search->filenames[i], com_token); + goto parseerror; + } + } +parseerror: + Mem_Free(f); + } + } + } + + c = 0; + for (j = 0, out = loadmodel->brushq3.data_textures;j < loadmodel->brushq3.num_textures;j++, out++) + { + if (out->surfaceparms == -1) + { + c++; + Con_DPrintf("%s: No shader found for texture \"%s\"\n", loadmodel->name, out->name); + out->surfaceparms = 0; + // these are defaults + if (!strcmp(out->name, "caulk") || !strcmp(out->name, "common/caulk") || !strcmp(out->name, "textures/common/caulk") + || !strcmp(out->name, "nodraw") || !strcmp(out->name, "common/nodraw") || !strcmp(out->name, "textures/common/nodraw")) + out->surfaceparms |= Q3SURFACEPARM_NODRAW; + if (!strncmp(out->name, "textures/skies/", 15)) + out->surfaceparms |= Q3SURFACEPARM_SKY; + if (R_TextureHasAlpha(out->skin.base)) + out->surfaceparms |= Q3SURFACEPARM_TRANS; + } } + Con_DPrintf("%s: %i textures missing shaders\n", loadmodel->name, c); } static void Mod_Q3BSP_LoadPlanes(lump_t *l) @@ -4172,9 +4476,9 @@ static void Mod_Q3BSP_LightPoint(model_t *model, const vec3_t p, vec3_t ambientc // FIXME: write this if (!model->brushq3.num_lightgrid) { - ambientcolor[0] += 128; - ambientcolor[1] += 128; - ambientcolor[2] += 128; + ambientcolor[0] = 1; + ambientcolor[1] = 1; + ambientcolor[2] = 1; return; } Matrix4x4_Transform(&model->brushq3.num_lightgrid_indexfromworld, p, transformed); @@ -4377,7 +4681,7 @@ static void Mod_Q3BSP_TraceBrush_RecursiveBSPNode(trace_t *trace, q3mnode_t *nod } } -static void Mod_Q3BSP_TraceBox(model_t *model, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask) +static void Mod_Q3BSP_TraceBox(model_t *model, int frame, trace_t *trace, const vec3_t boxstartmins, const vec3_t boxstartmaxs, const vec3_t boxendmins, const vec3_t boxendmaxs, int hitsupercontentsmask) { int i; float segmentmins[3], segmentmaxs[3]; @@ -4589,6 +4893,8 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) R_ResetQuakeSky(); } + mod->soundfromcenter = true; + mod->TraceBox = Mod_Q3BSP_TraceBox; mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents; mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents; mod->brush.GetPVS = Mod_Q3BSP_GetPVS; @@ -4596,7 +4902,6 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->brush.BoxTouchingPVS = Mod_Q3BSP_BoxTouchingPVS; mod->brush.LightPoint = Mod_Q3BSP_LightPoint; mod->brush.FindNonSolidLocation = Mod_Q3BSP_FindNonSolidLocation; - mod->brush.TraceBox = Mod_Q3BSP_TraceBox; //mod->DrawSky = R_Q3BSP_DrawSky; mod->Draw = R_Q3BSP_Draw; mod->DrawShadowVolume = R_Q3BSP_DrawShadowVolume; @@ -4667,7 +4972,7 @@ void Mod_Q3BSP_Load(model_t *mod, void *buffer) mod->radius2 = modelradius * modelradius; for (j = 0;j < mod->brushq3.data_thismodel->numfaces;j++) - if (mod->brushq3.data_thismodel->firstface[j].texture->renderflags & Q3MTEXTURERENDERFLAGS_SKY) + if (mod->brushq3.data_thismodel->firstface[j].texture->surfaceflags & Q3SURFACEFLAG_SKY) break; if (j < mod->brushq3.data_thismodel->numfaces) mod->DrawSky = R_Q3BSP_DrawSky;