X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=radiant%2Fcsg.cpp;h=44fefdc863484ec9759fb806724b08f04268fa8c;hb=b2827b118808cd6929d39ca7c628b8429542984f;hp=5676401eb982d0ce37bbdbde391c8ab67c71f551;hpb=b7e36c120eb1546a6c6f97f30e42ab7f9a559c61;p=xonotic%2Fnetradiant.git diff --git a/radiant/csg.cpp b/radiant/csg.cpp index 5676401e..44fefdc8 100644 --- a/radiant/csg.cpp +++ b/radiant/csg.cpp @@ -42,31 +42,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() ); @@ -74,7 +83,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(); @@ -98,6 +115,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() ); @@ -128,8 +146,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() ); } @@ -142,7 +160,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(); } @@ -166,11 +192,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 ); } }; @@ -192,15 +216,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 ); } }; @@ -208,17 +231,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 ); } }; @@ -231,8 +253,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 @@ -308,9 +330,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() ); @@ -405,9 +429,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() ); @@ -471,6 +497,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