X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=radiant%2Fbrush.h;h=7748327d089b520da17d63caa28ceffe2c5d4af7;hp=0fb6ffe225c2b0d3dbe45d0a8b3d5fb08a07079f;hb=110313f1465df17a8dccd6429279ddb27e51ef2d;hpb=7fc621fc78d0e040dc2c12f38dc53dd9048215dc diff --git a/radiant/brush.h b/radiant/brush.h index 0fb6ffe2..7748327d 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -102,7 +102,6 @@ inline void print_3x3( const Matrix4& m ){ } - inline bool texdef_sane( const texdef_t& texdef ){ return fabs( texdef.shift[0] ) < ( 1 << 16 ) && fabs( texdef.shift[1] ) < ( 1 << 16 ); @@ -308,23 +307,8 @@ class FaceShaderObserver { public: virtual void realiseShader() = 0; -virtual void unrealiseShader() = 0; -}; - -class FaceShaderObserverRealise -{ -public: -void operator()( FaceShaderObserver& observer ) const { - observer.realiseShader(); -} -}; -class FaceShaderObserverUnrealise -{ -public: -void operator()( FaceShaderObserver& observer ) const { - observer.unrealiseShader(); -} +virtual void unrealiseShader() = 0; }; typedef ReferencePair FaceShaderObserverPair; @@ -335,12 +319,14 @@ class ContentsFlagsValue public: ContentsFlagsValue(){ } + ContentsFlagsValue( int surfaceFlags, int contentFlags, int value, bool specified ) : m_surfaceFlags( surfaceFlags ), m_contentFlags( contentFlags ), m_value( value ), m_specified( specified ){ } + int m_surfaceFlags; int m_contentFlags; int m_value; @@ -376,7 +362,7 @@ SavedState( const FaceShader& faceShader ){ void exportState( FaceShader& faceShader ) const { faceShader.setShader( m_shader.c_str() ); - faceShader.setFlags( m_flags ); + faceShader.m_flags = m_flags; } }; @@ -395,9 +381,11 @@ FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsV m_realised( false ){ captureShader(); } + ~FaceShader(){ releaseShader(); } + // copy-construction not supported FaceShader( const FaceShader& other ); @@ -405,6 +393,7 @@ void instanceAttach(){ m_instanced = true; m_state->incrementUsed(); } + void instanceDetach(){ m_state->decrementUsed(); m_instanced = false; @@ -416,6 +405,7 @@ void captureShader(){ m_state = GlobalShaderCache().capture( m_shader.c_str() ); m_state->attach( *this ); } + void releaseShader(){ ASSERT_MESSAGE( m_state != 0, "shader cannot be released" ); m_state->detach( *this ); @@ -426,11 +416,16 @@ void releaseShader(){ void realise(){ ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" ); m_realised = true; - m_observers.forEach( FaceShaderObserverRealise() ); + m_observers.forEach([](FaceShaderObserver &observer) { + observer.realiseShader(); + }); } + void unrealise(){ ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" ); - m_observers.forEach( FaceShaderObserverUnrealise() ); + m_observers.forEach([](FaceShaderObserver &observer) { + observer.unrealiseShader(); + }); m_realised = false; } @@ -462,6 +457,7 @@ void setShader( const char* name ){ m_state->incrementUsed(); } } + ContentsFlagsValue getFlags() const { ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" ); if ( !m_flags.m_specified ) { @@ -474,6 +470,7 @@ ContentsFlagsValue getFlags() const { } return m_flags; } + void setFlags( const ContentsFlagsValue& flags ){ ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" ); ContentsFlagsValue_assignMasked( m_flags, flags ); @@ -489,12 +486,14 @@ std::size_t width() const { } return 1; } + std::size_t height() const { if ( m_realised ) { return m_state->getTexture().height; } return 1; } + unsigned int shaderFlags() const { if ( m_realised ) { return m_state->getFlags(); @@ -504,14 +503,14 @@ unsigned int shaderFlags() const { }; - - class FaceTexdef : public FaceShaderObserver { // not copyable FaceTexdef( const FaceTexdef& other ); + // not assignable FaceTexdef& operator=( const FaceTexdef& other ); + public: class SavedState { @@ -543,6 +542,7 @@ FaceTexdef( m_scaleApplied( false ){ m_shader.attach( *this ); } + ~FaceTexdef(){ m_shader.detach( *this ); } @@ -552,6 +552,7 @@ void addScale(){ m_scaleApplied = true; m_projection.m_brushprimit_texdef.addScale( m_shader.width(), m_shader.height() ); } + void removeScale(){ ASSERT_MESSAGE( m_scaleApplied, "texture scale aready removed" ); m_scaleApplied = false; @@ -563,6 +564,7 @@ void realiseShader(){ addScale(); } } + void unrealiseShader(){ if ( m_projectionInitialised && m_scaleApplied ) { removeScale(); @@ -613,6 +615,7 @@ TextureProjection normalised() const { tmp.removeScale( m_shader.width(), m_shader.height() ); return TextureProjection( m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t ); } + void setBasis( const Vector3& normal ){ Matrix4 basis; Normal_GetTransform( normal, basis ); @@ -683,6 +686,7 @@ void exportState( FacePlane& facePlane ) const { FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){ } + FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){ if ( !isDoom3Plane() ) { planepts_assign( m_planepts, other.m_planepts ); @@ -719,6 +723,7 @@ void reverse(){ updateSource(); } } + void transform( const Matrix4& matrix, bool mirror ){ if ( !isDoom3Plane() ) { @@ -749,6 +754,7 @@ void transform( const Matrix4& matrix, bool mirror ){ updateSource(); } } + void offset( float offset ){ if ( !isDoom3Plane() ) { Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) ); @@ -769,6 +775,7 @@ void offset( float offset ){ void updateTranslated(){ m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin ); } + void updateSource(){ m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) ); } @@ -777,16 +784,20 @@ void updateSource(){ PlanePoints& planePoints(){ return m_planepts; } + const PlanePoints& planePoints() const { return m_planepts; } + const Plane3& plane3() const { return m_planeCached; } + void setDoom3Plane( const Plane3& plane ){ m_plane = plane; updateTranslated(); } + const Plane3& getDoom3Plane() const { return m_plane; } @@ -802,6 +813,7 @@ void copy( const FacePlane& other ){ updateSource(); } } + void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){ if ( !isDoom3Plane() ) { m_planepts[0] = p0; @@ -842,9 +854,11 @@ virtual bool filter( const Face& face ) const = 0; }; bool face_filtered( Face& face ); + void add_face_filter( FaceFilter& filter, int mask, bool invert = false ); void Brush_addTextureChangedCallback( const SignalHandler& callback ); + void Brush_textureChanged(); @@ -854,8 +868,11 @@ class FaceObserver { public: virtual void planeChanged() = 0; + virtual void connectivityChanged() = 0; + virtual void shaderChanged() = 0; + virtual void evaluateTransform() = 0; }; @@ -911,6 +928,7 @@ MapFile* m_map; // assignment not supported Face& operator=( const Face& other ); + // copy-construction not supported Face( const Face& other ); @@ -929,6 +947,7 @@ Face( FaceObserver* observer ) : m_texdef.setBasis( m_plane.plane3().normal() ); planeChanged(); } + Face( const Vector3& p0, const Vector3& p1, @@ -949,6 +968,7 @@ Face( planeChanged(); updateFiltered(); } + Face( const Face& other, FaceObserver* observer ) : m_refcount( 0 ), m_shader( other.m_shader.getShader(), other.m_shader.m_flags ), @@ -963,6 +983,7 @@ Face( const Face& other, FaceObserver* observer ) : planeChanged(); updateFiltered(); } + ~Face(){ m_shader.detach( *this ); } @@ -975,6 +996,7 @@ void planeChanged(){ void realiseShader(){ m_observer->shaderChanged(); } + void unrealiseShader(){ } @@ -999,6 +1021,7 @@ void render( RenderStateFlags state ) const { void updateFiltered(){ m_filtered = face_filtered( *this ); } + bool isFiltered() const { return m_filtered; } @@ -1016,6 +1039,7 @@ void undoSave(){ UndoMemento* exportState() const { return new SavedState( *this ); } + void importState( const UndoMemento* data ){ undoSave(); @@ -1031,6 +1055,7 @@ void importState( const UndoMemento* data ){ void IncRef(){ ++m_refcount; } + void DecRef(){ if ( --m_refcount == 0 ) { delete this; @@ -1079,6 +1104,7 @@ void revertTransform(){ planepts_assign( m_move_planeptsTransformed, m_move_planepts ); m_texdefTransformed = m_texdef.m_projection; } + void freezeTransform(){ undoSave(); m_plane = m_planeTransformed; @@ -1141,6 +1167,7 @@ void shaderChanged(){ const char* GetShader() const { return m_shader.getShader(); } + void SetShader( const char* name ){ undoSave(); m_shader.setShader( name ); @@ -1150,6 +1177,7 @@ void SetShader( const char* name ){ void revertTexdef(){ m_texdefTransformed = m_texdef.m_projection; } + void texdefChanged(){ revertTexdef(); EmitTextureCoordinates(); @@ -1159,6 +1187,7 @@ void texdefChanged(){ void GetTexdef( TextureProjection& projection ) const { projection = m_texdef.normalised(); } + void SetTexdef( const TextureProjection& projection ){ undoSave(); m_texdef.setTexdef( projection ); @@ -1168,6 +1197,7 @@ void SetTexdef( const TextureProjection& projection ){ void GetFlags( ContentsFlagsValue& flags ) const { flags = m_shader.getFlags(); } + void SetFlags( const ContentsFlagsValue& flags ){ undoSave(); m_shader.setFlags( flags ); @@ -1215,6 +1245,7 @@ void construct_centroid(){ const Winding& getWinding() const { return m_winding; } + Winding& getWinding(){ return m_winding; } @@ -1223,21 +1254,27 @@ const Plane3& plane3() const { m_observer->evaluateTransform(); return m_planeTransformed.plane3(); } + FacePlane& getPlane(){ return m_plane; } + const FacePlane& getPlane() const { return m_plane; } + FaceTexdef& getTexdef(){ return m_texdef; } + const FaceTexdef& getTexdef() const { return m_texdef; } + FaceShader& getShader(){ return m_shader; } + const FaceShader& getShader() const { return m_shader; } @@ -1245,6 +1282,7 @@ const FaceShader& getShader() const { bool isDetail() const { return ( m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK ) != 0; } + void setDetail( bool detail ){ undoSave(); if ( detail && !isDetail() ) { @@ -1259,6 +1297,7 @@ void setDetail( bool detail ){ bool contributes() const { return m_winding.numpoints > 2; } + bool is_bounded() const { for ( Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i ) { @@ -1284,6 +1323,7 @@ FaceVertexId( std::size_t face, std::size_t vertex ) std::size_t getFace() const { return m_face; } + std::size_t getVertex() const { return m_vertex; } @@ -1299,6 +1339,7 @@ struct EdgeRenderIndices EdgeRenderIndices() : first( 0 ), second( 0 ){ } + EdgeRenderIndices( const RenderIndex _first, const RenderIndex _second ) : first( _first ), second( _second ){ } @@ -1312,6 +1353,7 @@ struct EdgeFaces EdgeFaces() : first( c_brush_maxFaces ), second( c_brush_maxFaces ){ } + EdgeFaces( const faceIndex_t _first, const faceIndex_t _second ) : first( _first ), second( _second ){ } @@ -1342,6 +1384,7 @@ const PointVertex* m_vertices; }; class Brush; + typedef std::vector brush_vector_t; class BrushFilter @@ -1351,6 +1394,7 @@ virtual bool filter( const Brush& brush ) const = 0; }; bool brush_filtered( Brush& brush ); + void add_brush_filter( BrushFilter& filter, int mask, bool invert = false ); @@ -1402,6 +1446,7 @@ FaceVertexId m_faceVertex; SelectableEdge( Faces& faces, FaceVertexId faceVertex ) : m_faces( faces ), m_faceVertex( faceVertex ){ } + SelectableEdge& operator=( const SelectableEdge& other ){ m_faceVertex = other.m_faceVertex; return *this; @@ -1429,6 +1474,7 @@ FaceVertexId m_faceVertex; SelectableVertex( Faces& faces, FaceVertexId faceVertex ) : m_faces( faces ), m_faceVertex( faceVertex ){ } + SelectableVertex& operator=( const SelectableVertex& other ){ m_faceVertex = other.m_faceVertex; return *this; @@ -1447,16 +1493,23 @@ class BrushObserver { public: virtual void reserve( std::size_t size ) = 0; + virtual void clear() = 0; + virtual void push_back( Face& face ) = 0; + virtual void pop_back() = 0; + virtual void erase( std::size_t index ) = 0; + virtual void connectivityChanged() = 0; virtual void edge_clear() = 0; + virtual void edge_push_back( SelectableEdge& edge ) = 0; virtual void vertex_clear() = 0; + virtual void vertex_push_back( SelectableVertex& vertex ) = 0; virtual void DEBUG_verify() const = 0; @@ -1510,8 +1563,8 @@ Array m_edge_faces; AABB m_aabb_local; // ---- -Callback m_evaluateTransform; -Callback m_boundsChanged; +Callback m_evaluateTransform; +Callback m_boundsChanged; mutable bool m_planeChanged; // b-rep evaluation required mutable bool m_transformChanged; // transform evaluation required @@ -1520,7 +1573,7 @@ mutable bool m_transformChanged; // transform evaluation required public: STRING_CONSTANT( Name, "Brush" ); -Callback m_lightsChanged; +Callback m_lightsChanged; // static data static Shader* m_state_point; @@ -1529,7 +1582,7 @@ static Shader* m_state_point; static EBrushType m_type; static double m_maxWorldCoord; -Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) : +Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) : m_node( &node ), m_undoable_observer( 0 ), m_map( 0 ), @@ -1542,7 +1595,7 @@ Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& bou m_transformChanged( false ){ planeChanged(); } -Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) : +Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) : m_node( &node ), m_undoable_observer( 0 ), m_map( 0 ), @@ -1555,6 +1608,7 @@ Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, m_transformChanged( false ){ copy( other ); } + Brush( const Brush& other ) : TransformNode( other ), Bounded( other ), @@ -1575,6 +1629,7 @@ Brush( const Brush& other ) : m_transformChanged( false ){ copy( other ); } + ~Brush(){ ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" ); } @@ -1611,6 +1666,7 @@ void attach( BrushObserver& observer ){ m_observers.insert( &observer ); } + void detach( BrushObserver& observer ){ m_observers.erase( &observer ); } @@ -1628,6 +1684,7 @@ void forEachFace_instanceAttach( MapFile* map ) const { ( *i )->instanceAttach( map ); } } + void forEachFace_instanceDetach( MapFile* map ) const { for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i ) { @@ -1636,6 +1693,7 @@ void forEachFace_instanceDetach( MapFile* map ) const { } InstanceCounter m_instanceCounter; + void instanceAttach( const scene::Path& path ){ if ( ++m_instanceCounter.m_count == 1 ) { m_map = path_find_mapfile( path.begin(), path.end() ); @@ -1648,6 +1706,7 @@ void instanceAttach( const scene::Path& path ){ ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" ); } } + void instanceDetach( const scene::Path& path ){ if ( --m_instanceCounter.m_count == 0 ) { forEachFace_instanceDetach( m_map ); @@ -1662,8 +1721,10 @@ void instanceDetach( const scene::Path& path ){ const char* name() const { return "brush"; } + void attach( const NameCallback& callback ){ } + void detach( const NameCallback& callback ){ } @@ -1686,6 +1747,7 @@ void planeChanged(){ aabbChanged(); m_lightsChanged(); } + void shaderChanged(){ updateFiltered(); planeChanged(); @@ -1702,7 +1764,8 @@ void transformChanged(){ m_transformChanged = true; planeChanged(); } -typedef MemberCaller TransformChangedCaller; + +typedef MemberCaller TransformChangedCaller; void evaluateTransform(){ if ( m_transformChanged ) { @@ -1711,12 +1774,15 @@ void evaluateTransform(){ m_evaluateTransform(); } } + const Matrix4& localToParent() const { return g_matrix4_identity; } + void aabbChanged(){ m_boundsChanged(); } + const AABB& localAABB() const { evaluateBRep(); return m_aabb_local; @@ -1751,18 +1817,21 @@ void transform( const Matrix4& matrix ){ ( *i )->transform( matrix, mirror ); } } + void snapto( float snap ){ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i ) { ( *i )->snapto( snap ); } } + void revertTransform(){ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i ) { ( *i )->revertTransform(); } } + void freezeTransform(){ for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i ) { @@ -1794,6 +1863,7 @@ class BrushUndoMemento : public UndoMemento public: BrushUndoMemento( const Faces& faces ) : m_faces( faces ){ } + void release(){ delete this; } @@ -1872,6 +1942,7 @@ static void constructStatic( EBrushType type ){ m_state_point = GlobalShaderCache().capture( "$POINT" ); } + static void destroyStatic(){ GlobalShaderCache().release( "$POINT" ); } @@ -1885,6 +1956,7 @@ typedef Faces::const_iterator const_iterator; const_iterator begin() const { return m_faces.begin(); } + const_iterator end() const { return m_faces.end(); } @@ -1892,9 +1964,11 @@ const_iterator end() const { Face* back(){ return m_faces.back(); } + const Face* back() const { return m_faces.back(); } + void reserve( std::size_t count ){ m_faces.reserve( count ); for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) @@ -1902,6 +1976,7 @@ void reserve( std::size_t count ){ ( *i )->reserve( count ); } } + void push_back( Faces::value_type face ){ m_faces.push_back( face ); if ( m_instanceCounter.m_count != 0 ) { @@ -1913,6 +1988,7 @@ void push_back( Faces::value_type face ){ ( *i )->DEBUG_verify(); } } + void pop_back(){ if ( m_instanceCounter.m_count != 0 ) { m_faces.back()->instanceDetach( m_map ); @@ -1924,6 +2000,7 @@ void pop_back(){ ( *i )->DEBUG_verify(); } } + void erase( std::size_t index ){ if ( m_instanceCounter.m_count != 0 ) { m_faces[index]->instanceDetach( m_map ); @@ -1935,6 +2012,7 @@ void erase( std::size_t index ){ ( *i )->DEBUG_verify(); } } + void connectivityChanged(){ for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) { @@ -1955,9 +2033,11 @@ void clear(){ ( *i )->DEBUG_verify(); } } + std::size_t size() const { return m_faces.size(); } + bool empty() const { return m_faces.empty(); } @@ -2105,6 +2185,7 @@ void edge_push_back( FaceVertexId faceVertex ){ ( *i )->edge_push_back( m_select_edges.back() ); } } + void edge_clear(){ m_select_edges.clear(); for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) @@ -2112,6 +2193,7 @@ void edge_clear(){ ( *i )->edge_clear(); } } + void vertex_push_back( FaceVertexId faceVertex ){ m_select_vertices.push_back( SelectableVertex( m_faces, faceVertex ) ); for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) @@ -2119,6 +2201,7 @@ void vertex_push_back( FaceVertexId faceVertex ){ ( *i )->vertex_push_back( m_select_vertices.back() ); } } + void vertex_clear(){ m_select_vertices.clear(); for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i ) @@ -2325,7 +2408,6 @@ void buildBRep(); }; - class FaceInstance; class FaceInstanceSet @@ -2336,6 +2418,7 @@ public: void insert( FaceInstance& faceInstance ){ m_faceInstances.append( faceInstance ); } + void erase( FaceInstance& faceInstance ){ m_faceInstances.erase( faceInstance ); } @@ -2351,6 +2434,7 @@ void foreach( Functor functor ){ bool empty() const { return m_faceInstances.empty(); } + FaceInstance& last() const { return m_faceInstances.back(); } @@ -2376,6 +2460,7 @@ inline VertexSelection::iterator VertexSelection_insert( VertexSelection& self, } return i; } + inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){ VertexSelection::iterator i = VertexSelection_find( self, value ); if ( i != self.end() ) { @@ -2386,10 +2471,12 @@ inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){ inline bool triangle_reversed( std::size_t x, std::size_t y, std::size_t z ){ return !( ( x < y && y < z ) || ( z < x && x < y ) || ( y < z && z < x ) ); } + template inline Vector3 triangle_cross( const BasicVector3& x, const BasicVector3 y, const BasicVector3& z ){ return vector3_cross( y - x, z - x ); } + template inline bool triangles_same_winding( const BasicVector3& x1, const BasicVector3 y1, const BasicVector3& z1, const BasicVector3& x2, const BasicVector3 y2, const BasicVector3& z2 ){ return vector3_dot( triangle_cross( x1, y1, z1 ), triangle_cross( x2, y2, z2 ) ) > 0; @@ -2407,13 +2494,17 @@ public: void addLight( const RendererLight& light ){ m_lights.push_back( &light ); } + void clear(){ m_lights.clear(); } + void evaluateLights() const { } + void lightsChanged() const { } + void forEachLight( const RendererLightCallback& callback ) const { for ( Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i ) { @@ -2443,6 +2534,7 @@ FaceInstance( Face& face, const SelectionChangeCallback& observer ) : m_selectableEdges( observer ), m_selectionChanged( observer ){ } + FaceInstance( const FaceInstance& other ) : m_face( other.m_face ), m_selectable( SelectedChangedCaller( *this ) ), @@ -2450,6 +2542,7 @@ FaceInstance( const FaceInstance& other ) : m_selectableEdges( other.m_selectableEdges ), m_selectionChanged( other.m_selectionChanged ){ } + FaceInstance& operator=( const FaceInstance& other ){ m_face = other.m_face; return *this; @@ -2458,6 +2551,7 @@ FaceInstance& operator=( const FaceInstance& other ){ Face& getFace(){ return *m_face; } + const Face& getFace() const { return *m_face; } @@ -2472,14 +2566,17 @@ void selectedChanged( const Selectable& selectable ){ } m_selectionChanged( selectable ); } -typedef MemberCaller1 SelectedChangedCaller; + +typedef MemberCaller SelectedChangedCaller; bool selectedVertices() const { return !m_vertexSelection.empty(); } + bool selectedEdges() const { return !m_edgeSelection.empty(); } + bool isSelected() const { return m_selectable.isSelected(); } @@ -2487,6 +2584,7 @@ bool isSelected() const { bool selectedComponents() const { return selectedVertices() || selectedEdges() || isSelected(); } + bool selectedComponents( SelectionSystem::EComponentMode mode ) const { switch ( mode ) { @@ -2500,6 +2598,7 @@ bool selectedComponents( SelectionSystem::EComponentMode mode ) const { return false; } } + void setSelected( SelectionSystem::EComponentMode mode, bool select ){ switch ( mode ) { @@ -2533,6 +2632,7 @@ void SelectedVertices_foreach( Functor functor ) const { } } } + template void SelectedEdges_foreach( Functor functor ) const { for ( VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i ) @@ -2545,6 +2645,7 @@ void SelectedEdges_foreach( Functor functor ) const { } } } + template void SelectedFaces_foreach( Functor functor ) const { if ( isSelected() ) { @@ -2560,23 +2661,16 @@ void SelectedComponents_foreach( Functor functor ) const { } void iterate_selected( AABB& aabb ) const { - SelectedComponents_foreach( AABBExtendByPoint( aabb ) ); -} - -class RenderablePointVectorPushBack -{ -RenderablePointVector& m_points; -public: -RenderablePointVectorPushBack( RenderablePointVector& points ) : m_points( points ){ -} -void operator()( const Vector3& point ) const { - const Colour4b colour_selected( 0, 0, 255, 255 ); - m_points.push_back( pointvertex_for_windingpoint( point, colour_selected ) ); + SelectedComponents_foreach([&](const Vector3 &point) { + aabb_extend_by_point_safe(aabb, point); + }); } -}; void iterate_selected( RenderablePointVector& points ) const { - SelectedComponents_foreach( RenderablePointVectorPushBack( points ) ); + SelectedComponents_foreach([&](const Vector3 &point) { + const Colour4b colour_selected(0, 0, 255, 255); + points.push_back(pointvertex_for_windingpoint(point, colour_selected)); + }); } bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const { @@ -2599,6 +2693,7 @@ void testSelect( SelectionTest& test, SelectionIntersection& best ){ m_face->testSelect( test, best ); } } + void testSelect( Selector& selector, SelectionTest& test ){ SelectionIntersection best; testSelect( test, best ); @@ -2606,6 +2701,7 @@ void testSelect( Selector& selector, SelectionTest& test ){ Selector_add( selector, m_selectable, best ); } } + void testSelect_centroid( Selector& selector, SelectionTest& test ){ if ( m_face->contributes() && !m_face->isFiltered() ) { SelectionIntersection best; @@ -2630,6 +2726,7 @@ void selectPlane( Selector& selector, const Line& line, PlanesIterator first, Pl selectedPlaneCallback( getFace().plane3() ); } + void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlanes ){ if ( selectedPlanes.contains( plane3_flipped( getFace().plane3() ) ) ) { Selector_add( selector, m_selectable ); @@ -2697,9 +2794,11 @@ void snapComponents( float snap ){ m_face->freezeTransform(); } } + void update_move_planepts_vertex( std::size_t index ){ m_face->update_move_planepts_vertex( index, m_face->m_move_planepts ); } + void update_move_planepts_vertex2( std::size_t index, std::size_t other ){ const std::size_t numpoints = m_face->getWinding().numpoints; ASSERT_MESSAGE( index < numpoints, "select_vertex: invalid index" ); @@ -2727,6 +2826,7 @@ void update_move_planepts_vertex2( std::size_t index, std::size_t other ){ m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex; planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate } + void update_selection_vertex(){ if ( m_vertexSelection.size() == 0 ) { m_selectableVertices.setSelected( false ); @@ -2753,6 +2853,7 @@ void update_selection_vertex(){ } } } + void select_vertex( std::size_t index, bool select ){ if ( select ) { VertexSelection_insert( m_vertexSelection, getFace().getWinding()[index].adjacent ); @@ -2781,6 +2882,7 @@ void update_move_planepts_edge( std::size_t index ){ m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex; planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate } + void update_selection_edge(){ if ( m_edgeSelection.size() == 0 ) { m_selectableEdges.setSelected( false ); @@ -2798,6 +2900,7 @@ void update_selection_edge(){ } } } + void select_edge( std::size_t index, bool select ){ if ( select ) { VertexSelection_insert( m_edgeSelection, getFace().getWinding()[index].adjacent ); @@ -2838,6 +2941,7 @@ public: static void constructStatic(){ m_state = GlobalShaderCache().capture( "$CLIPPER_OVERLAY" ); } + static void destroyStatic(){ GlobalShaderCache().release( "$CLIPPER_OVERLAY" ); } @@ -2889,7 +2993,6 @@ inline void Face_addLight( const FaceInstance& face, const Matrix4& localToWorld } - typedef std::vector FaceInstances; class EdgeInstance : public Selectable @@ -2903,6 +3006,7 @@ void select_edge( bool select ){ faceVertex = next_edge( m_edge->m_faces, faceVertex ); m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select ); } + bool selected_edge() const { FaceVertexId faceVertex = m_edge->m_faceVertex; if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) { @@ -2928,6 +3032,7 @@ EdgeInstance& operator=( const EdgeInstance& other ){ void setSelected( bool select ){ select_edge( select ); } + bool isSelected() const { return selected_edge(); } @@ -2956,6 +3061,7 @@ void select_vertex( bool select ){ } while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() ); } + bool selected_vertex() const { FaceVertexId faceVertex = m_vertex->m_faceVertex; do @@ -2981,6 +3087,7 @@ VertexInstance& operator=( const VertexInstance& other ){ void setSelected( bool select ){ select_vertex( select ); } + bool isSelected() const { return selected_vertex(); } @@ -3029,6 +3136,7 @@ TypeCasts(){ InstanceIdentityCast::install( m_casts ); InstanceContainedCast::install( m_casts ); } + InstanceTypeCastTable& get(){ return m_casts; } @@ -3071,7 +3179,8 @@ typedef LazyStatic StaticTypeCasts; void lightsChanged(){ m_lightList->lightsChanged(); } -typedef MemberCaller LightsChangedCaller; + +typedef MemberCaller LightsChangedCaller; STRING_CONSTANT( Name, "BrushInstance" ); @@ -3092,10 +3201,11 @@ BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush ) Instance::setTransformChangedCallback( LightsChangedCaller( *this ) ); } + ~BrushInstance(){ - Instance::setTransformChangedCallback( Callback() ); + Instance::setTransformChangedCallback( Callback() ); - m_brush.m_lightsChanged = Callback(); + m_brush.m_lightsChanged = Callback(); GlobalShaderCache().detach( *this ); m_counter->decrement(); @@ -3113,9 +3223,11 @@ const Brush& getBrush() const { Bounded& get( NullType){ return m_brush; } + Cullable& get( NullType){ return m_brush; } + Transformable& get( NullType){ return m_transform; } @@ -3126,13 +3238,13 @@ void selectedChanged( const Selectable& selectable ){ Instance::selectedChanged(); } -typedef MemberCaller1 SelectedChangedCaller; +typedef MemberCaller SelectedChangedCaller; void selectedChangedComponent( const Selectable& selectable ){ GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable ); GlobalSelectionSystem().onComponentSelection( *this, selectable ); } -typedef MemberCaller1 SelectedChangedComponentCaller; +typedef MemberCaller SelectedChangedComponentCaller; const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& visitor ){ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) @@ -3145,6 +3257,7 @@ const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& vis static void constructStatic(){ m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" ); } + static void destroyStatic(){ GlobalShaderCache().release( "$SELPOINT" ); } @@ -3152,6 +3265,7 @@ static void destroyStatic(){ void clear(){ m_faceInstances.clear(); } + void reserve( std::size_t size ){ m_faceInstances.reserve( size ); } @@ -3159,14 +3273,17 @@ void reserve( std::size_t size ){ void push_back( Face& face ){ m_faceInstances.push_back( FaceInstance( face, SelectedChangedComponentCaller( *this ) ) ); } + void pop_back(){ ASSERT_MESSAGE( !m_faceInstances.empty(), "erasing invalid element" ); m_faceInstances.pop_back(); } + void erase( std::size_t index ){ ASSERT_MESSAGE( index < m_faceInstances.size(), "erasing invalid element" ); m_faceInstances.erase( m_faceInstances.begin() + index ); } + void connectivityChanged(){ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { @@ -3177,6 +3294,7 @@ void connectivityChanged(){ void edge_clear(){ m_edgeInstances.clear(); } + void edge_push_back( SelectableEdge& edge ){ m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) ); } @@ -3184,6 +3302,7 @@ void edge_push_back( SelectableEdge& edge ){ void vertex_clear(){ m_vertexInstances.clear(); } + void vertex_push_back( SelectableVertex& vertex ){ m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) ); } @@ -3195,6 +3314,7 @@ void DEBUG_verify() const { bool isSelected() const { return m_selectable.isSelected(); } + void setSelected( bool select ){ m_selectable.setSelected( select ); } @@ -3346,12 +3466,14 @@ bool isSelectedComponents() const { } return false; } + void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { ( *i ).setSelected( mode, select ); } } + void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){ test.BeginMesh( localToWorld() ); @@ -3411,6 +3533,7 @@ void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), brushPlanes, j, selectedPlaneCallback ); } } + void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ){ for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { @@ -3425,6 +3548,7 @@ void transformComponents( const Matrix4& matrix ){ ( *i ).transformComponents( matrix ); } } + const AABB& getSelectedComponentsBounds() const { m_aabb_component = AABB(); @@ -3442,6 +3566,7 @@ void snapComponents( float snap ){ ( *i ).snapComponents( snap ); } } + void evaluateTransform(){ Matrix4 matrix( m_transform.calculateTransform() ); //globalOutputStream() << "matrix: " << matrix << "\n"; @@ -3454,12 +3579,14 @@ void evaluateTransform(){ transformComponents( matrix ); } } + void applyTransform(){ m_brush.revertTransform(); evaluateTransform(); m_brush.freezeTransform(); } -typedef MemberCaller ApplyTransformCaller; + +typedef MemberCaller ApplyTransformCaller; void setClipPlane( const Plane3& plane ){ m_clipPlane.setPlane( m_brush, plane ); @@ -3468,6 +3595,7 @@ void setClipPlane( const Plane3& plane ){ bool testLight( const RendererLight& light ) const { return light.testAABB( worldAABB() ); } + void insertLight( const RendererLight& light ){ const Matrix4& localToWorld = Instance::localToWorld(); for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) @@ -3475,6 +3603,7 @@ void insertLight( const RendererLight& light ){ Face_addLight( *i, localToWorld, light ); } } + void clearLights(){ for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i ) { @@ -3495,6 +3624,7 @@ const Functor& m_functor; public: BrushSelectedVisitor( const Functor& functor ) : m_functor( functor ){ } + void visit( scene::Instance& instance ) const { BrushInstance* brush = Instance_getBrush( instance ); if ( brush != 0 ) { @@ -3516,6 +3646,7 @@ const Functor& m_functor; public: BrushVisibleSelectedVisitor( const Functor& functor ) : m_functor( functor ){ } + void visit( scene::Instance& instance ) const { BrushInstance* brush = Instance_getBrush( instance ); if ( brush != 0 @@ -3537,6 +3668,7 @@ const BrushInstanceVisitor& m_visitor; public: BrushForEachFace( const BrushInstanceVisitor& visitor ) : m_visitor( visitor ){ } + void operator()( BrushInstance& brush ) const { brush.forEachFaceInstance( m_visitor ); } @@ -3550,6 +3682,7 @@ public: FaceInstanceVisitFace( const Functor& functor ) : functor( functor ){ } + void visit( FaceInstance& face ) const { functor( face.getFace() ); } @@ -3569,6 +3702,7 @@ public: FaceVisitAll( const Functor& functor ) : functor( functor ){ } + void visit( Face& face ) const { functor( face ); } @@ -3594,6 +3728,7 @@ public: FaceInstanceVisitAll( const Functor& functor ) : functor( functor ){ } + void visit( FaceInstance& face ) const { functor( face ); } @@ -3617,6 +3752,7 @@ class InstanceIfVisible : public Functor public: InstanceIfVisible( const Functor& functor ) : Functor( functor ){ } + void operator()( scene::Instance& instance ){ if ( instance.path().top().get().visible() ) { Functor::operator()( instance ); @@ -3631,6 +3767,7 @@ const Functor& m_functor; public: BrushVisibleWalker( const Functor& functor ) : m_functor( functor ){ } + bool pre( const scene::Path& path, scene::Instance& instance ) const { if ( path.top().get().visible() ) { BrushInstance* brush = Instance_getBrush( instance );