From 89b7bcdf53cd5366e13f8499ef901b1aaa1a9498 Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 27 Jul 2021 20:04:35 +0300 Subject: [PATCH] * read .map brush plane points and store brush planes for windings calculation in double precision (fixes cracks between brush faces) --- tools/quake3/common/polylib.cpp | 5 ++--- tools/quake3/common/polylib.h | 4 ++-- tools/quake3/common/scriplib.cpp | 5 ++++- tools/quake3/common/scriplib.h | 3 ++- tools/quake3/q3map2/brush.cpp | 4 ++-- tools/quake3/q3map2/map.cpp | 11 +++++++---- tools/quake3/q3map2/q3map2.h | 1 + 7 files changed, 20 insertions(+), 13 deletions(-) diff --git a/tools/quake3/common/polylib.cpp b/tools/quake3/common/polylib.cpp index fe59dc7d..87a9bb3e 100644 --- a/tools/quake3/common/polylib.cpp +++ b/tools/quake3/common/polylib.cpp @@ -177,7 +177,7 @@ Vector3 WindingCenter( const winding_t *w ){ BaseWindingForPlaneAccu ================= */ -winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& inplane ){ +winding_accu_t *BaseWindingForPlaneAccu( const Plane3& plane ){ // The goal in this function is to replicate the behavior of the original BaseWindingForPlane() // function (see below) but at the same time increasing accuracy substantially. @@ -194,7 +194,6 @@ winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& inplane ){ int x, i; float max, v; DoubleVector3 vright, vup, org; - const Plane3 plane( inplane.normal(), inplane.dist() ); winding_accu_t *w; // One of the components of normal must have a magnitiude greater than this value, @@ -554,7 +553,7 @@ void ClipWindingEpsilon( winding_t *in, const Plane3f& plane, ChopWindingInPlaceAccu ============= */ -void ChopWindingInPlaceAccu( winding_accu_t **inout, const Plane3f& plane, float crudeEpsilon ){ +void ChopWindingInPlaceAccu( winding_accu_t **inout, const Plane3& plane, float crudeEpsilon ){ winding_accu_t *in; int counts[3]; int i, j; diff --git a/tools/quake3/common/polylib.h b/tools/quake3/common/polylib.h index 8835b3ac..ff36fbe0 100644 --- a/tools/quake3/common/polylib.h +++ b/tools/quake3/common/polylib.h @@ -81,7 +81,7 @@ struct winding_accu_t DoubleVector3 p[]; }; -winding_accu_t *BaseWindingForPlaneAccu( const Plane3f& plane ); -void ChopWindingInPlaceAccu( winding_accu_t **w, const Plane3f& plane, float epsilon ); +winding_accu_t *BaseWindingForPlaneAccu( const Plane3& plane ); +void ChopWindingInPlaceAccu( winding_accu_t **w, const Plane3& plane, float epsilon ); winding_t *CopyWindingAccuToRegular( const winding_accu_t *w ); void FreeWindingAccu( winding_accu_t *w ); diff --git a/tools/quake3/common/scriplib.cpp b/tools/quake3/common/scriplib.cpp index ad16156f..2ebfc84b 100644 --- a/tools/quake3/common/scriplib.cpp +++ b/tools/quake3/common/scriplib.cpp @@ -364,7 +364,8 @@ void MatchToken( const char *match ) { } -void Parse1DMatrix( int x, float *m ) { +template +void Parse1DMatrix( int x, T *m ) { int i; MatchToken( "(" ); @@ -376,6 +377,8 @@ void Parse1DMatrix( int x, float *m ) { MatchToken( ")" ); } +template void Parse1DMatrix( int x, float *m ); +template void Parse1DMatrix( int x, double *m ); void Parse2DMatrix( int y, int x, float *m ) { int i; diff --git a/tools/quake3/common/scriplib.h b/tools/quake3/common/scriplib.h index d8dc08e4..93721eec 100644 --- a/tools/quake3/common/scriplib.h +++ b/tools/quake3/common/scriplib.h @@ -44,7 +44,8 @@ bool TokenAvailable( void ); void MatchToken( const char *match ); -void Parse1DMatrix( int x, float *m ); +template +void Parse1DMatrix( int x, T *m ); void Parse2DMatrix( int y, int x, float *m ); void Parse3DMatrix( int z, int y, int x, float *m ); diff --git a/tools/quake3/q3map2/brush.cpp b/tools/quake3/q3map2/brush.cpp index a0e35333..d592c76b 100644 --- a/tools/quake3/q3map2/brush.cpp +++ b/tools/quake3/q3map2/brush.cpp @@ -432,7 +432,7 @@ bool CreateBrushWindings( brush_t *brush ){ /* make huge winding */ #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES - w = BaseWindingForPlaneAccu( plane->plane ); + w = BaseWindingForPlaneAccu( ( side->plane.normal() != g_vector3_identity )? side->plane : Plane3( plane->normal(), plane->dist() ) ); #else w = BaseWindingForPlane( plane->plane ); #endif @@ -451,7 +451,7 @@ bool CreateBrushWindings( brush_t *brush ){ } plane = &mapplanes[ brush->sides[ j ].planenum ^ 1 ]; #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES - ChopWindingInPlaceAccu( &w, plane->plane, 0 ); + ChopWindingInPlaceAccu( &w, ( brush->sides[ j ].plane.normal() != g_vector3_identity )? plane3_flipped( brush->sides[ j ].plane ) : Plane3( plane->normal(), plane->dist() ), 0 ); #else ChopWindingInPlace( &w, plane->plane, 0 ); // CLIP_EPSILON ); #endif diff --git a/tools/quake3/q3map2/map.cpp b/tools/quake3/q3map2/map.cpp index 67723ff3..61420e8a 100644 --- a/tools/quake3/q3map2/map.cpp +++ b/tools/quake3/q3map2/map.cpp @@ -441,14 +441,15 @@ int FindFloatPlane( const Plane3f& inplane, int numPoints, const Vector3 *points takes 3 points and finds the plane they lie in */ -int MapPlaneFromPoints( Vector3 p[3] ){ +int MapPlaneFromPoints( DoubleVector3 p[3] ){ #if Q3MAP2_EXPERIMENTAL_HIGH_PRECISION_MATH_FIXES Plane3 plane; - PlaneFromPoints( plane, DoubleVector3( p[0] ), DoubleVector3( p[1] ), DoubleVector3( p[2] ) ); + 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). - return FindFloatPlane( Plane3f( plane.normal(), plane.dist() ), 3, p ); + const Vector3 points[3] = { p[0], p[1], p[2] }; + return FindFloatPlane( Plane3f( plane.normal(), plane.dist() ), 3, points ); #else Plane3f plane; PlaneFromPoints( plane, p ); @@ -1008,7 +1009,7 @@ void QuakeTextureVecs( const plane_t& plane, float shift[ 2 ], float rotate, flo static void ParseRawBrush( bool onlyLights ){ side_t *side; - Vector3 planePoints[ 3 ]; + DoubleVector3 planePoints[ 3 ]; int planenum; shaderInfo_t *si; float shift[ 2 ]; @@ -1172,6 +1173,7 @@ static void ParseRawBrush( bool onlyLights ){ /* find the plane number */ planenum = MapPlaneFromPoints( planePoints ); side->planenum = planenum; + PlaneFromPoints( side->plane, planePoints ); /* bp: get the texture mapping for this texturedef / plane combination */ if ( g_brushType == EBrushType::Quake ) { @@ -1382,6 +1384,7 @@ void AdjustBrushesForOrigin( entity_t *ent ){ /* find a new plane */ s->planenum = FindFloatPlane( mapplanes[ s->planenum ].normal(), newdist, 0, NULL ); + s->plane.dist() = -plane3_distance_to_point( s->plane, ent->originbrush_origin ); } /* rebuild brush windings (ydnar: just offsetting the winding above should be fine) */ diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 10f0f951..9f6c7e9c 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -738,6 +738,7 @@ struct side_t Vector3 texMat[ 2 ]; /* brush primitive texture matrix */ Vector4 vecs[ 2 ]; /* old-style texture coordinate mapping */ + Plane3 plane; /* optional plane in double precision for building windings */ winding_t *winding; winding_t *visibleHull; /* convex hull of all visible fragments */