mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
* fix deformvertexes autosprite2 on brushes and models
broken for brushes in c166e4214e by new triangualtion
broken for models forever
fixes https://github.com/TTimo/GtkRadiant/issues/658
This commit is contained in:
@@ -178,6 +178,7 @@ Q3map2:
|
||||
* -nobrushsnap: disable brush vertices snapping (of drawsurfs) (experimental, keep eye on meta merge efficiency)
|
||||
* improved brush faces triangulation wrt degenerate triangles production (non -maxarea algorithm)
|
||||
* -globalflag <surfaceparm>: add surface flag to every bsp shader. Reusable, e.g. -globalflag slick -globalflag nodamage.
|
||||
* fix deformvertexes autosprite2 on brushes and models
|
||||
|
||||
|
||||
|
||||
@@ -195,6 +196,7 @@ MBSPC:
|
||||
* append _decompiled suffix to decompiled map file names
|
||||
* improve decompilation quality of Q1, HL maps greatly (texturing correctness, less brushes)
|
||||
* -lessbrushes switch: less brushes when decompiling Q1, HL maps at the expense of texturing
|
||||
* fix build speed penalty due to terminal output
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -2258,6 +2258,89 @@ static void EmitPatchSurface( const entity_t& e, mapDrawSurface_t *ds ){
|
||||
numSurfacesByType[ static_cast<std::size_t>( ds->type ) ]++;
|
||||
}
|
||||
|
||||
/*
|
||||
Autosprite2Deform() function in vanilla Q3 engine and most of sourceports
|
||||
produces inconsistent results, which depend on vertex order and indexing.
|
||||
Try to please that windy lady.
|
||||
*/
|
||||
static void FixAutosprite2Surface( mapDrawSurface_t *ds ){
|
||||
if( ds->numVerts != 4 || ds->numIndexes != 6 ){
|
||||
Sys_Warning( "autosprite2 surface: ds->numVerts != 4 or ds->numIndexes != 6: must be simple rectangle\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
Plane3f plane;
|
||||
if( !PlaneFromPoints( plane, ds->verts[ds->indexes[0]].xyz, ds->verts[ds->indexes[1]].xyz, ds->verts[ds->indexes[2]].xyz ) ){
|
||||
Sys_Warning( "autosprite2 surface: degenerate triangle\n" );
|
||||
return;
|
||||
}
|
||||
|
||||
// reproduce Autosprite2Deform() calculations
|
||||
const int edgeVerts[6][2] = {
|
||||
{ 0, 1 },
|
||||
{ 0, 2 },
|
||||
{ 0, 3 },
|
||||
{ 1, 2 },
|
||||
{ 1, 3 },
|
||||
{ 2, 3 }
|
||||
};
|
||||
float lengths[2] = { 999999, 999999 };
|
||||
int edgeIdx[2] = {0};
|
||||
|
||||
// identify the two shortest edges
|
||||
for ( int j = 0; j < 6; ++j ) {
|
||||
const float l = vector3_length_squared( ds->verts[edgeVerts[j][0]].xyz - ds->verts[edgeVerts[j][1]].xyz );
|
||||
|
||||
if ( l < lengths[0] ) {
|
||||
edgeIdx[1] = edgeIdx[0];
|
||||
lengths[1] = lengths[0];
|
||||
edgeIdx[0] = j;
|
||||
lengths[0] = l;
|
||||
} else if ( l < lengths[1] ) {
|
||||
edgeIdx[1] = j;
|
||||
lengths[1] = l;
|
||||
}
|
||||
}
|
||||
// ref edges
|
||||
const bspDrawVert_t *edges[2][2] = { { ds->verts + edgeVerts[edgeIdx[0]][0], ds->verts + edgeVerts[edgeIdx[0]][1] },
|
||||
{ ds->verts + edgeVerts[edgeIdx[1]][0], ds->verts + edgeVerts[edgeIdx[1]][1] } };
|
||||
|
||||
if( edges[0][0] == edges[1][0]
|
||||
|| edges[0][0] == edges[1][1]
|
||||
|| edges[0][1] == edges[1][0]
|
||||
|| edges[0][1] == edges[1][1] ){
|
||||
Sys_Warning( "autosprite2 surface: two shortest edges share a vertex\n" ); // note also fails on exact square
|
||||
return;
|
||||
}
|
||||
|
||||
// find the midpoints
|
||||
const Vector3 mid[2] = { vector3_mid( edges[0][0]->xyz, edges[0][1]->xyz ),
|
||||
vector3_mid( edges[1][0]->xyz, edges[1][1]->xyz ) };
|
||||
|
||||
// find the vector of the major axis
|
||||
const Vector3 major = mid[1] - mid[0];
|
||||
|
||||
// cross this with the view direction to get minor axis
|
||||
const Vector3 minor = vector3_cross( major, -plane.normal() );
|
||||
|
||||
/* the rest of Autosprite2Deform() algorithm is srsly hot trash
|
||||
thus simply force the order and indexing, which are known as working */
|
||||
|
||||
/* 1-----------2 C C 1-----------2 A ^minor
|
||||
| | | | |
|
||||
B 0-----------3 A B 0-----------3 -----------> major */
|
||||
|
||||
if( vector3_dot( edges[0][1]->xyz - edges[0][0]->xyz, minor ) < 0 )
|
||||
std::swap( edges[0][0], edges[0][1] );
|
||||
if( vector3_dot( edges[1][1]->xyz - edges[1][0]->xyz, minor ) > 0 )
|
||||
std::swap( edges[1][0], edges[1][1] );
|
||||
|
||||
const bspDrawVert_t outverts[4] = { *edges[0][0], *edges[0][1], *edges[1][0], *edges[1][1] };
|
||||
std::copy_n( outverts, 4, ds->verts );
|
||||
|
||||
std::copy_n( std::array<int, 6>{ 3, 0, 2, 2, 0, 1 }.data(), 6, ds->indexes );
|
||||
}
|
||||
|
||||
/*
|
||||
OptimizeTriangleSurface() - ydnar
|
||||
optimizes the vertex/index data in a triangle surface
|
||||
@@ -2383,16 +2466,12 @@ static void OptimizeTriangleSurface( mapDrawSurface_t *ds ){
|
||||
*/
|
||||
|
||||
static void EmitTriangleSurface( mapDrawSurface_t *ds ){
|
||||
int i, temp;
|
||||
|
||||
/* invert the surface if necessary */
|
||||
if ( ds->backSide || ds->shaderInfo->invert ) {
|
||||
/* walk the indexes, reverse the triangle order */
|
||||
for ( i = 0; i < ds->numIndexes; i += 3 )
|
||||
for ( int i = 0; i < ds->numIndexes; i += 3 )
|
||||
{
|
||||
temp = ds->indexes[ i ];
|
||||
ds->indexes[ i ] = ds->indexes[ i + 1 ];
|
||||
ds->indexes[ i + 1 ] = temp;
|
||||
std::swap( ds->indexes[ i ], ds->indexes[ i + 1 ] );
|
||||
}
|
||||
|
||||
/* walk the verts, flip the normal */
|
||||
@@ -2403,6 +2482,12 @@ static void EmitTriangleSurface( mapDrawSurface_t *ds ){
|
||||
vector3_negate( ds->lightmapVecs[ 2 ] );
|
||||
}
|
||||
|
||||
if( ds->shaderInfo->autosprite
|
||||
&& ds->shaderInfo->shaderText != nullptr
|
||||
&& strIstr( ds->shaderInfo->shaderText, "autosprite2" ) != nullptr ){
|
||||
FixAutosprite2Surface( ds );
|
||||
}
|
||||
|
||||
/* allocate a new surface */
|
||||
bspDrawSurface_t& out = bspDrawSurfaces.emplace_back();
|
||||
ds->outputNum = bspDrawSurfaces.size() - 1;
|
||||
@@ -2443,7 +2528,7 @@ static void EmitTriangleSurface( mapDrawSurface_t *ds ){
|
||||
bspDrawVert_t *a, *b, *c;
|
||||
|
||||
/* walk triangle list */
|
||||
for ( i = 0; i < ds->numIndexes; i += 3 )
|
||||
for ( int i = 0; i < ds->numIndexes; i += 3 )
|
||||
{
|
||||
/* get verts */
|
||||
a = &ds->verts[ ds->indexes[ i ] ];
|
||||
@@ -2461,7 +2546,7 @@ static void EmitTriangleSurface( mapDrawSurface_t *ds ){
|
||||
}
|
||||
|
||||
/* RBSP */
|
||||
for ( i = 0; i < MAX_LIGHTMAPS; i++ )
|
||||
for ( int i = 0; i < MAX_LIGHTMAPS; i++ )
|
||||
{
|
||||
out.lightmapNum[ i ] = -3;
|
||||
out.lightmapStyles[ i ] = LS_NONE;
|
||||
|
||||
Reference in New Issue
Block a user