diff --git a/tools/quake3/q3map2/brush.cpp b/tools/quake3/q3map2/brush.cpp index 2f830395..f5d6f9f9 100644 --- a/tools/quake3/q3map2/brush.cpp +++ b/tools/quake3/q3map2/brush.cpp @@ -332,11 +332,8 @@ static brush_t BrushFromBounds( const Vector3& mins, const Vector3& maxs ){ b.sides.resize( 6 ); for ( int i = 0; i < 3; ++i ) { - float dist = maxs[i]; - b.sides[i].planenum = FindFloatPlane( g_vector3_axes[i], dist, Span( &maxs, 1 ) ); - - dist = -mins[i]; - b.sides[3 + i].planenum = FindFloatPlane( -g_vector3_axes[i], dist, Span( &mins, 1 ) ); + b.sides[i ].planenum = FindFloatPlane( Plane3f( g_vector3_axes[i], maxs[i] ), Span( &maxs, 1 ) ); + b.sides[i + 3].planenum = FindFloatPlane( Plane3f( -g_vector3_axes[i], -mins[i] ), Span( &mins, 1 ) ); } CreateBrushWindings( b ); diff --git a/tools/quake3/q3map2/facebsp.cpp b/tools/quake3/q3map2/facebsp.cpp index aa5a5d04..79e11d69 100644 --- a/tools/quake3/q3map2/facebsp.cpp +++ b/tools/quake3/q3map2/facebsp.cpp @@ -61,7 +61,7 @@ static void SelectSplitPlaneNum( const node_t *node, const facelist_t& list, int } const float dist = blockSize[ i ] * ( floor( node->minmax.mins[ i ] / blockSize[ i ] ) + 1 ); if ( node->minmax.maxs[ i ] > dist ) { - *splitPlaneNum = FindFloatPlane( g_vector3_axes[i], dist, {} ); + *splitPlaneNum = FindFloatPlane( Plane3f( g_vector3_axes[i], dist ) ); return; } } diff --git a/tools/quake3/q3map2/light_ydnar.cpp b/tools/quake3/q3map2/light_ydnar.cpp index f9e471e2..6fb2f8e0 100644 --- a/tools/quake3/q3map2/light_ydnar.cpp +++ b/tools/quake3/q3map2/light_ydnar.cpp @@ -767,7 +767,7 @@ static int MapSingleLuxel( rawLightmap_t *lm, const surfaceInfo_t *info, const b if ( worldverts != nullptr && lightmapTriangleCheck ) { Plane3f hostplane; - PlaneFromPoints( hostplane, worldverts[0], worldverts[1], worldverts[2] ); + PlaneFromPoints( hostplane, worldverts ); for ( j = 0; j < 3; ++j ) { diff --git a/tools/quake3/q3map2/map.cpp b/tools/quake3/q3map2/map.cpp index 756ba211..00e3aca5 100644 --- a/tools/quake3/q3map2/map.cpp +++ b/tools/quake3/q3map2/map.cpp @@ -138,7 +138,6 @@ static int CreateNewFloatPlane( const Plane3f& plane ){ static bool SnapNormal( Vector3& normal ){ #if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX - int i; bool adjusted = false; // A change from the original SnapNormal() is that we snap each @@ -167,7 +166,7 @@ static bool SnapNormal( Vector3& normal ){ /* - for ( i = 0; i < 30; ++i ) + for ( int i = 0; i < 30; ++i ) { double x, y, z, length; x = (double) 1.0; @@ -186,7 +185,7 @@ static bool SnapNormal( Vector3& normal ){ Error( "vectorNormalize test completed" ); */ - for ( i = 0; i < 3; ++i ) + for ( int i = 0; i < 3; ++i ) { if ( normal[i] != 0 && -normalEpsilon < normal[i] && normal[i] < normalEpsilon ) { normal[i] = 0; @@ -194,11 +193,10 @@ static bool SnapNormal( Vector3& normal ){ } } - if ( adjusted ) { + if ( adjusted ) VectorNormalize( normal ); - return true; - } - return false; + + return adjusted; #else int i; @@ -299,12 +297,15 @@ static void SnapPlane( Plane3f& plane ){ SnapPlaneImproved() snaps a plane to normal/distance epsilons, improved code */ -void SnapPlaneImproved( Plane3f& plane, const Span& points ){ - if ( SnapNormal( plane.normal() ) ) { +template +bool SnapPlaneImproved( Plane3f& plane, const Span>& points ){ + bool adjusted; + + if ( ( adjusted = SnapNormal( plane.normal() ) ) ) { if ( !points.empty() ) { // Adjust the dist so that the provided points don't drift away. DoubleVector3 center( 0 ); - for ( const Vector3& point : points ) + for ( const BasicVector3& point : points ) { center += point; } @@ -319,9 +320,14 @@ void SnapPlaneImproved( Plane3f& plane, const Span& points ){ const float distNearestInt = std::rint( plane.dist() ); if ( -distanceEpsilon < plane.dist() - distNearestInt && plane.dist() - distNearestInt < distanceEpsilon ) { plane.dist() = distNearestInt; + adjusted = true; } } + + return adjusted; } +template bool SnapPlaneImproved( Plane3f& plane, const Span>& points ); +template bool SnapPlaneImproved( Plane3f& plane, const Span>& points ); @@ -330,8 +336,8 @@ void SnapPlaneImproved( Plane3f& plane, const Span& points ){ ydnar: changed to allow a number of test points to be supplied that must be within an epsilon distance of the plane */ - -int FindFloatPlane( const Plane3f& inplane, const Span& points ) // NOTE: this has a side effect on the normal. Good or bad? +template +int FindFloatPlane___( const Plane3f& inplane, const Span>& points ) // NOTE: this has a side effect on the normal. Good or bad? #ifdef USE_HASHING @@ -362,7 +368,7 @@ int FindFloatPlane( const Plane3f& inplane, const Span& points ) //% return p - mapplanes; /* ydnar: test supplied points against this plane */ - if( std::ranges::all_of( points, [&]( const Vector3& point ){ // true for empty + if( std::ranges::all_of( points, [&]( const BasicVector3& point ){ // true for empty // NOTE: When dist approaches 2^16, the resolution of 32 bit floating // point number is greatly decreased. The distanceEpsilon cannot be // very small when world coordinates extend to 2^16. Making the @@ -416,6 +422,12 @@ int FindFloatPlane( const Plane3f& inplane, const Span& points ) } #endif +int FindFloatPlane( const Plane3f& inplane, const Span& points ){ + return FindFloatPlane___( inplane, points ); +} +int FindFloatPlane( const Plane3f& inplane, const Span& points ){ + return FindFloatPlane___( inplane, points ); +} @@ -424,21 +436,13 @@ int FindFloatPlane( const Plane3f& inplane, const Span& points ) takes 3 points and finds the plane they lie in */ -inline int MapPlaneFromPoints( DoubleVector3 p[3] ){ -#if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES +inline std::pair MapPlaneFromPoints( const DoubleVector3 (&p)[3] ){ Plane3 plane; PlaneFromPoints( plane, p ); // TODO: A 32 bit float for the plane distance isn't enough resolution // if the plane is 2^16 units away from the origin (the "epsilon" approaches // 0.01 in that case). - const Vector3 points[3] = { p[0], p[1], p[2] }; - return FindFloatPlane( Plane3f( plane ), points ); -#else - Plane3f plane; - PlaneFromPoints( plane, p ); - const Vector3 points[3] = { p[0], p[1], p[2] }; - return FindFloatPlane( plane, points ); -#endif + return { FindFloatPlane( Plane3f( plane ), p ), plane }; } @@ -615,7 +619,7 @@ void AddBrushBevels(){ } } - s.planenum = FindFloatPlane( plane, {} ); + s.planenum = FindFloatPlane( plane ); s.contentFlags = sides[ 0 ].contentFlags; /* handle bevel surfaceflags */ for ( const side_t& side : sides ) { @@ -993,8 +997,7 @@ static void ParseRawBrush( bool onlyLights ){ Parse1DMatrix( 3, planePoints[ 2 ].data() ); /* find the plane number */ - side.planenum = MapPlaneFromPoints( planePoints ); - PlaneFromPoints( side.plane, planePoints ); + std::tie( side.planenum, side.plane ) = MapPlaneFromPoints( planePoints ); /* bp: read the texture matrix */ if ( g_brushType == EBrushType::Bp ) { diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 7b637755..81c4d2c2 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -1569,11 +1569,9 @@ public: /* map.c */ void LoadMapFile( const char *filename, bool onlyLights, bool noCollapseGroups ); -void SnapPlaneImproved( Plane3f& plane, const Span& points ); -int FindFloatPlane( const Plane3f& plane, const Span& points ); -inline int FindFloatPlane( const Vector3& normal, float dist, const Span& points ){ - return FindFloatPlane( Plane3f( normal, dist ), points ); -} +template bool SnapPlaneImproved( Plane3f& plane, const Span>& points ); +int FindFloatPlane( const Plane3f& plane, const Span& points = {} ); +int FindFloatPlane( const Plane3f& plane, const Span& points ); bool PlaneEqual( const plane_t& p, const Plane3f& plane ); void AddBrushBevels(); EntityCompileParams ParseEntityCompileParams( const entity_t& e, const entity_t *eparent, bool worldShadowGroup ); diff --git a/tools/quake3/q3map2/surface.cpp b/tools/quake3/q3map2/surface.cpp index 19aec529..1d334743 100644 --- a/tools/quake3/q3map2/surface.cpp +++ b/tools/quake3/q3map2/surface.cpp @@ -2524,7 +2524,7 @@ static void MakeDebugPortalSurfs_r( const node_t *node, shaderInfo_t& si ){ mapDrawSurface_t& ds = AllocDrawSurface( ESurfaceType::Face ); ds.shaderInfo = &si; ds.planar = true; - ds.planeNum = FindFloatPlane( p->plane.plane, {} ); + ds.planeNum = FindFloatPlane( p->plane.plane ); ds.lightmapVecs[ 2 ] = p->plane.normal(); ds.fogNum = FOG_INVALID; ds.verts.resize( w.size(), c_bspDrawVert_t0 ); diff --git a/tools/quake3/q3map2/vis.cpp b/tools/quake3/q3map2/vis.cpp index f8025f00..a6be08ab 100644 --- a/tools/quake3/q3map2/vis.cpp +++ b/tools/quake3/q3map2/vis.cpp @@ -39,7 +39,7 @@ vportal_t *sorted_portals[ MAX_MAP_PORTALS * 2 ]; static visPlane_t PlaneFromWinding( const fixedWinding_t *w ){ // calc plane visPlane_t plane; - PlaneFromPoints( plane, w->points[0], w->points[1], w->points[2] ); + PlaneFromPoints( plane, w->points ); return plane; }