//#if COLLISIONPARANOID < 2
static int Mod_Q1BSP_RecursiveHullCheckPoint(RecursiveHullCheckTraceInfo_t *t, int num)
{
+ mplane_t *plane;
+ mclipnode_t *nodes = t->hull->clipnodes;
+ mplane_t *planes = t->hull->planes;
+ vec3_t point;
+ VectorCopy(t->start, point);
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];
+ {
+ plane = planes + nodes[num].planenum;
+ num = nodes[num].children[(plane->type < 3 ? point[plane->type] : DotProduct(plane->normal, point)) < plane->dist];
+ }
num = Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num);
t->trace->startsupercontents |= num;
if (num & SUPERCONTENTS_LIQUIDSMASK)
#endif
}
+static int Mod_Q1BSP_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
+{
+ int num = 0;
+ mplane_t *plane;
+ mclipnode_t *nodes = model->brushq1.hulls[0].clipnodes;
+ mplane_t *planes = model->brushq1.hulls[0].planes;
+ while (num >= 0)
+ {
+ plane = planes + nodes[num].planenum;
+ num = nodes[num].children[(plane->type < 3 ? point[plane->type] : DotProduct(plane->normal, point)) < plane->dist];
+ }
+ return Mod_Q1BSP_SuperContentsFromNativeContents(NULL, num);
+}
+
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, int boxq3surfaceflags, texture_t *boxtexture)
{
#if 1
mod->soundfromcenter = true;
mod->TraceBox = Mod_Q1BSP_TraceBox;
+ mod->PointSuperContents = Mod_Q1BSP_PointSuperContents;
mod->brush.TraceLineOfSight = Mod_Q1BSP_TraceLineOfSight;
mod->brush.SuperContentsFromNativeContents = Mod_Q1BSP_SuperContentsFromNativeContents;
mod->brush.NativeContentsFromSuperContents = Mod_Q1BSP_NativeContentsFromSuperContents;
if (loadmodel->brush.numsubmodels)
loadmodel->brush.submodels = (model_t **)Mem_Alloc(loadmodel->mempool, loadmodel->brush.numsubmodels * sizeof(model_t *));
- if (loadmodel->isworldmodel)
- {
- // clear out any stale submodels or worldmodels lying around
- // if we did this clear before now, an error might abort loading and
- // leave things in a bad state
- Mod_RemoveStaleWorldModels(loadmodel);
- }
-
// LordHavoc: to clear the fog around the original quake submodel code, I
// will explain:
// first of all, some background info on the submodels:
colbrushf_t *brush;
// find which leaf the point is in
while (node->plane)
- node = node->children[DotProduct(point, node->plane->normal) < node->plane->dist];
+ node = node->children[(node->plane->type < 3 ? point[node->plane->type] : DotProduct(point, node->plane->normal)) < node->plane->dist];
// point trace the brushes
leaf = (mleaf_t *)node;
for (i = 0;i < leaf->numleafbrushes;i++)
}
}
+static int Mod_Q3BSP_PointSuperContents(struct model_s *model, int frame, const vec3_t point)
+{
+ int i;
+ int supercontents = 0;
+ q3mbrush_t *brush;
+ // test if the point is inside each brush
+ if (model->brush.submodel)
+ {
+ // submodels are effectively one leaf
+ for (i = 0, brush = model->brush.data_brushes + model->firstmodelbrush;i < model->nummodelbrushes;i++, brush++)
+ if (brush->colbrushf && Collision_PointInsideBrushFloat(point, brush->colbrushf))
+ supercontents |= brush->colbrushf->supercontents;
+ }
+ else
+ {
+ mnode_t *node = model->brush.data_nodes;
+ mleaf_t *leaf;
+ // find which leaf the point is in
+ while (node->plane)
+ node = node->children[(node->plane->type < 3 ? point[node->plane->type] : DotProduct(point, node->plane->normal)) < node->plane->dist];
+ leaf = (mleaf_t *)node;
+ // now check the brushes in the leaf
+ for (i = 0;i < leaf->numleafbrushes;i++)
+ {
+ brush = model->brush.data_brushes + leaf->firstleafbrush[i];
+ if (brush->colbrushf && Collision_PointInsideBrushFloat(point, brush->colbrushf))
+ supercontents |= brush->colbrushf->supercontents;
+ }
+ }
+ return supercontents;
+}
+
static int Mod_Q3BSP_SuperContentsFromNativeContents(model_t *model, int nativecontents)
{
int supercontents = 0;
mod->soundfromcenter = true;
mod->TraceBox = Mod_Q3BSP_TraceBox;
+ mod->PointSuperContents = Mod_Q3BSP_PointSuperContents;
mod->brush.TraceLineOfSight = Mod_Q1BSP_TraceLineOfSight;
mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents;
mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents;
loadmodel->brush.num_leafs = 0;
Mod_Q3BSP_RecursiveFindNumLeafs(loadmodel->brush.data_nodes);
- if (loadmodel->isworldmodel)
- {
- // clear out any stale submodels or worldmodels lying around
- // if we did this clear before now, an error might abort loading and
- // leave things in a bad state
- Mod_RemoveStaleWorldModels(loadmodel);
- }
-
mod = loadmodel;
for (i = 0;i < loadmodel->brush.numsubmodels;i++)
{