FindFloatPlane() support double reference points

This commit is contained in:
Garux
2025-11-16 22:54:26 +05:00
parent f028db25dc
commit 52a84481bf
7 changed files with 38 additions and 40 deletions
+2 -5
View File
@@ -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 );
+1 -1
View File
@@ -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;
}
}
+1 -1
View File
@@ -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 )
{
+29 -26
View File
@@ -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<const Vector3>& points ){
if ( SnapNormal( plane.normal() ) ) {
template<class T>
bool SnapPlaneImproved( Plane3f& plane, const Span<const BasicVector3<T>>& 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<T>& point : points )
{
center += point;
}
@@ -319,9 +320,14 @@ void SnapPlaneImproved( Plane3f& plane, const Span<const Vector3>& 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<float>( Plane3f& plane, const Span<const BasicVector3<float>>& points );
template bool SnapPlaneImproved<double>( Plane3f& plane, const Span<const BasicVector3<double>>& points );
@@ -330,8 +336,8 @@ void SnapPlaneImproved( Plane3f& plane, const Span<const Vector3>& 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<const Vector3>& points ) // NOTE: this has a side effect on the normal. Good or bad?
template<class T>
int FindFloatPlane___( const Plane3f& inplane, const Span<const BasicVector3<T>>& 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<const Vector3>& 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<T>& 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<const Vector3>& points )
}
#endif
int FindFloatPlane( const Plane3f& inplane, const Span<const Vector3>& points ){
return FindFloatPlane___( inplane, points );
}
int FindFloatPlane( const Plane3f& inplane, const Span<const DoubleVector3>& points ){
return FindFloatPlane___( inplane, points );
}
@@ -424,21 +436,13 @@ int FindFloatPlane( const Plane3f& inplane, const Span<const Vector3>& 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<int, Plane3> 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 ) {
+3 -5
View File
@@ -1569,11 +1569,9 @@ public:
/* map.c */
void LoadMapFile( const char *filename, bool onlyLights, bool noCollapseGroups );
void SnapPlaneImproved( Plane3f& plane, const Span<const Vector3>& points );
int FindFloatPlane( const Plane3f& plane, const Span<const Vector3>& points );
inline int FindFloatPlane( const Vector3& normal, float dist, const Span<const Vector3>& points ){
return FindFloatPlane( Plane3f( normal, dist ), points );
}
template<class T> bool SnapPlaneImproved( Plane3f& plane, const Span<const BasicVector3<T>>& points );
int FindFloatPlane( const Plane3f& plane, const Span<const Vector3>& points = {} );
int FindFloatPlane( const Plane3f& plane, const Span<const DoubleVector3>& points );
bool PlaneEqual( const plane_t& p, const Plane3f& plane );
void AddBrushBevels();
EntityCompileParams ParseEntityCompileParams( const entity_t& e, const entity_t *eparent, bool worldShadowGroup );
+1 -1
View File
@@ -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 );
+1 -1
View File
@@ -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;
}