use spatially sorted indices during search of coincident vertices in AddMetaVertToSurface
This commit is contained in:
parent
e780b45696
commit
0ad3d89d4a
|
|
@ -30,8 +30,12 @@
|
||||||
|
|
||||||
/* dependencies */
|
/* dependencies */
|
||||||
#include "q3map2.h"
|
#include "q3map2.h"
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
|
const Plane3f c_spatial_sort_plane( 0.786868, 0.316861, 0.529564, 0 );
|
||||||
|
const float c_spatial_EQUAL_EPSILON = EQUAL_EPSILON * 2;
|
||||||
|
|
||||||
|
|
||||||
#define VERTS_EXCEEDED -1000
|
#define VERTS_EXCEEDED -1000
|
||||||
|
|
||||||
|
|
@ -1237,28 +1241,38 @@ void SmoothMetaTriangles( void ){
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
struct SpatialIndex
|
||||||
|
{
|
||||||
|
const float m_dist;
|
||||||
|
const int m_index; // index of bspDrawVert_t in mapDrawSurface_t::verts array
|
||||||
|
SpatialIndex( const Vector3& point, int index ) : m_dist( plane3_distance_to_point( c_spatial_sort_plane, point ) ), m_index( index ){}
|
||||||
|
bool operator<( const SpatialIndex& other ) const {
|
||||||
|
return m_dist < other.m_dist - c_spatial_EQUAL_EPSILON;
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
using Sorted_indices = std::multiset<SpatialIndex>;
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
AddMetaVertToSurface()
|
AddMetaVertToSurface()
|
||||||
adds a drawvert to a surface unless an existing vert matching already exists
|
adds a drawvert to a surface unless an existing vert matching already exists
|
||||||
returns the index of that vert (or < 0 on failure)
|
returns the index of that vert (or < 0 on failure)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincident ){
|
int AddMetaVertToSurface( mapDrawSurface_t *ds, const bspDrawVert_t& dv1, const Sorted_indices& sorted_indices, int *coincident ){
|
||||||
int i;
|
|
||||||
bspDrawVert_t *dv2;
|
|
||||||
|
|
||||||
|
|
||||||
/* go through the verts and find a suitable candidate */
|
/* go through the verts and find a suitable candidate */
|
||||||
for ( i = 0; i < ds->numVerts; i++ )
|
const auto [begin, end] = sorted_indices.equal_range( SpatialIndex( dv1.xyz, 0 ) );
|
||||||
{
|
for( auto it = begin; it != end; ++it ){
|
||||||
/* get test vert */
|
/* get test vert */
|
||||||
dv2 = &ds->verts[ i ];
|
const bspDrawVert_t& dv2 = ds->verts[ it->m_index ];
|
||||||
|
|
||||||
/* compare xyz and normal */
|
/* compare xyz and normal */
|
||||||
if ( !VectorCompare( dv1->xyz, dv2->xyz ) ) {
|
if ( !VectorCompare( dv1.xyz, dv2.xyz ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( !VectorCompare( dv1->normal, dv2->normal ) ) {
|
if ( !VectorCompare( dv1.normal, dv2.normal ) ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1266,16 +1280,16 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid
|
||||||
( *coincident )++;
|
( *coincident )++;
|
||||||
|
|
||||||
/* compare texture coordinates and color */
|
/* compare texture coordinates and color */
|
||||||
if ( dv1->st[ 0 ] != dv2->st[ 0 ] || dv1->st[ 1 ] != dv2->st[ 1 ] ) {
|
if ( dv1.st[ 0 ] != dv2.st[ 0 ] || dv1.st[ 1 ] != dv2.st[ 1 ] ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if ( dv1->color[ 0 ].alpha() != dv2->color[ 0 ].alpha() ) {
|
if ( dv1.color[ 0 ].alpha() != dv2.color[ 0 ].alpha() ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* found a winner */
|
/* found a winner */
|
||||||
numMergedVerts++;
|
numMergedVerts++;
|
||||||
return i;
|
return it->m_index;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* overflow check */
|
/* overflow check */
|
||||||
|
|
@ -1284,8 +1298,7 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid
|
||||||
}
|
}
|
||||||
|
|
||||||
/* made it this far, add the vert and return */
|
/* made it this far, add the vert and return */
|
||||||
dv2 = &ds->verts[ ds->numVerts++ ];
|
ds->verts[ ds->numVerts++ ] = dv1;
|
||||||
*dv2 = *dv1;
|
|
||||||
return ( ds->numVerts - 1 );
|
return ( ds->numVerts - 1 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1301,18 +1314,18 @@ int AddMetaVertToSurface( mapDrawSurface_t *ds, bspDrawVert_t *dv1, int *coincid
|
||||||
#define AXIS_SCORE 100000
|
#define AXIS_SCORE 100000
|
||||||
#define AXIS_MIN 100000
|
#define AXIS_MIN 100000
|
||||||
#define VERT_SCORE 10000
|
#define VERT_SCORE 10000
|
||||||
#define SURFACE_SCORE 1000
|
#define SURFACE_SCORE 1000
|
||||||
#define ST_SCORE 50
|
#define ST_SCORE 50
|
||||||
#define ST_SCORE2 ( 2 * ( ST_SCORE ) )
|
#define ST_SCORE2 ( 2 * ( ST_SCORE ) )
|
||||||
|
|
||||||
#define DEFAULT_ADEQUATE_SCORE ( (AXIS_MIN) +1 * ( VERT_SCORE ) )
|
#define DEFAULT_ADEQUATE_SCORE ( (AXIS_MIN) + 1 * (VERT_SCORE) )
|
||||||
#define DEFAULT_GOOD_SCORE ( (AXIS_MIN) +2 * (VERT_SCORE) +4 * ( ST_SCORE ) )
|
#define DEFAULT_GOOD_SCORE ( (AXIS_MIN) + 2 * (VERT_SCORE) + 4 * (ST_SCORE) )
|
||||||
#define PERFECT_SCORE ( (AXIS_MIN) +3 * ( VERT_SCORE ) + (SURFACE_SCORE) +4 * ( ST_SCORE ) )
|
#define PERFECT_SCORE ( (AXIS_MIN) + 3 * (VERT_SCORE) + (SURFACE_SCORE) + 4 * (ST_SCORE) )
|
||||||
|
|
||||||
#define ADEQUATE_SCORE ( metaAdequateScore >= 0 ? metaAdequateScore : DEFAULT_ADEQUATE_SCORE )
|
#define ADEQUATE_SCORE ( metaAdequateScore >= 0 ? metaAdequateScore : DEFAULT_ADEQUATE_SCORE )
|
||||||
#define GOOD_SCORE ( metaGoodScore >= 0 ? metaGoodScore : DEFAULT_GOOD_SCORE )
|
#define GOOD_SCORE ( metaGoodScore >= 0 ? metaGoodScore : DEFAULT_GOOD_SCORE )
|
||||||
|
|
||||||
static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, MinMax& texMinMax, bool testAdd ){
|
static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri, MinMax& texMinMax, Sorted_indices& sorted_indices, bool testAdd ){
|
||||||
int i, score, coincident, ai, bi, ci;
|
int i, score, coincident, ai, bi, ci;
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1368,10 +1381,11 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||||
mapDrawSurface_t old( *ds );
|
mapDrawSurface_t old( *ds );
|
||||||
|
|
||||||
/* attempt to add the verts */
|
/* attempt to add the verts */
|
||||||
|
const int numVerts_original = ds->numVerts;
|
||||||
coincident = 0;
|
coincident = 0;
|
||||||
ai = AddMetaVertToSurface( ds, &metaVerts[ tri->indexes[ 0 ] ], &coincident );
|
ai = AddMetaVertToSurface( ds, metaVerts[ tri->indexes[ 0 ] ], sorted_indices, &coincident );
|
||||||
bi = AddMetaVertToSurface( ds, &metaVerts[ tri->indexes[ 1 ] ], &coincident );
|
bi = AddMetaVertToSurface( ds, metaVerts[ tri->indexes[ 1 ] ], sorted_indices, &coincident );
|
||||||
ci = AddMetaVertToSurface( ds, &metaVerts[ tri->indexes[ 2 ] ], &coincident );
|
ci = AddMetaVertToSurface( ds, metaVerts[ tri->indexes[ 2 ] ], sorted_indices, &coincident );
|
||||||
|
|
||||||
/* check vertex underflow */
|
/* check vertex underflow */
|
||||||
if ( ai < 0 || bi < 0 || ci < 0 ) {
|
if ( ai < 0 || bi < 0 || ci < 0 ) {
|
||||||
|
|
@ -1500,6 +1514,11 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t *ds, metaTriangle_t *tri,
|
||||||
|
|
||||||
/* add a side reference */
|
/* add a side reference */
|
||||||
ds->sideRef = AllocSideRef( tri->side, ds->sideRef );
|
ds->sideRef = AllocSideRef( tri->side, ds->sideRef );
|
||||||
|
|
||||||
|
for( const auto id : { ai, bi, ci } ){
|
||||||
|
if( id >= numVerts_original )
|
||||||
|
sorted_indices.insert( SpatialIndex( ds->verts[id].xyz, id ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* return to sender */
|
/* return to sender */
|
||||||
|
|
@ -1559,8 +1578,10 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles,
|
||||||
|
|
||||||
MinMax texMinMax;
|
MinMax texMinMax;
|
||||||
|
|
||||||
|
Sorted_indices sorted_indices;
|
||||||
|
|
||||||
/* add the first triangle */
|
/* add the first triangle */
|
||||||
if ( AddMetaTriangleToSurface( ds, seed, texMinMax, false ) ) {
|
if ( AddMetaTriangleToSurface( ds, seed, texMinMax, sorted_indices, false ) ) {
|
||||||
( *numAdded )++;
|
( *numAdded )++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1593,14 +1614,14 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* score this triangle */
|
/* score this triangle */
|
||||||
score = AddMetaTriangleToSurface( ds, test, texMinMax, true );
|
score = AddMetaTriangleToSurface( ds, test, texMinMax, sorted_indices, true );
|
||||||
if ( score > bestScore ) {
|
if ( score > bestScore ) {
|
||||||
best = j;
|
best = j;
|
||||||
bestScore = score;
|
bestScore = score;
|
||||||
|
|
||||||
/* if we have a score over a certain threshold, just use it */
|
/* if we have a score over a certain threshold, just use it */
|
||||||
if ( bestScore >= GOOD_SCORE ) {
|
if ( bestScore >= GOOD_SCORE ) {
|
||||||
if ( AddMetaTriangleToSurface( ds, &possibles[ best ], texMinMax, false ) ) {
|
if ( AddMetaTriangleToSurface( ds, &possibles[ best ], texMinMax, sorted_indices, false ) ) {
|
||||||
( *numAdded )++;
|
( *numAdded )++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1614,7 +1635,7 @@ static void MetaTrianglesToSurface( int numPossibles, metaTriangle_t *possibles,
|
||||||
|
|
||||||
/* add best candidate */
|
/* add best candidate */
|
||||||
if ( best >= 0 && bestScore > ADEQUATE_SCORE ) {
|
if ( best >= 0 && bestScore > ADEQUATE_SCORE ) {
|
||||||
if ( AddMetaTriangleToSurface( ds, &possibles[ best ], texMinMax, false ) ) {
|
if ( AddMetaTriangleToSurface( ds, &possibles[ best ], texMinMax, sorted_indices, false ) ) {
|
||||||
( *numAdded )++;
|
( *numAdded )++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user