X-Git-Url: http://git.xonotic.org/?a=blobdiff_plain;f=model_brush.c;h=a5c0c1ce30a5db57f7a4c3f6e432cf7113d67784;hb=e7088b647d8131ff08e2e71587859bbf032652bf;hp=7a16f6d7f6942cfc1b82000d5a92efdbb3f93b81;hpb=ad12d2a34f5f25a4c1abaa3d40e33706aef3fe78;p=xonotic%2Fdarkplaces.git diff --git a/model_brush.c b/model_brush.c index 7a16f6d7..a5c0c1ce 100644 --- a/model_brush.c +++ b/model_brush.c @@ -1298,7 +1298,6 @@ static const texture_t *Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(Recu int i; int j; int k; - int axis = node->plane->type; const msurface_t *surface; float normal[3]; float v0[3]; @@ -1314,20 +1313,18 @@ static const texture_t *Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(Recu surface = model->data_surfaces + node->firstsurface; for (i = 0;i < node->numsurfaces;i++, surface++) { - if (axis < 3) - { - if (mid[axis] < surface->mins[axis] || mid[axis] > surface->maxs[axis]) - continue; - } - else - { - if (!BoxesOverlap(mid, mid, surface->mins, surface->maxs)) - continue; - } + // skip surfaces whose bounding box does not include the point +// if (!BoxesOverlap(mid, mid, surface->mins, surface->maxs)) +// continue; + // skip faces with contents we don't care about if (!(t->trace->hitsupercontentsmask & surface->texture->supercontents)) continue; + // get the surface normal - since it is flat we know any vertex normal will suffice VectorCopy(model->surfmesh.data_normal3f + 3 * surface->num_firstvertex, normal); - //VectorCopy(node->plane->normal, normal); + // skip backfaces + if (DotProduct(t->dist, normal) > 0) + continue; + // iterate edges and see if the point is outside one of them for (j = 0, k = surface->num_vertices - 1;j < surface->num_vertices;k = j, j++) { VectorCopy(model->surfmesh.data_vertex3f + 3 * (surface->num_firstvertex + k), v0); @@ -1337,6 +1334,7 @@ static const texture_t *Mod_Q1BSP_TraceLineAgainstSurfacesFindTextureOnNode(Recu if (DotProduct(edgenormal, p) > DotProduct(edgenormal, v0)) break; } + // if the point is outside one of the edges, it is not within the surface if (j < surface->num_vertices) continue; @@ -5977,9 +5975,38 @@ static void Mod_CollisionBIH_TracePoint_RecursiveBIHNode(trace_t *trace, dp_mode const bih_node_t *node; const colbrushf_t *brush; int axis; - while (nodenum >= 0) + for(;;) { node = model->collision_bih.nodes + nodenum; +#if 1 + if (!BoxesOverlap(point, point, node->mins, node->maxs)) + return; +#endif + if (node->type == BIH_UNORDERED) + { + for (axis = 0;axis < BIH_MAXUNORDEREDCHILDREN && node->children[axis] >= 0;axis++) + { + leaf = model->collision_bih.leafs + node->children[axis]; +#if 1 + if (!BoxesOverlap(point, point, leaf->mins, leaf->maxs)) + continue; +#endif + switch(leaf->type) + { + case BIH_BRUSH: + brush = model->brush.data_brushes[leaf->itemindex].colbrushf; + Collision_TracePointBrushFloat(trace, point, brush); + break; + case BIH_COLLISIONTRIANGLE: + // collision triangle - skipped because they have no volume + break; + case BIH_RENDERTRIANGLE: + // render triangle - skipped because they have no volume + break; + } + } + return; + } axis = node->type - BIH_SPLITX; if (point[axis] <= node->backmax) { @@ -5992,22 +6019,6 @@ static void Mod_CollisionBIH_TracePoint_RecursiveBIHNode(trace_t *trace, dp_mode else // no overlap with either child? just return return; } - if (!model->collision_bih.leafs) - return; - leaf = model->collision_bih.leafs + (-1-nodenum); - switch(leaf->type) - { - case BIH_BRUSH: - brush = model->brush.data_brushes[leaf->itemindex].colbrushf; - Collision_TracePointBrushFloat(trace, point, brush); - break; - case BIH_COLLISIONTRIANGLE: - // collision triangle - skipped because they have no volume - break; - case BIH_RENDERTRIANGLE: - // render triangle - skipped because they have no volume - break; - } } static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model_t *model, bih_t *bih, int nodenum, const vec3_t start, const vec3_t end, const vec3_t linestart, const vec3_t lineend) @@ -6037,13 +6048,44 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model segmentmaxs[0] = max(start[0], end[0]); segmentmaxs[1] = max(start[1], end[1]); segmentmaxs[2] = max(start[2], end[2]); - while (nodenum >= 0) + for (;;) { node = bih->nodes + nodenum; -#if 0 +#if 1 if (!BoxesOverlap(segmentmins, segmentmaxs, node->mins, node->maxs)) return; #endif + if (node->type == BIH_UNORDERED) + { + for (axis = 0;axis < BIH_MAXUNORDEREDCHILDREN && node->children[axis] >= 0;axis++) + { + leaf = model->collision_bih.leafs + node->children[axis]; +#if 1 + if (!BoxesOverlap(segmentmins, segmentmaxs, leaf->mins, leaf->maxs)) + continue; +#endif + switch(leaf->type) + { + case BIH_BRUSH: + brush = model->brush.data_brushes[leaf->itemindex].colbrushf; + Collision_TraceLineBrushFloat(trace, linestart, lineend, brush, brush); + break; + case BIH_COLLISIONTRIANGLE: + if (!mod_q3bsp_curves_collisions.integer) + continue; + e = model->brush.data_collisionelement3i + 3*leaf->itemindex; + texture = model->data_textures + leaf->textureindex; + Collision_TraceLineTriangleFloat(trace, linestart, lineend, model->brush.data_collisionvertex3f + e[0] * 3, model->brush.data_collisionvertex3f + e[1] * 3, model->brush.data_collisionvertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); + break; + case BIH_RENDERTRIANGLE: + e = model->surfmesh.data_element3i + 3*leaf->itemindex; + texture = model->data_textures + leaf->textureindex; + Collision_TraceLineTriangleFloat(trace, linestart, lineend, model->surfmesh.data_vertex3f + e[0] * 3, model->surfmesh.data_vertex3f + e[1] * 3, model->surfmesh.data_vertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); + break; + } + } + return; + } axis = node->type - BIH_SPLITX; #if 0 if (segmentmins[axis] <= node->backmax) @@ -6288,32 +6330,6 @@ static void Mod_CollisionBIH_TraceLine_RecursiveBIHNode(trace_t *trace, dp_model #endif #endif } - if (!bih->leafs) - return; - leaf = bih->leafs + (-1-nodenum); -#if 1 - if (!BoxesOverlap(segmentmins, segmentmaxs, leaf->mins, leaf->maxs)) - return; -#endif - switch(leaf->type) - { - case BIH_BRUSH: - brush = model->brush.data_brushes[leaf->itemindex].colbrushf; - Collision_TraceLineBrushFloat(trace, linestart, lineend, brush, brush); - break; - case BIH_COLLISIONTRIANGLE: - if (!mod_q3bsp_curves_collisions.integer) - return; - e = model->brush.data_collisionelement3i + 3*leaf->itemindex; - texture = model->data_textures + leaf->textureindex; - Collision_TraceLineTriangleFloat(trace, linestart, lineend, model->brush.data_collisionvertex3f + e[0] * 3, model->brush.data_collisionvertex3f + e[1] * 3, model->brush.data_collisionvertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); - break; - case BIH_RENDERTRIANGLE: - e = model->surfmesh.data_element3i + 3*leaf->itemindex; - texture = model->data_textures + leaf->textureindex; - Collision_TraceLineTriangleFloat(trace, linestart, lineend, model->surfmesh.data_vertex3f + e[0] * 3, model->surfmesh.data_vertex3f + e[1] * 3, model->surfmesh.data_vertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); - break; - } } static void Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace_t *trace, dp_model_t *model, int nodenum, const colbrushf_t *thisbrush_start, const colbrushf_t *thisbrush_end, const vec3_t segmentmins, const vec3_t segmentmaxs) @@ -6324,9 +6340,40 @@ static void Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace_t *trace, dp_mode const int *e; const texture_t *texture; int axis; - while (nodenum >= 0) + for(;;) { node = model->collision_bih.nodes + nodenum; + if (node->type == BIH_UNORDERED) + { + for (axis = 0;axis < BIH_MAXUNORDEREDCHILDREN && node->children[axis] >= 0;axis++) + { + leaf = model->collision_bih.leafs + node->children[axis]; +#if 1 + if (!BoxesOverlap(segmentmins, segmentmaxs, leaf->mins, leaf->maxs)) + continue; +#endif + switch(leaf->type) + { + case BIH_BRUSH: + brush = model->brush.data_brushes[leaf->itemindex].colbrushf; + Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, brush, brush); + break; + case BIH_COLLISIONTRIANGLE: + if (!mod_q3bsp_curves_collisions.integer) + continue; + e = model->brush.data_collisionelement3i + 3*leaf->itemindex; + texture = model->data_textures + leaf->textureindex; + Collision_TraceBrushTriangleFloat(trace, thisbrush_start, thisbrush_end, model->brush.data_collisionvertex3f + e[0] * 3, model->brush.data_collisionvertex3f + e[1] * 3, model->brush.data_collisionvertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); + break; + case BIH_RENDERTRIANGLE: + e = model->surfmesh.data_element3i + 3*leaf->itemindex; + texture = model->data_textures + leaf->textureindex; + Collision_TraceBrushTriangleFloat(trace, thisbrush_start, thisbrush_end, model->surfmesh.data_vertex3f + e[0] * 3, model->surfmesh.data_vertex3f + e[1] * 3, model->surfmesh.data_vertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); + break; + } + } + return; + } axis = node->type - BIH_SPLITX; #if 1 if (!BoxesOverlap(segmentmins, segmentmaxs, node->mins, node->maxs)) @@ -6348,32 +6395,6 @@ static void Mod_CollisionBIH_TraceBrush_RecursiveBIHNode(trace_t *trace, dp_mode else return; // trace falls between children } - if (!model->collision_bih.leafs) - return; - leaf = model->collision_bih.leafs + (-1-nodenum); -#if 1 - if (!BoxesOverlap(segmentmins, segmentmaxs, leaf->mins, leaf->maxs)) - return; -#endif - switch(leaf->type) - { - case BIH_BRUSH: - brush = model->brush.data_brushes[leaf->itemindex].colbrushf; - Collision_TraceBrushBrushFloat(trace, thisbrush_start, thisbrush_end, brush, brush); - break; - case BIH_COLLISIONTRIANGLE: - if (!mod_q3bsp_curves_collisions.integer) - return; - e = model->brush.data_collisionelement3i + 3*leaf->itemindex; - texture = model->data_textures + leaf->textureindex; - Collision_TraceBrushTriangleFloat(trace, thisbrush_start, thisbrush_end, model->brush.data_collisionvertex3f + e[0] * 3, model->brush.data_collisionvertex3f + e[1] * 3, model->brush.data_collisionvertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); - break; - case BIH_RENDERTRIANGLE: - e = model->surfmesh.data_element3i + 3*leaf->itemindex; - texture = model->data_textures + leaf->textureindex; - Collision_TraceBrushTriangleFloat(trace, thisbrush_start, thisbrush_end, model->surfmesh.data_vertex3f + e[0] * 3, model->surfmesh.data_vertex3f + e[1] * 3, model->surfmesh.data_vertex3f + e[2] * 3, texture->supercontents, texture->surfaceflags, texture); - break; - } } void Mod_CollisionBIH_TracePoint(dp_model_t *model, const frameblend_t *frameblend, const skeleton_t *skeleton, trace_t *trace, const vec3_t start, int hitsupercontentsmask) @@ -7046,7 +7067,7 @@ bih_t *Mod_MakeCollisionBIH(dp_model_t *model, qboolean userendersurfaces, bih_t } // allocate buffers for the produced and temporary data - bihmaxnodes = bihnumleafs - 1; + bihmaxnodes = bihnumleafs + 1; bihnodes = (bih_node_t *)Mem_Alloc(loadmodel->mempool, sizeof(bih_node_t) * bihmaxnodes); temp_leafsort = (int *)Mem_Alloc(loadmodel->mempool, sizeof(int) * bihnumleafs * 2); temp_leafsortscratch = temp_leafsort + bihnumleafs; @@ -7166,7 +7187,7 @@ void Mod_Q3BSP_Load(dp_model_t *mod, void *buffer, void *bufferend) mod->TraceLine = Mod_Q3BSP_TraceLine; mod->TracePoint = Mod_Q3BSP_TracePoint; mod->PointSuperContents = Mod_Q3BSP_PointSuperContents; - mod->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLineAgainstSurfaces; + mod->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLine; mod->brush.TraceLineOfSight = Mod_Q3BSP_TraceLineOfSight; mod->brush.SuperContentsFromNativeContents = Mod_Q3BSP_SuperContentsFromNativeContents; mod->brush.NativeContentsFromSuperContents = Mod_Q3BSP_NativeContentsFromSuperContents; @@ -7465,7 +7486,7 @@ void Mod_OBJ_Load(dp_model_t *mod, void *buffer, void *bufferend) loadmodel->TraceBrush = Mod_CollisionBIH_TraceBrush; loadmodel->TraceLine = Mod_CollisionBIH_TraceLine; loadmodel->TracePoint = Mod_CollisionBIH_TracePoint_Mesh; - loadmodel->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLineAgainstSurfaces; + loadmodel->TraceLineAgainstSurfaces = Mod_CollisionBIH_TraceLine; loadmodel->PointSuperContents = Mod_CollisionBIH_PointSuperContents_Mesh; loadmodel->brush.TraceLineOfSight = NULL; loadmodel->brush.SuperContentsFromNativeContents = NULL;