* read .map brush plane points and store brush planes for windings calculation in double precision (fixes cracks between brush faces)

This commit is contained in:
Garux 2021-07-27 20:04:35 +03:00
parent 3c17f8fbc5
commit 89b7bcdf53
7 changed files with 20 additions and 13 deletions

View File

@ -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;

View File

@ -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 );

View File

@ -364,7 +364,8 @@ void MatchToken( const char *match ) {
}
void Parse1DMatrix( int x, float *m ) {
template<typename T>
void Parse1DMatrix( int x, T *m ) {
int i;
MatchToken( "(" );
@ -376,6 +377,8 @@ void Parse1DMatrix( int x, float *m ) {
MatchToken( ")" );
}
template void Parse1DMatrix<float>( int x, float *m );
template void Parse1DMatrix<double>( int x, double *m );
void Parse2DMatrix( int y, int x, float *m ) {
int i;

View File

@ -44,7 +44,8 @@ bool TokenAvailable( void );
void MatchToken( const char *match );
void Parse1DMatrix( int x, float *m );
template<typename T>
void Parse1DMatrix( int x, T *m );
void Parse2DMatrix( int y, int x, float *m );
void Parse3DMatrix( int z, int y, int x, float *m );

View File

@ -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

View File

@ -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) */

View File

@ -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 */