// if the first leaf is solid, set startsolid
if (t->trace->allsolid)
t->trace->startsolid = true;
+#ifdef COLLISIONPARANOID
+ Con_Printf("S");
+#endif
return HULLCHECKSTATE_SOLID;
}
else
{
t->trace->allsolid = false;
+#ifdef COLLISIONPARANOID
+ Con_Printf("E");
+#endif
return HULLCHECKSTATE_EMPTY;
}
}
{
if (t2 < 0)
{
+#ifdef COLLISIONPARANOID
+ Con_Printf("<");
+#endif
num = node->children[1];
goto loc0;
}
{
if (t2 >= 0)
{
+#ifdef COLLISIONPARANOID
+ Con_Printf(">");
+#endif
num = node->children[0];
goto loc0;
}
// the line intersects, find intersection point
// LordHavoc: this uses the original trace for maximum accuracy
+#ifdef COLLISIONPARANOID
+ Con_Printf("M");
+#endif
if (plane->type < 3)
{
t1 = t->start[plane->type] - plane->dist;
midf = t1 / (t1 - t2);
t->trace->fraction = bound(0.0f, midf, 1.0);
+#ifdef COLLISIONPARANOID
+ Con_Printf("D");
+#endif
return HULLCHECKSTATE_DONE;
}
+#ifndef COLLISIONPARANOID
+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
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
}
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
VectorSubtract(boxstartmins, rhc.hull->clip_mins, rhc.start);
VectorSubtract(boxendmins, rhc.hull->clip_mins, rhc.end);
VectorSubtract(rhc.end, rhc.start, rhc.dist);
+#ifdef COLLISIONPARANOID
+ 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 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)
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))
loadmodel->brushq3.data_textures = out;
loadmodel->brushq3.num_textures = count;
- // FIXME: do a quick parse of the shader files to see if any names match
- // up and get their surfaceparms
-
-
for (i = 0;i < count;i++, in++, out++)
{
out->number = i;
out->nativecontents = LittleLong(in->contents);
out->supercontents = Mod_Q3BSP_SuperContentsFromNativeContents(loadmodel, out->nativecontents);
Mod_LoadSkinFrame(&out->skin, out->name, TEXF_MIPMAP | TEXF_ALPHA | TEXF_PRECACHE, false, true, true);
- out->renderflags = 0;
- 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->renderflags |= Q3MTEXTURERENDERFLAGS_NODRAW;
- if (!strncmp(out->name, "textures/skies/", 15))
- out->renderflags |= Q3MTEXTURERENDERFLAGS_SKY;
- if (R_TextureHasAlpha(out->skin.base))
- out->renderflags |= Q3MTEXTURERENDERFLAGS_TRANSPARENT;
+ 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)
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;