X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fcsg.cpp;h=9de2dca24f705960f6adc8f5c24b14e0818f093a;hb=e876e8ef487eeb9123f4906373622ffe3b6ea9d4;hp=aab9caa573972a18d36e6ac677f1d095b168dd50;hpb=f73cc19a6166fc04269f953c980175779f81b9b0;p=xonotic%2Fnetradiant.git diff --git a/radiant/csg.cpp b/radiant/csg.cpp index aab9caa5..9de2dca2 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -57,31 +57,40 @@ void Face_makeBrush( Face& face, const Brush& brush, brush_vector_t& out, float } } -class FaceMakeBrush -{ -const Brush& brush; -brush_vector_t& out; -float offset; -public: -FaceMakeBrush( const Brush& brush, brush_vector_t& out, float offset ) - : brush( brush ), out( out ), offset( offset ){ +void Face_makeRoom( Face &face, const Brush &brush, brush_vector_t &out, float offset ){ + if ( face.contributes() ) { + face.getPlane().offset( offset ); + out.push_back( new Brush( brush ) ); + face.getPlane().offset( -offset ); + Face* newFace = out.back()->addFace( face ); + if ( newFace != 0 ) { + newFace->flipWinding(); + newFace->planeChanged(); + } + } } -void operator()( Face& face ) const { - Face_makeBrush( face, brush, out, offset ); + +void Brush_makeHollow( const Brush &brush, brush_vector_t &out, float offset ){ + Brush_forEachFace( brush, [&]( Face &face ) { + Face_makeBrush( face, brush, out, offset ); + } ); } -}; -void Brush_makeHollow( const Brush& brush, brush_vector_t& out, float offset ){ - Brush_forEachFace( brush, FaceMakeBrush( brush, out, offset ) ); +void Brush_makeRoom( const Brush &brush, brush_vector_t &out, float offset ){ + Brush_forEachFace( brush, [&]( Face &face ) { + Face_makeRoom( face, brush, out, offset ); + } ); } class BrushHollowSelectedWalker : public scene::Graph::Walker { float m_offset; +bool m_makeRoom; public: -BrushHollowSelectedWalker( float offset ) - : m_offset( offset ){ +BrushHollowSelectedWalker( float offset, bool makeRoom ) + : m_offset( offset ), m_makeRoom( makeRoom ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { Brush* brush = Node_getBrush( path.top() ); @@ -89,7 +98,15 @@ bool pre( const scene::Path& path, scene::Instance& instance ) const { && Instance_getSelectable( instance )->isSelected() && path.size() > 1 ) { brush_vector_t out; - Brush_makeHollow( *brush, out, m_offset ); + + if ( m_makeRoom ) { + Brush_makeRoom(* brush, out, m_offset ); + } + else + { + Brush_makeHollow(* brush, out, m_offset ); + } + for ( brush_vector_t::const_iterator i = out.begin(); i != out.end(); ++i ) { ( *i )->removeEmptyFaces(); @@ -113,6 +130,7 @@ public: BrushGatherSelected( brush_vector_t& brushlist ) : m_brushlist( brushlist ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { Brush* brush = Node_getBrush( path.top() ); @@ -143,8 +161,8 @@ void post( const scene::Path& path, scene::Instance& instance ) const { } }; -void Scene_BrushMakeHollow_Selected( scene::Graph& graph ){ - GlobalSceneGraph().traverse( BrushHollowSelectedWalker( GetGridSize() ) ); +void Scene_BrushMakeHollow_Selected( scene::Graph& graph, bool makeRoom ){ + GlobalSceneGraph().traverse( BrushHollowSelectedWalker( GetGridSize(), makeRoom ) ); GlobalSceneGraph().traverse( BrushDeleteSelected() ); } @@ -157,7 +175,15 @@ void Scene_BrushMakeHollow_Selected( scene::Graph& graph ){ void CSG_MakeHollow( void ){ UndoableCommand undo( "brushHollow" ); - Scene_BrushMakeHollow_Selected( GlobalSceneGraph() ); + Scene_BrushMakeHollow_Selected( GlobalSceneGraph(), false ); + + SceneChangeNotify(); +} + +void CSG_MakeRoom( void ){ + UndoableCommand undo( "brushRoom" ); + + Scene_BrushMakeHollow_Selected( GlobalSceneGraph(), true ); SceneChangeNotify(); } @@ -181,11 +207,9 @@ class Dereference { const Functor& functor; public: -typedef typename RemoveReference::type* first_argument_type; -typedef typename Functor::result_type result_type; Dereference( const Functor& functor ) : functor( functor ){ } -result_type operator()( first_argument_type firstArgument ) const { +get_result_type operator()( typename RemoveReference>::type *firstArgument ) const { return functor( *firstArgument ); } }; @@ -207,15 +231,14 @@ Face* Brush_findIf( const Brush& brush, const Predicate& predicate ){ template class BindArguments1 { -typedef typename Caller::second_argument_type FirstBound; +typedef get_argument FirstBound; FirstBound firstBound; public: -typedef typename Caller::result_type result_type; -typedef typename Caller::first_argument_type first_argument_type; BindArguments1( FirstBound firstBound ) : firstBound( firstBound ){ } -result_type operator()( first_argument_type firstArgument ) const { + +get_result_type operator()( get_argument firstArgument ) const { return Caller::call( firstArgument, firstBound ); } }; @@ -223,17 +246,16 @@ result_type operator()( first_argument_type firstArgument ) const { template class BindArguments2 { -typedef typename Caller::second_argument_type FirstBound; -typedef typename Caller::third_argument_type SecondBound; +typedef get_argument FirstBound; +typedef get_argument SecondBound; FirstBound firstBound; SecondBound secondBound; public: -typedef typename Caller::result_type result_type; -typedef typename Caller::first_argument_type first_argument_type; BindArguments2( FirstBound firstBound, SecondBound secondBound ) : firstBound( firstBound ), secondBound( secondBound ){ } -result_type operator()( first_argument_type firstArgument ) const { + +get_result_type operator()( get_argument firstArgument ) const { return Caller::call( firstArgument, firstBound, secondBound ); } }; @@ -246,8 +268,8 @@ BindArguments2 bindArguments( const Caller& caller, FirstBound firstBoun inline bool Face_testPlane( const Face& face, const Plane3& plane, bool flipped ){ return face.contributes() && !Winding_TestPlane( face.getWinding(), plane, flipped ); } -typedef Function3 FaceTestPlane; +typedef Function FaceTestPlane; /// \brief Returns true if @@ -323,9 +345,11 @@ public: SubtractBrushesFromUnselected( const brush_vector_t& brushlist, std::size_t& before, std::size_t& after ) : m_brushlist( brushlist ), m_before( before ), m_after( after ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { return true; } + void post( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { Brush* brush = Node_getBrush( path.top() ); @@ -420,9 +444,11 @@ public: BrushSplitByPlaneSelected( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection, EBrushSplit split ) : m_p0( p0 ), m_p1( p1 ), m_p2( p2 ), m_shader( shader ), m_projection( projection ), m_split( split ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { return true; } + void post( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { Brush* brush = Node_getBrush( path.top() ); @@ -486,6 +512,7 @@ public: BrushInstanceSetClipPlane( const Plane3& plane ) : m_plane( plane ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { BrushInstance* brush = Instance_getBrush( instance ); if ( brush != 0