* patch thicken: create new patches in original patch entity

aabb degenerate check of 'opposite wall'
This commit is contained in:
Garux 2021-10-19 18:25:42 +03:00
parent 197f9e7cb4
commit 36a1495e33

View File

@ -169,9 +169,9 @@ void Scene_PatchDoCap_Selected( scene::Graph& graph, const char* shader ){
InstanceVector instances; InstanceVector instances;
Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) ); Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) );
for ( InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i ) for ( auto i : instances )
{ {
Patch_makeCaps( *Node_getPatch( ( *i )->path().top() ), *( *i ), eType, shader ); Patch_makeCaps( *Node_getPatch( i->path().top() ), *i, eType, shader );
} }
} }
} }
@ -192,19 +192,25 @@ void Scene_PatchDeform( scene::Graph& graph, const int deform, const int axis )
{ {
InstanceVector instances; InstanceVector instances;
Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) ); Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) );
for ( InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i ) for ( auto i : instances )
{ {
Patch_deform( *Node_getPatch( ( *i )->path().top() ), *( *i ), deform, axis ); Patch_deform( *Node_getPatch( i->path().top() ), *i, deform, axis );
} }
} }
void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickness, bool seams, const int axis ){ void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickness, bool seams, const int axis ){
const auto aabb_small = []( const AABB& aabb ){
return ( aabb.extents[0] < 0.01 && aabb.extents[1] < 0.01 ) ||
( aabb.extents[1] < 0.01 && aabb.extents[2] < 0.01 ) ||
( aabb.extents[0] < 0.01 && aabb.extents[2] < 0.01 );
};
// Create a new patch node // Create a new patch node
NodeSmartReference node( g_patchCreator->createPatch() ); NodeSmartReference node( g_patchCreator->createPatch() );
// Insert the node into worldspawn // Insert the node into original's entity
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node ); Node_getTraversable( instance.path().parent() )->insert( node );
// Retrieve the contained patch from the node // Retrieve the contained patch from the node
Patch* targetPatch = Node_getPatch( node ); Patch* targetPatch = Node_getPatch( node );
@ -214,29 +220,21 @@ void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickne
bool no34 = true; bool no34 = true;
targetPatch->createThickenedOpposite( patch, thickness, axis, no12, no34 ); targetPatch->createThickenedOpposite( patch, thickness, axis, no12, no34 );
// Now select the newly created patches { // Now select the newly created patch
{ scene::Path path( instance.parent()->path() );
scene::Path patchpath( makeReference( GlobalSceneGraph().root() ) ); path.push( makeReference( node.get() ) );
patchpath.push( makeReference( *Map_GetWorldspawn( g_map ) ) ); selectPath( path, true );
patchpath.push( makeReference( node.get() ) );
Instance_getSelectable( *GlobalSceneGraph().find( patchpath ) )->setSelected( true );
} }
if( seams && thickness != 0.0f ){ if( seams && thickness != 0.0f ){
int i = 0; int i = no12? 2 : 0;
if ( no12 ){ int iend = no34? 2 : 4;
i = 2;
}
int iend = 4;
if ( no34 ){
iend = 2;
}
// Now create the four walls // Now create the four walls
for ( ; i < iend; i++ ){ for ( ; i < iend; ++i ){
// Allocate new patch // Allocate new patch
NodeSmartReference node = NodeSmartReference( g_patchCreator->createPatch() ); NodeSmartReference node = NodeSmartReference( g_patchCreator->createPatch() );
// Insert each node into worldspawn // Insert each node into worldspawn
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->insert( node ); Node_getTraversable( instance.path().parent() )->insert( node );
// Retrieve the contained patch from the node // Retrieve the contained patch from the node
Patch* wallPatch = Node_getPatch( node ); Patch* wallPatch = Node_getPatch( node );
@ -244,34 +242,34 @@ void Patch_thicken( Patch& patch, scene::Instance& instance, const float thickne
// Create the wall patch by passing i as wallIndex // Create the wall patch by passing i as wallIndex
wallPatch->createThickenedWall( patch, *targetPatch, i ); wallPatch->createThickenedWall( patch, *targetPatch, i );
if( ( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[1] <= 0.00005 ) || if( aabb_small( wallPatch->localAABB() ) ){
( wallPatch->localAABB().extents[1] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ||
( wallPatch->localAABB().extents[0] <= 0.00005 && wallPatch->localAABB().extents[2] <= 0.00005 ) ){
//globalOutputStream() << "Thicken: Discarding degenerate patch.\n"; //globalOutputStream() << "Thicken: Discarding degenerate patch.\n";
Node_getTraversable( Map_FindOrInsertWorldspawn( g_map ) )->erase( node ); Node_getTraversable( instance.path().parent() )->erase( node );
} }
else else { // Now select the newly created patch
// Now select the newly created patches scene::Path path( instance.parent()->path() );
{ path.push( makeReference( node.get() ) );
scene::Path patchpath( makeReference( GlobalSceneGraph().root() ) ); selectPath( path, true );
patchpath.push( makeReference( *Map_GetWorldspawn(g_map) ) );
patchpath.push( makeReference( node.get() ) );
Instance_getSelectable( *GlobalSceneGraph().find( patchpath ) )->setSelected( true );
} }
} }
} }
// Invert the target patch so that it faces the opposite direction // Invert the target patch so that it faces the opposite direction
targetPatch->InvertMatrix(); targetPatch->InvertMatrix();
if( aabb_small( targetPatch->localAABB() ) ){
//globalOutputStream() << "Thicken: Discarding degenerate patch.\n";
Node_getTraversable( instance.path().parent() )->erase( node );
}
} }
void Scene_PatchThicken( scene::Graph& graph, const int thickness, bool seams, const int axis ) void Scene_PatchThicken( scene::Graph& graph, const int thickness, bool seams, const int axis )
{ {
InstanceVector instances; InstanceVector instances;
Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) ); Scene_forEachVisibleSelectedPatchInstance( PatchStoreInstance( instances ) );
for ( InstanceVector::const_iterator i = instances.begin(); i != instances.end(); ++i ) for ( auto i : instances )
{ {
Patch_thicken( *Node_getPatch( ( *i )->path().top() ), *( *i ), thickness, seams, axis ); Patch_thicken( *Node_getPatch( i->path().top() ), *i, thickness, seams, axis );
} }
} }