diff --git a/tools/quake3/q3map2/bsp.cpp b/tools/quake3/q3map2/bsp.cpp index 9abf3fc5..c0a68f34 100644 --- a/tools/quake3/q3map2/bsp.cpp +++ b/tools/quake3/q3map2/bsp.cpp @@ -226,17 +226,17 @@ static void FixBrushSides( const entity_t& e ){ } /* walk sideref list */ - for ( const sideRef_t *sideRef = ds.sideRef; sideRef != nullptr; sideRef = sideRef->next ) + for ( const side_t *sideRef : ds.sideRefs ) { /* get bsp brush side */ - if ( sideRef->side.outputNum < 0 ) { + if ( sideRef->outputNum < 0 ) { continue; } - bspBrushSide_t& side = bspBrushSides[ sideRef->side.outputNum ]; + bspBrushSide_t& side = bspBrushSides[ sideRef->outputNum ]; /* set drawsurface */ side.surfaceNum = ds.outputNum; - //% Sys_FPrintf( SYS_VRB, "DS: %7d Side: %7d ", ds.outputNum, sideRef->side->outputNum ); + //% Sys_FPrintf( SYS_VRB, "DS: %7d Side: %7d ", ds.outputNum, sideRef->outputNum ); /* set shader */ if ( !strEqual( bspShaders[ side.shaderNum ].shader, ds.shaderInfo->shader ) ) { diff --git a/tools/quake3/q3map2/decals.cpp b/tools/quake3/q3map2/decals.cpp index cbee2c44..b2dcec55 100644 --- a/tools/quake3/q3map2/decals.cpp +++ b/tools/quake3/q3map2/decals.cpp @@ -535,7 +535,7 @@ static void ProjectDecalOntoWinding( const decalProjector_t& dp, const mapDrawSu static void ProjectDecalOntoFace( const decalProjector_t& dp, const mapDrawSurface_t& ds ){ /* dummy check */ - if ( ds.sideRef == nullptr ) { + if ( ds.sideRefs.empty() ) { return; } diff --git a/tools/quake3/q3map2/fog.cpp b/tools/quake3/q3map2/fog.cpp index a51f46a3..b8b92673 100644 --- a/tools/quake3/q3map2/fog.cpp +++ b/tools/quake3/q3map2/fog.cpp @@ -243,7 +243,7 @@ static bool ChopPatchSurfaceByBrush( mapDrawSurface_t& ds, const brush_t *b ){ /* ydnar: do this the hacky right way */ mapDrawSurface_t& newds = AllocDrawSurface( ESurfaceType::Patch ); - newds = ds; + newds.copyParams( ds ); newds.patchWidth = outside[ i ].width; newds.patchHeight = outside[ i ].height; newds.verts.assign( outside[ i ].begin(), outside[ i ].end() ); @@ -306,10 +306,10 @@ static bool ChopFaceSurfaceByBrush( const entity_t& e, mapDrawSurface_t& ds, con /* dummy check */ - if ( ds.sideRef == nullptr ) { + if ( ds.sideRefs.empty() ) { return false; } - const side_t& sideRef = ds.sideRef->side; + const side_t& sideRef = *ds.sideRefs.front(); /* initial setup */ winding_t w = WindingFromDrawSurf( ds ); @@ -369,8 +369,7 @@ static bool ChopFaceSurfaceByBrush( const entity_t& e, mapDrawSurface_t& ds, con } /* copy new to original */ - ClearSurface( ds ); - ds = *newds; + ds = std::move( *newds ); /* didn't really add a new drawsurface... :) */ numMapDrawSurfs--; diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 862020e6..a981cf50 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -697,15 +697,6 @@ struct side_t }; -struct sideRef_t -{ - sideRef_t *next; - const side_t &side; - sideRef_t( sideRef_t *next, const side_t &side ) : next( next ), side( side ){ - } -}; - - /* ydnar: generic index mapping for entities (natural extension of terrain texturing) */ struct indexMap_t { @@ -794,8 +785,10 @@ public: } mesh_t& operator=( const mesh_t& ) = delete; mesh_t& operator=( mesh_t&& other ) noexcept { - std::destroy_at( this ); - std::construct_at( this, std::move( other ) ); + if( this != &other ){ + std::destroy_at( this ); + std::construct_at( this, std::move( other ) ); + } return *this; }; ~mesh_t(){ @@ -898,7 +891,7 @@ constexpr const char *surfaceTypeName( ESurfaceType type ){ /* ydnar: this struct needs an overhaul (again, heh) */ -struct mapDrawSurface_t +struct mapDrawSurface_t_params { ESurfaceType type; bool planar; @@ -908,25 +901,16 @@ struct mapDrawSurface_t bool skybox; /* ydnar: yet another fun hack */ bool backSide; /* ydnar: q3map_backShader support */ - mapDrawSurface_t *parent; /* ydnar: for cloned (skybox) surfaces to share lighting data */ - mapDrawSurface_t *clone; /* ydnar: for cloned surfaces */ - mapDrawSurface_t *cel; /* ydnar: for cloned cel surfaces */ + class mapDrawSurface_t *parent; /* ydnar: for cloned (skybox) surfaces to share lighting data */ + class mapDrawSurface_t *clone; /* ydnar: for cloned surfaces */ + class mapDrawSurface_t *cel; /* ydnar: for cloned cel surfaces */ shaderInfo_t *shaderInfo; shaderInfo_t *celShader; const brush_t *mapBrush; - sideRef_t *sideRef; int fogNum; - /* vertexes and triangles */ - DrawVerts verts; - DrawIndexes indexes; - - int numVerts() const { - return verts.size(); - }; - int planeNum = -1; Vector3 lightmapOrigin{ 0 }; /* also used for flares */ Vector3 lightmapVecs[ 3 ]{ Vector3( 0 ), Vector3( 0 ), Vector3( 0 ) }; /* also used for flares */ @@ -961,11 +945,26 @@ struct mapDrawSurface_t /* ydnar: editor/useful numbering */ int entityNum; int surfaceNum; +}; +struct mapDrawSurface_t : public mapDrawSurface_t_params +{ + /* vertexes and triangles */ + DrawVerts verts; + DrawIndexes indexes; - void addSideRef( const side_t *side ){ - if ( side != nullptr ) { - sideRef = new sideRef_t( sideRef, *side ); - } + int numVerts() const { + return verts.size(); + }; + + std::vector sideRefs; + + void addSideRef( const side_t *side ){ // note might store only unique refs + if ( side != nullptr ) + sideRefs.push_back( side ); + } + + void copyParams( const mapDrawSurface_t& other ){ + static_cast( *this ) = static_cast( other ); } }; diff --git a/tools/quake3/q3map2/surface.cpp b/tools/quake3/q3map2/surface.cpp index 3ceee47e..db5c3d89 100644 --- a/tools/quake3/q3map2/surface.cpp +++ b/tools/quake3/q3map2/surface.cpp @@ -107,11 +107,10 @@ mapDrawSurface_t *CloneSurface( const mapDrawSurface_t& src, shaderInfo_t *si ){ /* allocate a new surface */ mapDrawSurface_t& ds = AllocDrawSurface( src.type ); - /* copy it */ - ds = src; - - /* destroy side reference */ - ds.sideRef = nullptr; + /* copy it besides side references */ + ds.copyParams( src ); + ds.verts = src.verts; + ds.indexes = src.indexes; /* set shader */ ds.shaderInfo = si; @@ -195,6 +194,7 @@ void ClearSurface( mapDrawSurface_t& ds ){ ds.planeNum = -1; ds.verts = DrawVerts(); // deallocate ds.indexes = DrawIndexes(); // deallocate + ds.sideRefs = decltype( ds.sideRefs )(); // deallocate } @@ -1085,13 +1085,13 @@ void SubdivideFaceSurfaces( const entity_t& e ){ for ( mapDrawSurface_t& ds : Span( mapDrawSurfs + e.firstDrawSurf, mapDrawSurfs + numMapDrawSurfs ) ) { /* only subdivide brush sides */ - if ( ds.type != ESurfaceType::Face || ds.mapBrush == nullptr || ds.sideRef == nullptr ) { + if ( ds.type != ESurfaceType::Face || ds.mapBrush == nullptr || ds.sideRefs.empty() ) { continue; } /* get bits */ const brush_t *brush = ds.mapBrush; - const side_t& side = ds.sideRef->side; + const side_t& side = *ds.sideRefs.front(); /* check subdivision for shader */ const shaderInfo_t *si = side.shaderInfo; diff --git a/tools/quake3/q3map2/surface_meta.cpp b/tools/quake3/q3map2/surface_meta.cpp index f269cf0d..422499fc 100644 --- a/tools/quake3/q3map2/surface_meta.cpp +++ b/tools/quake3/q3map2/surface_meta.cpp @@ -305,7 +305,7 @@ static void SurfaceToMetaTriangles( mapDrawSurface_t& ds ){ /* build a metatriangle */ metaTriangle_t src; src.si = ds.shaderInfo; - src.side = ( ds.sideRef != nullptr ? &ds.sideRef->side : nullptr ); + src.side = ( ds.sideRefs.empty()? nullptr : ds.sideRefs.front() ); src.entityNum = ds.entityNum; src.surfaceNum = ds.surfaceNum; src.planeNum = ds.planeNum; @@ -359,7 +359,7 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){ /* make a copy of the drawsurface */ mapDrawSurface_t& dsNew = AllocDrawSurface( ESurfaceType::Meta ); - dsNew = ds; + dsNew.copyParams( ds ); /* if the patch is nonsolid, then discard it */ if ( !( ds.shaderInfo->compileFlags & C_SOLID ) && !( ds.shaderInfo->contentFlags & GetRequiredSurfaceParm<"playerclip">().contentFlags ) ) { @@ -368,7 +368,6 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){ /* basic transmogrification */ dsNew.type = ESurfaceType::Meta; - dsNew.indexes.clear(); dsNew.indexes.reserve( ( mesh.width - 1 ) * ( mesh.height - 1 ) * 6 ); /* copy the verts in */