From f92c4fa25685862cc7916d67a3b23edeaf1ad47f Mon Sep 17 00:00:00 2001 From: Rudolf Polzer Date: Fri, 19 Feb 2010 22:50:19 +0100 Subject: [PATCH] fix patch collision issue by linking patches into all nodes that touch a bbox of a 3x3 segment of the patch, instead of subdividing the patch. Otherwise, different subdivisions can cause patch visibility or collision issues. --- tools/quake3/q3map2/surface.c | 60 +++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/tools/quake3/q3map2/surface.c b/tools/quake3/q3map2/surface.c index a99c5800..6a49c791 100644 --- a/tools/quake3/q3map2/surface.c +++ b/tools/quake3/q3map2/surface.c @@ -1965,6 +1965,44 @@ int FilterPointIntoTree_r( vec3_t point, mapDrawSurface_t *ds, node_t *node ) return AddReferenceToLeaf( ds, node ); } +/* +FilterBoxIntoTree_r() - ydnar +filters a box from a surface into the tree +*/ + +int FilterBoxIntoTree_r( vec3_t mins, vec3_t maxs, mapDrawSurface_t *ds, node_t *node ) +{ + float d, d0, d1, d2, dmin, dmax; + plane_t *plane; + int refs = 0; + + + /* is this a decision node? */ + if( node->planenum != PLANENUM_LEAF ) + { + /* classify the point in relation to the plane */ + plane = &mapplanes[ node->planenum ]; + d = DotProduct( mins, plane->normal ) - plane->dist; + d0 = (maxs[0] - mins[0]) * plane->normal[0]; + d1 = (maxs[1] - mins[1]) * plane->normal[1]; + d2 = (maxs[2] - mins[2]) * plane->normal[2]; + dmax = d + (d0>0 ? d0 : 0) + (d1>0 ? d1 : 0) + (d2>0 ? d2 : 0); + dmin = d + (d0<0 ? d0 : 0) + (d1<0 ? d1 : 0) + (d2<0 ? d2 : 0); + + /* filter by this plane */ + refs = 0; + if( dmax >= -ON_EPSILON ) + refs += FilterBoxIntoTree_r( mins, maxs, ds, node->children[ 0 ] ); + if( dmin <= ON_EPSILON ) + refs += FilterBoxIntoTree_r( mins, maxs, ds, node->children[ 1 ] ); + + /* return */ + return refs; + } + + /* add a reference */ + return AddReferenceToLeaf( ds, node ); +} /* @@ -2095,14 +2133,13 @@ static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ) mesh_t src, *mesh; winding_t *w; - +#if 0 /* subdivide the surface */ src.width = ds->patchWidth; src.height = ds->patchHeight; src.verts = ds->verts; mesh = SubdivideMesh( src, FILTER_SUBDIVISION, 32 ); - /* filter each quad into the tree (fixme: use new patch x-triangulation code?) */ refs = 0; for( y = 0; y < (mesh->height - 1); y++ ) @@ -2133,6 +2170,25 @@ static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ) /* free the subdivided mesh and return */ FreeMesh( mesh ); +#else + for(y = 0; y + 2 < ds->patchHeight; y += 2) + for(x = 0; x + 2 < ds->patchWidth; x += 2) + { + vec3_t mins, maxs; + ClearBounds(mins, maxs); + AddPointToBounds(ds->verts[(y+0) * ds->patchWidth + (x+0)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+0) * ds->patchWidth + (x+1)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+0) * ds->patchWidth + (x+2)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+1) * ds->patchWidth + (x+0)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+1) * ds->patchWidth + (x+1)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+1) * ds->patchWidth + (x+2)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+2) * ds->patchWidth + (x+0)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+2) * ds->patchWidth + (x+1)].xyz, mins, maxs); + AddPointToBounds(ds->verts[(y+2) * ds->patchWidth + (x+2)].xyz, mins, maxs); + refs += FilterBoxIntoTree_r(mins, maxs, ds, tree->headnode); + } +#endif + return refs; } -- 2.39.2