]> de.git.xonotic.org Git - xonotic/netradiant.git/blob - radiant/brush.h
Q3map2:
[xonotic/netradiant.git] / radiant / brush.h
1 /*
2    Copyright (C) 1999-2006 Id Software, Inc. and contributors.
3    For a list of contributors, see the accompanying CONTRIBUTORS file.
4
5    This file is part of GtkRadiant.
6
7    GtkRadiant is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    GtkRadiant is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GtkRadiant; if not, write to the Free Software
19    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  */
21
22 #if !defined( INCLUDED_BRUSH_H )
23 #define INCLUDED_BRUSH_H
24
25 /// \file
26 /// \brief The brush primitive.
27 ///
28 /// A collection of planes that define a convex polyhedron.
29 /// The Boundary-Representation of this primitive is a manifold polygonal mesh.
30 /// Each face polygon is represented by a list of vertices in a \c Winding.
31 /// Each vertex is associated with another face that is adjacent to the edge
32 /// formed by itself and the next vertex in the winding. This information can
33 /// be used to find edge-pairs and vertex-rings.
34
35
36 #include "debugging/debugging.h"
37
38 #include "itexdef.h"
39 #include "iundo.h"
40 #include "iselection.h"
41 #include "irender.h"
42 #include "imap.h"
43 #include "ibrush.h"
44 #include "igl.h"
45 #include "ifilter.h"
46 #include "nameable.h"
47 #include "moduleobserver.h"
48
49 #include <set>
50
51 #include "cullable.h"
52 #include "renderable.h"
53 #include "selectable.h"
54 #include "editable.h"
55 #include "mapfile.h"
56
57 #include "math/frustum.h"
58 #include "selectionlib.h"
59 #include "render.h"
60 #include "texturelib.h"
61 #include "container/container.h"
62 #include "generic/bitfield.h"
63 #include "signal/signalfwd.h"
64
65 #include "winding.h"
66 #include "brush_primit.h"
67
68 const unsigned int BRUSH_DETAIL_FLAG = 27;
69 const unsigned int BRUSH_DETAIL_MASK = ( 1 << BRUSH_DETAIL_FLAG );
70
71 enum EBrushType
72 {
73         eBrushTypeQuake,
74         eBrushTypeQuake2,
75         eBrushTypeQuake3,
76         eBrushTypeQuake3BP,
77         eBrushTypeDoom3,
78         eBrushTypeQuake4,
79         eBrushTypeHalfLife,
80 };
81
82
83 #define BRUSH_CONNECTIVITY_DEBUG 0
84 #define BRUSH_DEGENERATE_DEBUG 0
85
86 template<typename TextOuputStreamType>
87 inline TextOuputStreamType& ostream_write( TextOuputStreamType& ostream, const Matrix4& m ){
88         return ostream << "(" << m[0] << " " << m[1] << " " << m[2] << " " << m[3] << ", "
89                                    << m[4] << " " << m[5] << " " << m[6] << " " << m[7] << ", "
90                                    << m[8] << " " << m[9] << " " << m[10] << " " << m[11] << ", "
91                                    << m[12] << " " << m[13] << " " << m[14] << " " << m[15] << ")";
92 }
93
94 inline void print_vector3( const Vector3& v ){
95         globalOutputStream() << "( " << v.x() << " " << v.y() << " " << v.z() << " )\n";
96 }
97
98 inline void print_3x3( const Matrix4& m ){
99         globalOutputStream() << "( " << m.xx() << " " << m.xy() << " " << m.xz() << " ) "
100                                                  << "( " << m.yx() << " " << m.yy() << " " << m.yz() << " ) "
101                                                  << "( " << m.zx() << " " << m.zy() << " " << m.zz() << " )\n";
102 }
103
104
105
106 inline bool texdef_sane( const texdef_t& texdef ){
107         return fabs( texdef.shift[0] ) < ( 1 << 16 )
108                    && fabs( texdef.shift[1] ) < ( 1 << 16 );
109 }
110
111 inline void Winding_DrawWireframe( const Winding& winding ){
112         glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex );
113         glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) );
114 }
115
116 inline void Winding_Draw( const Winding& winding, const Vector3& normal, RenderStateFlags state ){
117         glVertexPointer( 3, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->vertex );
118
119         if ( ( state & RENDER_BUMP ) != 0 ) {
120                 Vector3 normals[c_brush_maxFaces];
121                 typedef Vector3* Vector3Iter;
122                 for ( Vector3Iter i = normals, end = normals + winding.numpoints; i != end; ++i )
123                 {
124                         *i = normal;
125                 }
126                 if ( GlobalShaderCache().useShaderLanguage() ) {
127                         glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals );
128                         glVertexAttribPointerARB( c_attr_TexCoord0, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord );
129                         glVertexAttribPointerARB( c_attr_Tangent, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent );
130                         glVertexAttribPointerARB( c_attr_Binormal, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent );
131                 }
132                 else
133                 {
134                         glVertexAttribPointerARB( 11, 3, GL_FLOAT, 0, sizeof( Vector3 ), normals );
135                         glVertexAttribPointerARB( 8, 2, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->texcoord );
136                         glVertexAttribPointerARB( 9, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->tangent );
137                         glVertexAttribPointerARB( 10, 3, GL_FLOAT, 0, sizeof( WindingVertex ), &winding.points.data()->bitangent );
138                 }
139         }
140         else
141         {
142                 if ( state & RENDER_LIGHTING ) {
143                         Vector3 normals[c_brush_maxFaces];
144                         typedef Vector3* Vector3Iter;
145                         for ( Vector3Iter i = normals, last = normals + winding.numpoints; i != last; ++i )
146                         {
147                                 *i = normal;
148                         }
149                         glNormalPointer( GL_FLOAT, sizeof( Vector3 ), normals );
150                 }
151
152                 if ( state & RENDER_TEXTURE ) {
153                         glTexCoordPointer( 2, GL_FLOAT, sizeof( WindingVertex ), &winding.points.data()->texcoord );
154                 }
155         }
156 #if 0
157         if ( state & RENDER_FILL ) {
158                 glDrawArrays( GL_TRIANGLE_FAN, 0, GLsizei( winding.numpoints ) );
159         }
160         else
161         {
162                 glDrawArrays( GL_LINE_LOOP, 0, GLsizei( winding.numpoints ) );
163         }
164 #else
165         glDrawArrays( GL_POLYGON, 0, GLsizei( winding.numpoints ) );
166 #endif
167
168 #if 0
169         const Winding& winding = winding;
170
171         if ( state & RENDER_FILL ) {
172                 glBegin( GL_POLYGON );
173         }
174         else
175         {
176                 glBegin( GL_LINE_LOOP );
177         }
178
179         if ( state & RENDER_LIGHTING ) {
180                 glNormal3fv( normal );
181         }
182
183         for ( int i = 0; i < winding.numpoints; ++i )
184         {
185                 if ( state & RENDER_TEXTURE ) {
186                         glTexCoord2fv( &winding.points[i][3] );
187                 }
188                 glVertex3fv( winding.points[i] );
189         }
190         glEnd();
191 #endif
192 }
193
194
195 #include "shaderlib.h"
196
197 typedef DoubleVector3 PlanePoints[3];
198
199 inline bool planepts_equal( const PlanePoints planepts, const PlanePoints other ){
200         return planepts[0] == other[0] && planepts[1] == other[1] && planepts[2] == other[2];
201 }
202
203 inline void planepts_assign( PlanePoints planepts, const PlanePoints other ){
204         planepts[0] = other[0];
205         planepts[1] = other[1];
206         planepts[2] = other[2];
207 }
208
209 inline void planepts_quantise( PlanePoints planepts, double snap ){
210         vector3_snap( planepts[0], snap );
211         vector3_snap( planepts[1], snap );
212         vector3_snap( planepts[2], snap );
213 }
214
215 inline float vector3_max_component( const Vector3& vec3 ){
216         return std::max( fabsf( vec3[0] ), std::max( fabsf( vec3[1] ), fabsf( vec3[2] ) ) );
217 }
218
219 inline void edge_snap( Vector3& edge, double snap ){
220         float scale = static_cast<float>( ceil( fabs( snap / vector3_max_component( edge ) ) ) );
221         if ( scale > 0.0f ) {
222                 vector3_scale( edge, scale );
223         }
224         vector3_snap( edge, snap );
225 }
226
227 inline void planepts_snap( PlanePoints planepts, double snap ){
228         Vector3 edge01( vector3_subtracted( planepts[1], planepts[0] ) );
229         Vector3 edge12( vector3_subtracted( planepts[2], planepts[1] ) );
230         Vector3 edge20( vector3_subtracted( planepts[0], planepts[2] ) );
231
232         double length_squared_01 = vector3_dot( edge01, edge01 );
233         double length_squared_12 = vector3_dot( edge12, edge12 );
234         double length_squared_20 = vector3_dot( edge20, edge20 );
235
236         vector3_snap( planepts[0], snap );
237
238         if ( length_squared_01 < length_squared_12 ) {
239                 if ( length_squared_12 < length_squared_20 ) {
240                         edge_snap( edge01, snap );
241                         edge_snap( edge12, snap );
242                         planepts[1] = vector3_added( planepts[0], edge01 );
243                         planepts[2] = vector3_added( planepts[1], edge12 );
244                 }
245                 else
246                 {
247                         edge_snap( edge20, snap );
248                         edge_snap( edge01, snap );
249                         planepts[1] = vector3_added( planepts[0], edge20 );
250                         planepts[2] = vector3_added( planepts[1], edge01 );
251                 }
252         }
253         else
254         {
255                 if ( length_squared_01 < length_squared_20 ) {
256                         edge_snap( edge01, snap );
257                         edge_snap( edge12, snap );
258                         planepts[1] = vector3_added( planepts[0], edge01 );
259                         planepts[2] = vector3_added( planepts[1], edge12 );
260                 }
261                 else
262                 {
263                         edge_snap( edge12, snap );
264                         edge_snap( edge20, snap );
265                         planepts[1] = vector3_added( planepts[0], edge12 );
266                         planepts[2] = vector3_added( planepts[1], edge20 );
267                 }
268         }
269 }
270
271 inline PointVertex pointvertex_for_planept( const DoubleVector3& point, const Colour4b& colour ){
272         return PointVertex(
273                            Vertex3f(
274                                    static_cast<float>( point.x() ),
275                                    static_cast<float>( point.y() ),
276                                    static_cast<float>( point.z() )
277                                    ),
278                            colour
279                            );
280 }
281
282 inline PointVertex pointvertex_for_windingpoint( const Vector3& point, const Colour4b& colour ){
283         return PointVertex(
284                            vertex3f_for_vector3( point ),
285                            colour
286                            );
287 }
288
289 inline bool check_plane_is_integer( const PlanePoints& planePoints ){
290         return !float_is_integer( planePoints[0][0] )
291                    || !float_is_integer( planePoints[0][1] )
292                    || !float_is_integer( planePoints[0][2] )
293                    || !float_is_integer( planePoints[1][0] )
294                    || !float_is_integer( planePoints[1][1] )
295                    || !float_is_integer( planePoints[1][2] )
296                    || !float_is_integer( planePoints[2][0] )
297                    || !float_is_integer( planePoints[2][1] )
298                    || !float_is_integer( planePoints[2][2] );
299 }
300
301 inline void brush_check_shader( const char* name ){
302         if ( !shader_valid( name ) ) {
303                 globalErrorStream() << "brush face has invalid texture name: '" << name << "'\n";
304         }
305 }
306
307 class FaceShaderObserver
308 {
309 public:
310 virtual void realiseShader() = 0;
311 virtual void unrealiseShader() = 0;
312 };
313
314 class FaceShaderObserverRealise
315 {
316 public:
317 void operator()( FaceShaderObserver& observer ) const {
318         observer.realiseShader();
319 }
320 };
321
322 class FaceShaderObserverUnrealise
323 {
324 public:
325 void operator()( FaceShaderObserver& observer ) const {
326         observer.unrealiseShader();
327 }
328 };
329
330 typedef ReferencePair<FaceShaderObserver> FaceShaderObserverPair;
331
332
333 class ContentsFlagsValue
334 {
335 public:
336 ContentsFlagsValue(){
337 }
338 ContentsFlagsValue( int surfaceFlags, int contentFlags, int value, bool specified ) :
339         m_surfaceFlags( surfaceFlags ),
340         m_contentFlags( contentFlags ),
341         m_value( value ),
342         m_specified( specified ){
343 }
344 int m_surfaceFlags;
345 int m_contentFlags;
346 int m_value;
347 bool m_specified;
348 };
349
350 inline void ContentsFlagsValue_assignMasked( ContentsFlagsValue& flags, const ContentsFlagsValue& other ){
351         bool detail = bitfield_enabled( flags.m_contentFlags, BRUSH_DETAIL_MASK );
352         flags = other;
353         if ( detail ) {
354                 flags.m_contentFlags = bitfield_enable( flags.m_contentFlags, BRUSH_DETAIL_MASK );
355         }
356         else
357         {
358                 flags.m_contentFlags = bitfield_disable( flags.m_contentFlags, BRUSH_DETAIL_MASK );
359         }
360 }
361
362
363 class FaceShader : public ModuleObserver
364 {
365 public:
366 class SavedState
367 {
368 public:
369 CopiedString m_shader;
370 ContentsFlagsValue m_flags;
371
372 SavedState( const FaceShader& faceShader ){
373         m_shader = faceShader.getShader();
374         m_flags = faceShader.m_flags;
375 }
376
377 void exportState( FaceShader& faceShader ) const {
378         faceShader.setShader( m_shader.c_str() );
379         //faceShader.setFlags( m_flags );
380         faceShader.m_flags = m_flags;
381 }
382 };
383
384 CopiedString m_shader;
385 Shader* m_state;
386 ContentsFlagsValue m_flags;
387 FaceShaderObserverPair m_observers;
388 bool m_instanced;
389 bool m_realised;
390
391 FaceShader( const char* shader, const ContentsFlagsValue& flags = ContentsFlagsValue( 0, 0, 0, false ) ) :
392         m_shader( shader ),
393         m_state( 0 ),
394         m_flags( flags ),
395         m_instanced( false ),
396         m_realised( false ){
397         captureShader();
398 }
399 ~FaceShader(){
400         releaseShader();
401 }
402 // copy-construction not supported
403 FaceShader( const FaceShader& other );
404
405 void instanceAttach(){
406         m_instanced = true;
407         m_state->incrementUsed();
408 }
409 void instanceDetach(){
410         m_state->decrementUsed();
411         m_instanced = false;
412 }
413
414 void captureShader(){
415         ASSERT_MESSAGE( m_state == 0, "shader cannot be captured" );
416         brush_check_shader( m_shader.c_str() );
417         m_state = GlobalShaderCache().capture( m_shader.c_str() );
418         m_state->attach( *this );
419 }
420 void releaseShader(){
421         ASSERT_MESSAGE( m_state != 0, "shader cannot be released" );
422         m_state->detach( *this );
423         GlobalShaderCache().release( m_shader.c_str() );
424         m_state = 0;
425 }
426
427 void realise(){
428         ASSERT_MESSAGE( !m_realised, "FaceTexdef::realise: already realised" );
429         m_realised = true;
430         m_observers.forEach( FaceShaderObserverRealise() );
431 }
432 void unrealise(){
433         ASSERT_MESSAGE( m_realised, "FaceTexdef::unrealise: already unrealised" );
434         m_observers.forEach( FaceShaderObserverUnrealise() );
435         m_realised = false;
436 }
437
438 void attach( FaceShaderObserver& observer ){
439         m_observers.attach( observer );
440         if ( m_realised ) {
441                 observer.realiseShader();
442         }
443 }
444
445 void detach( FaceShaderObserver& observer ){
446         if ( m_realised ) {
447                 observer.unrealiseShader();
448         }
449         m_observers.detach( observer );
450 }
451
452 const char* getShader() const {
453         return m_shader.c_str();
454 }
455 void setShader( const char* name ){
456         if ( m_instanced ) {
457                 m_state->decrementUsed();
458         }
459         releaseShader();
460         m_shader = name;
461         captureShader();
462         if ( m_instanced ) {
463                 m_state->incrementUsed();
464         }
465 }
466 ContentsFlagsValue getFlags() const {
467         ASSERT_MESSAGE( m_realised, "FaceShader::getFlags: flags not valid when unrealised" );
468         if ( !m_flags.m_specified ) {
469                 return ContentsFlagsValue(
470                                    m_state->getTexture().surfaceFlags,
471                                    m_state->getTexture().contentFlags,
472                                    m_state->getTexture().value,
473                                    true
474                                    );
475         }
476         return m_flags;
477 }
478 void setFlags( const ContentsFlagsValue& flags ){
479         ASSERT_MESSAGE( m_realised, "FaceShader::setFlags: flags not valid when unrealised" );
480         ContentsFlagsValue_assignMasked( m_flags, flags );
481 }
482
483 Shader* state() const {
484         return m_state;
485 }
486
487 std::size_t width() const {
488         if ( m_realised ) {
489                 return m_state->getTexture().width;
490         }
491         return 1;
492 }
493 std::size_t height() const {
494         if ( m_realised ) {
495                 return m_state->getTexture().height;
496         }
497         return 1;
498 }
499 unsigned int shaderFlags() const {
500         if ( m_realised ) {
501                 return m_state->getFlags();
502         }
503         return 0;
504 }
505 };
506
507
508
509
510 class FaceTexdef : public FaceShaderObserver
511 {
512 // not copyable
513 FaceTexdef( const FaceTexdef& other );
514 // not assignable
515 FaceTexdef& operator=( const FaceTexdef& other );
516 public:
517 class SavedState
518 {
519 public:
520 TextureProjection m_projection;
521
522 SavedState( const FaceTexdef& faceTexdef ){
523         m_projection = faceTexdef.m_projection;
524 }
525
526 void exportState( FaceTexdef& faceTexdef ) const {
527         Texdef_Assign( faceTexdef.m_projection, m_projection );
528 }
529 };
530
531 FaceShader& m_shader;
532 TextureProjection m_projection;
533 bool m_projectionInitialised;
534 bool m_scaleApplied;
535
536 FaceTexdef(
537         FaceShader& shader,
538         const TextureProjection& projection,
539         bool projectionInitialised = true
540         ) :
541         m_shader( shader ),
542         m_projection( projection ),
543         m_projectionInitialised( projectionInitialised ),
544         m_scaleApplied( false ){
545         m_shader.attach( *this );
546 }
547 ~FaceTexdef(){
548         m_shader.detach( *this );
549 }
550
551 void addScale(){
552         ASSERT_MESSAGE( !m_scaleApplied, "texture scale aready added" );
553         m_scaleApplied = true;
554         m_projection.m_brushprimit_texdef.addScale( m_shader.width(), m_shader.height() );
555 }
556 void removeScale(){
557         ASSERT_MESSAGE( m_scaleApplied, "texture scale aready removed" );
558         m_scaleApplied = false;
559         m_projection.m_brushprimit_texdef.removeScale( m_shader.width(), m_shader.height() );
560 }
561
562 void realiseShader(){
563         if ( m_projectionInitialised && !m_scaleApplied ) {
564                 addScale();
565         }
566 }
567 void unrealiseShader(){
568         if ( m_projectionInitialised && m_scaleApplied ) {
569                 removeScale();
570         }
571 }
572
573 void setTexdef( const TextureProjection& projection ){
574         removeScale();
575         Texdef_Assign( m_projection, projection );
576         addScale();
577 }
578
579 void shift( float s, float t ){
580         ASSERT_MESSAGE( texdef_sane( m_projection.m_texdef ), "FaceTexdef::shift: bad texdef" );
581         removeScale();
582         Texdef_Shift( m_projection, s, t );
583         addScale();
584 }
585
586 void scale( float s, float t ){
587         removeScale();
588         Texdef_Scale( m_projection, s, t );
589         addScale();
590 }
591
592 void rotate( float angle ){
593         removeScale();
594         Texdef_Rotate( m_projection, angle );
595         addScale();
596 }
597
598 void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){
599         Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat );
600 }
601
602 void emitTextureCoordinates( Winding& winding, const Vector3& normal, const Matrix4& localToWorld ){
603         Texdef_EmitTextureCoordinates( m_projection, m_shader.width(), m_shader.height(), winding, normal, localToWorld );
604 }
605
606 void transform( const Plane3& plane, const Matrix4& matrix ){
607         removeScale();
608         Texdef_transformLocked( m_projection, m_shader.width(), m_shader.height(), plane, matrix );
609         addScale();
610 }
611
612 TextureProjection normalised() const {
613         brushprimit_texdef_t tmp( m_projection.m_brushprimit_texdef );
614         tmp.removeScale( m_shader.width(), m_shader.height() );
615         return TextureProjection( m_projection.m_texdef, tmp, m_projection.m_basis_s, m_projection.m_basis_t );
616 }
617 void setBasis( const Vector3& normal ){
618         Matrix4 basis;
619         Normal_GetTransform( normal, basis );
620         m_projection.m_basis_s = Vector3( basis.xx(), basis.yx(), basis.zx() );
621         m_projection.m_basis_t = Vector3( -basis.xy(), -basis.yy(), -basis.zy() );
622 }
623 };
624
625 inline void planepts_print( const PlanePoints& planePoints, TextOutputStream& ostream ){
626         ostream << "( " << planePoints[0][0] << " " << planePoints[0][1] << " " << planePoints[0][2] << " ) "
627                         << "( " << planePoints[1][0] << " " << planePoints[1][1] << " " << planePoints[1][2] << " ) "
628                         << "( " << planePoints[2][0] << " " << planePoints[2][1] << " " << planePoints[2][2] << " )";
629 }
630
631
632 inline Plane3 Plane3_applyTranslation( const Plane3& plane, const Vector3& translation ){
633         Plane3 tmp( plane3_translated( Plane3( plane.normal(), -plane.dist() ), translation ) );
634         return Plane3( tmp.normal(), -tmp.dist() );
635 }
636
637 inline Plane3 Plane3_applyTransform( const Plane3& plane, const Matrix4& matrix ){
638         Plane3 tmp( plane3_transformed( Plane3( plane.normal(), -plane.dist() ), matrix ) );
639         return Plane3( tmp.normal(), -tmp.dist() );
640 }
641
642 class FacePlane
643 {
644 PlanePoints m_planepts;
645 Plane3 m_planeCached;
646 Plane3 m_plane;
647 public:
648 Vector3 m_funcStaticOrigin;
649
650 static EBrushType m_type;
651
652 static bool isDoom3Plane(){
653         return FacePlane::m_type == eBrushTypeDoom3 || FacePlane::m_type == eBrushTypeQuake4;
654 }
655
656 class SavedState
657 {
658 public:
659 PlanePoints m_planepts;
660 Plane3 m_plane;
661
662 SavedState( const FacePlane& facePlane ){
663         if ( facePlane.isDoom3Plane() ) {
664                 m_plane = facePlane.m_plane;
665         }
666         else
667         {
668                 planepts_assign( m_planepts, facePlane.planePoints() );
669         }
670 }
671
672 void exportState( FacePlane& facePlane ) const {
673         if ( facePlane.isDoom3Plane() ) {
674                 facePlane.m_plane = m_plane;
675                 facePlane.updateTranslated();
676         }
677         else
678         {
679                 planepts_assign( facePlane.planePoints(), m_planepts );
680                 facePlane.MakePlane();
681         }
682 }
683 };
684
685 FacePlane() : m_funcStaticOrigin( 0, 0, 0 ){
686 }
687 FacePlane( const FacePlane& other ) : m_funcStaticOrigin( 0, 0, 0 ){
688         if ( !isDoom3Plane() ) {
689                 planepts_assign( m_planepts, other.m_planepts );
690                 MakePlane();
691         }
692         else
693         {
694                 m_plane = other.m_plane;
695                 updateTranslated();
696         }
697 }
698
699 void MakePlane(){
700         if ( !isDoom3Plane() ) {
701 #if 0
702                 if ( check_plane_is_integer( m_planepts ) ) {
703                         globalErrorStream() << "non-integer planepts: ";
704                         planepts_print( m_planepts, globalErrorStream() );
705                         globalErrorStream() << "\n";
706                 }
707 #endif
708                 m_planeCached = plane3_for_points( m_planepts );
709         }
710 }
711
712 void reverse(){
713         if ( !isDoom3Plane() ) {
714                 vector3_swap( m_planepts[0], m_planepts[2] );
715                 MakePlane();
716         }
717         else
718         {
719                 m_planeCached = plane3_flipped( m_plane );
720                 updateSource();
721         }
722 }
723 void transform( const Matrix4& matrix, bool mirror ){
724         if ( !isDoom3Plane() ) {
725
726 #if 0
727                 bool off = check_plane_is_integer( planePoints() );
728 #endif
729
730                 matrix4_transform_point( matrix, m_planepts[0] );
731                 matrix4_transform_point( matrix, m_planepts[1] );
732                 matrix4_transform_point( matrix, m_planepts[2] );
733
734                 if ( mirror ) {
735                         reverse();
736                 }
737
738 #if 0
739                 if ( check_plane_is_integer( planePoints() ) ) {
740                         if ( !off ) {
741                                 globalErrorStream() << "caused by transform\n";
742                         }
743                 }
744 #endif
745                 MakePlane();
746         }
747         else
748         {
749                 m_planeCached = Plane3_applyTransform( m_planeCached, matrix );
750                 updateSource();
751         }
752 }
753 void offset( float offset ){
754         if ( !isDoom3Plane() ) {
755                 Vector3 move( vector3_scaled( m_planeCached.normal(), -offset ) );
756
757                 vector3_subtract( m_planepts[0], move );
758                 vector3_subtract( m_planepts[1], move );
759                 vector3_subtract( m_planepts[2], move );
760
761                 MakePlane();
762         }
763         else
764         {
765                 m_planeCached.d += offset;
766                 updateSource();
767         }
768 }
769
770 void updateTranslated(){
771         m_planeCached = Plane3_applyTranslation( m_plane, m_funcStaticOrigin );
772 }
773 void updateSource(){
774         m_plane = Plane3_applyTranslation( m_planeCached, vector3_negated( m_funcStaticOrigin ) );
775 }
776
777
778 PlanePoints& planePoints(){
779         return m_planepts;
780 }
781 const PlanePoints& planePoints() const {
782         return m_planepts;
783 }
784 const Plane3& plane3() const {
785         return m_planeCached;
786 }
787 void setDoom3Plane( const Plane3& plane ){
788         m_plane = plane;
789         updateTranslated();
790 }
791 const Plane3& getDoom3Plane() const {
792         return m_plane;
793 }
794
795 void copy( const FacePlane& other ){
796         if ( !isDoom3Plane() ) {
797                 planepts_assign( m_planepts, other.m_planepts );
798                 MakePlane();
799         }
800         else
801         {
802                 m_planeCached = other.m_plane;
803                 updateSource();
804         }
805 }
806 void copy( const Vector3& p0, const Vector3& p1, const Vector3& p2 ){
807         if ( !isDoom3Plane() ) {
808                 m_planepts[0] = p0;
809                 m_planepts[1] = p1;
810                 m_planepts[2] = p2;
811                 MakePlane();
812         }
813         else
814         {
815                 m_planeCached = plane3_for_points( p2, p1, p0 );
816                 updateSource();
817         }
818 }
819 };
820
821 inline void Winding_testSelect( Winding& winding, SelectionTest& test, SelectionIntersection& best ){
822         test.TestPolygon( VertexPointer( reinterpret_cast<VertexPointer::pointer>( &winding.points.data()->vertex ), sizeof( WindingVertex ) ), winding.numpoints, best );
823 }
824
825 const double GRID_MIN = 0.125;
826
827 inline double quantiseInteger( double f ){
828         return float_to_integer( f );
829 }
830
831 inline double quantiseFloating( double f ){
832         return float_snapped( f, 1.f / ( 1 << 16 ) );
833 }
834
835 typedef double ( *QuantiseFunc )( double f );
836
837 class Face;
838
839 class FaceFilter
840 {
841 public:
842 virtual bool filter( const Face& face ) const = 0;
843 };
844
845 bool face_filtered( Face& face );
846 void add_face_filter( FaceFilter& filter, int mask, bool invert = false );
847
848 void Brush_addTextureChangedCallback( const SignalHandler& callback );
849 void Brush_textureChanged();
850
851
852 extern bool g_brush_texturelock_enabled;
853
854 class FaceObserver
855 {
856 public:
857 virtual void planeChanged() = 0;
858 virtual void connectivityChanged() = 0;
859 virtual void shaderChanged() = 0;
860 virtual void evaluateTransform() = 0;
861 };
862
863 class Face :
864         public OpenGLRenderable,
865         public Filterable,
866         public Undoable,
867         public FaceShaderObserver
868 {
869 std::size_t m_refcount;
870
871 class SavedState : public UndoMemento
872 {
873 public:
874 FacePlane::SavedState m_planeState;
875 FaceTexdef::SavedState m_texdefState;
876 FaceShader::SavedState m_shaderState;
877
878 SavedState( const Face& face ) : m_planeState( face.getPlane() ), m_texdefState( face.getTexdef() ), m_shaderState( face.getShader() ){
879 }
880
881 void exportState( Face& face ) const {
882         m_planeState.exportState( face.getPlane() );
883         m_shaderState.exportState( face.getShader() );
884         m_texdefState.exportState( face.getTexdef() );
885 }
886
887 void release(){
888         delete this;
889 }
890 };
891
892 public:
893 static QuantiseFunc m_quantise;
894 static EBrushType m_type;
895
896 PlanePoints m_move_planepts;
897 PlanePoints m_move_planeptsTransformed;
898 private:
899 FacePlane m_plane;
900 FacePlane m_planeTransformed;
901 FaceShader m_shader;
902 FaceTexdef m_texdef;
903 TextureProjection m_texdefTransformed;
904
905 Winding m_winding;
906 Vector3 m_centroid;
907 bool m_filtered;
908
909 FaceObserver* m_observer;
910 UndoObserver* m_undoable_observer;
911 MapFile* m_map;
912
913 // assignment not supported
914 Face& operator=( const Face& other );
915 // copy-construction not supported
916 Face( const Face& other );
917
918 public:
919
920 Face( FaceObserver* observer ) :
921         m_refcount( 0 ),
922         m_shader( texdef_name_default() ),
923         m_texdef( m_shader, TextureProjection(), false ),
924         m_filtered( false ),
925         m_observer( observer ),
926         m_undoable_observer( 0 ),
927         m_map( 0 ){
928         m_shader.attach( *this );
929         m_plane.copy( Vector3( 0, 0, 0 ), Vector3( 64, 0, 0 ), Vector3( 0, 64, 0 ) );
930         m_texdef.setBasis( m_plane.plane3().normal() );
931         planeChanged();
932 }
933 Face(
934         const Vector3& p0,
935         const Vector3& p1,
936         const Vector3& p2,
937         const char* shader,
938         const TextureProjection& projection,
939         FaceObserver* observer
940         ) :
941         m_refcount( 0 ),
942         m_shader( shader ),
943         m_texdef( m_shader, projection ),
944         m_observer( observer ),
945         m_undoable_observer( 0 ),
946         m_map( 0 ){
947         m_shader.attach( *this );
948         m_plane.copy( p0, p1, p2 );
949         m_texdef.setBasis( m_plane.plane3().normal() );
950         planeChanged();
951         updateFiltered();
952 }
953 Face( const Face& other, FaceObserver* observer ) :
954         m_refcount( 0 ),
955         m_shader( other.m_shader.getShader(), other.m_shader.m_flags ),
956         m_texdef( m_shader, other.getTexdef().normalised() ),
957         m_observer( observer ),
958         m_undoable_observer( 0 ),
959         m_map( 0 ){
960         m_shader.attach( *this );
961         m_plane.copy( other.m_plane );
962         planepts_assign( m_move_planepts, other.m_move_planepts );
963         m_texdef.setBasis( m_plane.plane3().normal() );
964         planeChanged();
965         updateFiltered();
966 }
967 ~Face(){
968         m_shader.detach( *this );
969 }
970
971 void planeChanged(){
972         revertTransform();
973         m_observer->planeChanged();
974 }
975
976 void realiseShader(){
977         m_observer->shaderChanged();
978 }
979 void unrealiseShader(){
980 }
981
982 void instanceAttach( MapFile* map ){
983         m_shader.instanceAttach();
984         m_map = map;
985         m_undoable_observer = GlobalUndoSystem().observer( this );
986         GlobalFilterSystem().registerFilterable( *this );
987 }
988 void instanceDetach( MapFile* map ){
989         GlobalFilterSystem().unregisterFilterable( *this );
990         m_undoable_observer = 0;
991         GlobalUndoSystem().release( this );
992         m_map = 0;
993         m_shader.instanceDetach();
994 }
995
996 void render( RenderStateFlags state ) const {
997         Winding_Draw( m_winding, m_planeTransformed.plane3().normal(), state );
998 }
999
1000 void updateFiltered(){
1001         m_filtered = face_filtered( *this );
1002 }
1003 bool isFiltered() const {
1004         return m_filtered;
1005 }
1006
1007 void undoSave(){
1008         if ( m_map != 0 ) {
1009                 m_map->changed();
1010         }
1011         if ( m_undoable_observer != 0 ) {
1012                 m_undoable_observer->save( this );
1013         }
1014 }
1015
1016 // undoable
1017 UndoMemento* exportState() const {
1018         return new SavedState( *this );
1019 }
1020 void importState( const UndoMemento* data ){
1021         undoSave();
1022
1023         static_cast<const SavedState*>( data )->exportState( *this );
1024
1025         planeChanged();
1026         m_observer->connectivityChanged();
1027         texdefChanged();
1028         m_observer->shaderChanged();
1029         updateFiltered();
1030 }
1031
1032 void IncRef(){
1033         ++m_refcount;
1034 }
1035 void DecRef(){
1036         if ( --m_refcount == 0 ) {
1037                 delete this;
1038         }
1039 }
1040
1041 void flipWinding(){
1042         m_plane.reverse();
1043         planeChanged();
1044 }
1045
1046 bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
1047         return volume.TestPlane( Plane3( plane3().normal(), -plane3().dist() ), localToWorld );
1048 }
1049
1050 void render( Renderer& renderer, const Matrix4& localToWorld ) const {
1051         renderer.SetState( m_shader.state(), Renderer::eFullMaterials );
1052         renderer.addRenderable( *this, localToWorld );
1053 }
1054
1055 void transform( const Matrix4& matrix, bool mirror ){
1056         if ( g_brush_texturelock_enabled ) {
1057                 Texdef_transformLocked( m_texdefTransformed, m_shader.width(), m_shader.height(), m_plane.plane3(), matrix );
1058         }
1059
1060         m_planeTransformed.transform( matrix, mirror );
1061
1062 #if 0
1063         ASSERT_MESSAGE( projectionaxis_for_normal( normal ) == projectionaxis_for_normal( plane3().normal() ), "bleh" );
1064 #endif
1065         m_observer->planeChanged();
1066
1067         if ( g_brush_texturelock_enabled ) {
1068                 Brush_textureChanged();
1069         }
1070 }
1071
1072 void assign_planepts( const PlanePoints planepts ){
1073         m_planeTransformed.copy( planepts[0], planepts[1], planepts[2] );
1074         m_observer->planeChanged();
1075 }
1076
1077 /// \brief Reverts the transformable state of the brush to identity.
1078 void revertTransform(){
1079         m_planeTransformed = m_plane;
1080         planepts_assign( m_move_planeptsTransformed, m_move_planepts );
1081         m_texdefTransformed = m_texdef.m_projection;
1082 }
1083 void freezeTransform(){
1084         undoSave();
1085         m_plane = m_planeTransformed;
1086         planepts_assign( m_move_planepts, m_move_planeptsTransformed );
1087         m_texdef.m_projection = m_texdefTransformed;
1088 }
1089
1090 void update_move_planepts_vertex( std::size_t index, PlanePoints planePoints ){
1091         std::size_t numpoints = getWinding().numpoints;
1092         ASSERT_MESSAGE( index < numpoints, "update_move_planepts_vertex: invalid index" );
1093
1094         std::size_t opposite = Winding_Opposite( getWinding(), index );
1095         std::size_t adjacent = Winding_wrap( getWinding(), opposite + numpoints - 1 );
1096         planePoints[0] = getWinding()[opposite].vertex;
1097         planePoints[1] = getWinding()[index].vertex;
1098         planePoints[2] = getWinding()[adjacent].vertex;
1099         // winding points are very inaccurate, so they must be quantised before using them to generate the face-plane
1100         planepts_quantise( planePoints, GRID_MIN );
1101 }
1102
1103 void snapto( float snap ){
1104         if ( contributes() ) {
1105 #if 0
1106                 ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane before snap to grid" );
1107                 planepts_snap( m_plane.planePoints(), snap );
1108                 ASSERT_MESSAGE( plane3_valid( m_plane.plane3() ), "invalid plane after snap to grid" );
1109 #else
1110                 PlanePoints planePoints;
1111                 update_move_planepts_vertex( 0, planePoints );
1112                 vector3_snap( planePoints[0], snap );
1113                 vector3_snap( planePoints[1], snap );
1114                 vector3_snap( planePoints[2], snap );
1115                 assign_planepts( planePoints );
1116                 freezeTransform();
1117 #endif
1118                 SceneChangeNotify();
1119                 if ( !plane3_valid( m_plane.plane3() ) ) {
1120                         globalErrorStream() << "WARNING: invalid plane after snap to grid\n";
1121                 }
1122         }
1123 }
1124
1125 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1126         Winding_testSelect( m_winding, test, best );
1127 }
1128
1129 void testSelect_centroid( SelectionTest& test, SelectionIntersection& best ){
1130         test.TestPoint( m_centroid, best );
1131 }
1132
1133 void shaderChanged(){
1134         EmitTextureCoordinates();
1135         Brush_textureChanged();
1136         m_observer->shaderChanged();
1137         updateFiltered();
1138         planeChanged();
1139         SceneChangeNotify();
1140 }
1141
1142 const char* GetShader() const {
1143         return m_shader.getShader();
1144 }
1145 void SetShader( const char* name ){
1146         undoSave();
1147         m_shader.setShader( name );
1148         shaderChanged();
1149 }
1150
1151 void revertTexdef(){
1152         m_texdefTransformed = m_texdef.m_projection;
1153 }
1154 void texdefChanged(){
1155         revertTexdef();
1156         EmitTextureCoordinates();
1157         Brush_textureChanged();
1158 }
1159
1160 void GetTexdef( TextureProjection& projection ) const {
1161         projection = m_texdef.normalised();
1162 }
1163 void SetTexdef( const TextureProjection& projection ){
1164         undoSave();
1165         m_texdef.setTexdef( projection );
1166         texdefChanged();
1167 }
1168
1169 void GetFlags( ContentsFlagsValue& flags ) const {
1170         flags = m_shader.getFlags();
1171 }
1172 void SetFlags( const ContentsFlagsValue& flags ){
1173         undoSave();
1174         m_shader.setFlags( flags );
1175         m_observer->shaderChanged();
1176         updateFiltered();
1177 }
1178
1179 void ShiftTexdef( float s, float t ){
1180         undoSave();
1181         m_texdef.shift( s, t );
1182         texdefChanged();
1183 }
1184
1185 void ScaleTexdef( float s, float t ){
1186         undoSave();
1187         m_texdef.scale( s, t );
1188         texdefChanged();
1189 }
1190
1191 void RotateTexdef( float angle ){
1192         undoSave();
1193         m_texdef.rotate( angle );
1194         texdefChanged();
1195 }
1196
1197 void FitTexture( float s_repeat, float t_repeat ){
1198         undoSave();
1199         m_texdef.fit( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat );
1200         texdefChanged();
1201 }
1202
1203 void EmitTextureCoordinates(){
1204         Texdef_EmitTextureCoordinates( m_texdefTransformed, m_shader.width(), m_shader.height(), m_winding, plane3().normal(), g_matrix4_identity );
1205 }
1206
1207
1208 const Vector3& centroid() const {
1209         return m_centroid;
1210 }
1211
1212 void construct_centroid(){
1213         Winding_Centroid( m_winding, plane3(), m_centroid );
1214 }
1215
1216 const Winding& getWinding() const {
1217         return m_winding;
1218 }
1219 Winding& getWinding(){
1220         return m_winding;
1221 }
1222
1223 const Plane3& plane3() const {
1224         m_observer->evaluateTransform();
1225         return m_planeTransformed.plane3();
1226 }
1227 FacePlane& getPlane(){
1228         return m_plane;
1229 }
1230 const FacePlane& getPlane() const {
1231         return m_plane;
1232 }
1233 FaceTexdef& getTexdef(){
1234         return m_texdef;
1235 }
1236 const FaceTexdef& getTexdef() const {
1237         return m_texdef;
1238 }
1239 FaceShader& getShader(){
1240         return m_shader;
1241 }
1242 const FaceShader& getShader() const {
1243         return m_shader;
1244 }
1245
1246 bool isDetail() const {
1247         return ( m_shader.m_flags.m_contentFlags & BRUSH_DETAIL_MASK ) != 0;
1248 }
1249 void setDetail( bool detail ){
1250         undoSave();
1251         if ( detail && !isDetail() ) {
1252                 m_shader.m_flags.m_contentFlags |= BRUSH_DETAIL_MASK;
1253         }
1254         else if ( !detail && isDetail() ) {
1255                 m_shader.m_flags.m_contentFlags &= ~BRUSH_DETAIL_MASK;
1256         }
1257         m_observer->shaderChanged();
1258 }
1259
1260 bool contributes() const {
1261         return m_winding.numpoints > 2;
1262 }
1263 bool is_bounded() const {
1264         for ( Winding::const_iterator i = m_winding.begin(); i != m_winding.end(); ++i )
1265         {
1266                 if ( ( *i ).adjacent == c_brush_maxFaces ) {
1267                         return false;
1268                 }
1269         }
1270         return true;
1271 }
1272 };
1273
1274
1275 class FaceVertexId
1276 {
1277 std::size_t m_face;
1278 std::size_t m_vertex;
1279
1280 public:
1281 FaceVertexId( std::size_t face, std::size_t vertex )
1282         : m_face( face ), m_vertex( vertex ){
1283 }
1284
1285 std::size_t getFace() const {
1286         return m_face;
1287 }
1288 std::size_t getVertex() const {
1289         return m_vertex;
1290 }
1291 };
1292
1293 typedef std::size_t faceIndex_t;
1294
1295 struct EdgeRenderIndices
1296 {
1297         RenderIndex first;
1298         RenderIndex second;
1299
1300         EdgeRenderIndices()
1301                 : first( 0 ), second( 0 ){
1302         }
1303         EdgeRenderIndices( const RenderIndex _first, const RenderIndex _second )
1304                 : first( _first ), second( _second ){
1305         }
1306 };
1307
1308 struct EdgeFaces
1309 {
1310         faceIndex_t first;
1311         faceIndex_t second;
1312
1313         EdgeFaces()
1314                 : first( c_brush_maxFaces ), second( c_brush_maxFaces ){
1315         }
1316         EdgeFaces( const faceIndex_t _first, const faceIndex_t _second )
1317                 : first( _first ), second( _second ){
1318         }
1319 };
1320
1321 class RenderableWireframe : public OpenGLRenderable
1322 {
1323 public:
1324 void render( RenderStateFlags state ) const {
1325 #if 1
1326         glColorPointer( 4, GL_UNSIGNED_BYTE, sizeof( PointVertex ), &m_vertices->colour );
1327         glVertexPointer( 3, GL_FLOAT, sizeof( PointVertex ), &m_vertices->vertex );
1328         glDrawElements( GL_LINES, GLsizei( m_size << 1 ), RenderIndexTypeID, m_faceVertex.data() );
1329 #else
1330         glBegin( GL_LINES );
1331         for ( std::size_t i = 0; i < m_size; ++i )
1332         {
1333                 glVertex3fv( &m_vertices[m_faceVertex[i].first].vertex.x );
1334                 glVertex3fv( &m_vertices[m_faceVertex[i].second].vertex.x );
1335         }
1336         glEnd();
1337 #endif
1338 }
1339
1340 Array<EdgeRenderIndices> m_faceVertex;
1341 std::size_t m_size;
1342 const PointVertex* m_vertices;
1343 };
1344
1345 class Brush;
1346 typedef std::vector<Brush*> brush_vector_t;
1347
1348 class BrushFilter
1349 {
1350 public:
1351 virtual bool filter( const Brush& brush ) const = 0;
1352 };
1353
1354 bool brush_filtered( Brush& brush );
1355 void add_brush_filter( BrushFilter& filter, int mask, bool invert = false );
1356
1357
1358 /// \brief Returns true if 'self' takes priority when building brush b-rep.
1359 inline bool plane3_inside( const Plane3& self, const Plane3& other, bool selfIsLater ){
1360         if ( vector3_equal_epsilon( self.normal(), other.normal(), 0.001 ) ) {
1361                 // same plane? prefer the one with smaller index
1362                 if ( self.dist() == other.dist() ) {
1363                         return selfIsLater;
1364                 }
1365                 return self.dist() < other.dist();
1366         }
1367         return true;
1368 }
1369
1370 typedef SmartPointer<Face> FaceSmartPointer;
1371 typedef std::vector<FaceSmartPointer> Faces;
1372
1373 /// \brief Returns the unique-id of the edge adjacent to \p faceVertex in the edge-pair for the set of \p faces.
1374 inline FaceVertexId next_edge( const Faces& faces, FaceVertexId faceVertex ){
1375         std::size_t adjacent_face = faces[faceVertex.getFace()]->getWinding()[faceVertex.getVertex()].adjacent;
1376         std::size_t adjacent_vertex = Winding_FindAdjacent( faces[adjacent_face]->getWinding(), faceVertex.getFace() );
1377
1378         ASSERT_MESSAGE( adjacent_vertex != c_brush_maxFaces, "connectivity data invalid" );
1379         if ( adjacent_vertex == c_brush_maxFaces ) {
1380                 return faceVertex;
1381         }
1382
1383         return FaceVertexId( adjacent_face, adjacent_vertex );
1384 }
1385
1386 /// \brief Returns the unique-id of the vertex adjacent to \p faceVertex in the vertex-ring for the set of \p faces.
1387 inline FaceVertexId next_vertex( const Faces& faces, FaceVertexId faceVertex ){
1388         FaceVertexId nextEdge = next_edge( faces, faceVertex );
1389         return FaceVertexId( nextEdge.getFace(), Winding_next( faces[nextEdge.getFace()]->getWinding(), nextEdge.getVertex() ) );
1390 }
1391
1392 class SelectableEdge
1393 {
1394 Vector3 getEdge() const {
1395         const Winding& winding = getFace().getWinding();
1396         return vector3_mid( winding[m_faceVertex.getVertex()].vertex, winding[Winding_next( winding, m_faceVertex.getVertex() )].vertex );
1397 }
1398
1399 public:
1400 Faces& m_faces;
1401 FaceVertexId m_faceVertex;
1402
1403 SelectableEdge( Faces& faces, FaceVertexId faceVertex )
1404         : m_faces( faces ), m_faceVertex( faceVertex ){
1405 }
1406 SelectableEdge& operator=( const SelectableEdge& other ){
1407         m_faceVertex = other.m_faceVertex;
1408         return *this;
1409 }
1410
1411 Face& getFace() const {
1412         return *m_faces[m_faceVertex.getFace()];
1413 }
1414
1415 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1416         test.TestPoint( getEdge(), best );
1417 }
1418 };
1419
1420 class SelectableVertex
1421 {
1422 Vector3 getVertex() const {
1423         return getFace().getWinding()[m_faceVertex.getVertex()].vertex;
1424 }
1425
1426 public:
1427 Faces& m_faces;
1428 FaceVertexId m_faceVertex;
1429
1430 SelectableVertex( Faces& faces, FaceVertexId faceVertex )
1431         : m_faces( faces ), m_faceVertex( faceVertex ){
1432 }
1433 SelectableVertex& operator=( const SelectableVertex& other ){
1434         m_faceVertex = other.m_faceVertex;
1435         return *this;
1436 }
1437
1438 Face& getFace() const {
1439         return *m_faces[m_faceVertex.getFace()];
1440 }
1441
1442 void testSelect( SelectionTest& test, SelectionIntersection& best ){
1443         test.TestPoint( getVertex(), best );
1444 }
1445 };
1446
1447 class BrushObserver
1448 {
1449 public:
1450 virtual void reserve( std::size_t size ) = 0;
1451 virtual void clear() = 0;
1452 virtual void push_back( Face& face ) = 0;
1453 virtual void pop_back() = 0;
1454 virtual void erase( std::size_t index ) = 0;
1455 virtual void connectivityChanged() = 0;
1456
1457 virtual void edge_clear() = 0;
1458 virtual void edge_push_back( SelectableEdge& edge ) = 0;
1459
1460 virtual void vertex_clear() = 0;
1461 virtual void vertex_push_back( SelectableVertex& vertex ) = 0;
1462
1463 virtual void DEBUG_verify() const = 0;
1464 };
1465
1466 class BrushVisitor
1467 {
1468 public:
1469 virtual void visit( Face& face ) const = 0;
1470 };
1471
1472 class Brush :
1473         public TransformNode,
1474         public Bounded,
1475         public Cullable,
1476         public Snappable,
1477         public Undoable,
1478         public FaceObserver,
1479         public Filterable,
1480         public Nameable,
1481         public BrushDoom3
1482 {
1483 private:
1484 scene::Node* m_node;
1485 typedef UniqueSet<BrushObserver*> Observers;
1486 Observers m_observers;
1487 UndoObserver* m_undoable_observer;
1488 MapFile* m_map;
1489
1490 // state
1491 Faces m_faces;
1492 // ----
1493
1494 // cached data compiled from state
1495 Array<PointVertex> m_faceCentroidPoints;
1496 RenderablePointArray m_render_faces;
1497
1498 Array<PointVertex> m_uniqueVertexPoints;
1499 typedef std::vector<SelectableVertex> SelectableVertices;
1500 SelectableVertices m_select_vertices;
1501 RenderablePointArray m_render_vertices;
1502
1503 Array<PointVertex> m_uniqueEdgePoints;
1504 typedef std::vector<SelectableEdge> SelectableEdges;
1505 SelectableEdges m_select_edges;
1506 RenderablePointArray m_render_edges;
1507
1508 Array<EdgeRenderIndices> m_edge_indices;
1509 Array<EdgeFaces> m_edge_faces;
1510
1511 AABB m_aabb_local;
1512 // ----
1513
1514 Callback m_evaluateTransform;
1515 Callback m_boundsChanged;
1516
1517 mutable bool m_planeChanged;   // b-rep evaluation required
1518 mutable bool m_transformChanged;   // transform evaluation required
1519 // ----
1520
1521 public:
1522 STRING_CONSTANT( Name, "Brush" );
1523
1524 Callback m_lightsChanged;
1525
1526 // static data
1527 static Shader* m_state_point;
1528 // ----
1529
1530 static EBrushType m_type;
1531 static double m_maxWorldCoord;
1532
1533 Brush( scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
1534         m_node( &node ),
1535         m_undoable_observer( 0 ),
1536         m_map( 0 ),
1537         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1538         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1539         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1540         m_evaluateTransform( evaluateTransform ),
1541         m_boundsChanged( boundsChanged ),
1542         m_planeChanged( false ),
1543         m_transformChanged( false ){
1544         planeChanged();
1545 }
1546 Brush( const Brush& other, scene::Node& node, const Callback& evaluateTransform, const Callback& boundsChanged ) :
1547         m_node( &node ),
1548         m_undoable_observer( 0 ),
1549         m_map( 0 ),
1550         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1551         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1552         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1553         m_evaluateTransform( evaluateTransform ),
1554         m_boundsChanged( boundsChanged ),
1555         m_planeChanged( false ),
1556         m_transformChanged( false ){
1557         copy( other );
1558 }
1559 Brush( const Brush& other ) :
1560         TransformNode( other ),
1561         Bounded( other ),
1562         Cullable( other ),
1563         Snappable(),
1564         Undoable( other ),
1565         FaceObserver( other ),
1566         Filterable( other ),
1567         Nameable( other ),
1568         BrushDoom3( other ),
1569         m_node( 0 ),
1570         m_undoable_observer( 0 ),
1571         m_map( 0 ),
1572         m_render_faces( m_faceCentroidPoints, GL_POINTS ),
1573         m_render_vertices( m_uniqueVertexPoints, GL_POINTS ),
1574         m_render_edges( m_uniqueEdgePoints, GL_POINTS ),
1575         m_planeChanged( false ),
1576         m_transformChanged( false ){
1577         copy( other );
1578 }
1579 ~Brush(){
1580         ASSERT_MESSAGE( m_observers.empty(), "Brush::~Brush: observers still attached" );
1581 }
1582
1583 // assignment not supported
1584 Brush& operator=( const Brush& other );
1585
1586 void setDoom3GroupOrigin( const Vector3& origin ){
1587         //globalOutputStream() << "func_static origin before: " << m_funcStaticOrigin << " after: " << origin << "\n";
1588         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1589         {
1590                 ( *i )->getPlane().m_funcStaticOrigin = origin;
1591                 ( *i )->getPlane().updateTranslated();
1592                 ( *i )->planeChanged();
1593         }
1594         planeChanged();
1595 }
1596
1597 void attach( BrushObserver& observer ){
1598         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1599         {
1600                 observer.push_back( *( *i ) );
1601         }
1602
1603         for ( SelectableEdges::iterator i = m_select_edges.begin(); i != m_select_edges.end(); ++i )
1604         {
1605                 observer.edge_push_back( *i );
1606         }
1607
1608         for ( SelectableVertices::iterator i = m_select_vertices.begin(); i != m_select_vertices.end(); ++i )
1609         {
1610                 observer.vertex_push_back( *i );
1611         }
1612
1613         m_observers.insert( &observer );
1614 }
1615 void detach( BrushObserver& observer ){
1616         m_observers.erase( &observer );
1617 }
1618
1619 void forEachFace( const BrushVisitor& visitor ) const {
1620         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1621         {
1622                 visitor.visit( *( *i ) );
1623         }
1624 }
1625
1626 void forEachFace_instanceAttach( MapFile* map ) const {
1627         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1628         {
1629                 ( *i )->instanceAttach( map );
1630         }
1631 }
1632 void forEachFace_instanceDetach( MapFile* map ) const {
1633         for ( Faces::const_iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1634         {
1635                 ( *i )->instanceDetach( map );
1636         }
1637 }
1638
1639 InstanceCounter m_instanceCounter;
1640 void instanceAttach( const scene::Path& path ){
1641         if ( ++m_instanceCounter.m_count == 1 ) {
1642                 m_map = path_find_mapfile( path.begin(), path.end() );
1643                 m_undoable_observer = GlobalUndoSystem().observer( this );
1644                 GlobalFilterSystem().registerFilterable( *this );
1645                 forEachFace_instanceAttach( m_map );
1646         }
1647         else
1648         {
1649                 ASSERT_MESSAGE( path_find_mapfile( path.begin(), path.end() ) == m_map, "node is instanced across more than one file" );
1650         }
1651 }
1652 void instanceDetach( const scene::Path& path ){
1653         if ( --m_instanceCounter.m_count == 0 ) {
1654                 forEachFace_instanceDetach( m_map );
1655                 GlobalFilterSystem().unregisterFilterable( *this );
1656                 m_map = 0;
1657                 m_undoable_observer = 0;
1658                 GlobalUndoSystem().release( this );
1659         }
1660 }
1661
1662 // nameable
1663 const char* name() const {
1664         return "brush";
1665 }
1666 void attach( const NameCallback& callback ){
1667 }
1668 void detach( const NameCallback& callback ){
1669 }
1670
1671 // filterable
1672 void updateFiltered(){
1673         if ( m_node != 0 ) {
1674                 if ( brush_filtered( *this ) ) {
1675                         m_node->enable( scene::Node::eFiltered );
1676                 }
1677                 else
1678                 {
1679                         m_node->disable( scene::Node::eFiltered );
1680                 }
1681         }
1682 }
1683
1684 // observer
1685 void planeChanged(){
1686         m_planeChanged = true;
1687         aabbChanged();
1688         m_lightsChanged();
1689 }
1690 void shaderChanged(){
1691         updateFiltered();
1692         planeChanged();
1693 }
1694
1695 void evaluateBRep() const {
1696         if ( m_planeChanged ) {
1697                 m_planeChanged = false;
1698                 const_cast<Brush*>( this )->buildBRep();
1699         }
1700 }
1701
1702 void transformChanged(){
1703         m_transformChanged = true;
1704         planeChanged();
1705 }
1706 typedef MemberCaller<Brush, &Brush::transformChanged> TransformChangedCaller;
1707
1708 void evaluateTransform(){
1709         if ( m_transformChanged ) {
1710                 m_transformChanged = false;
1711                 revertTransform();
1712                 m_evaluateTransform();
1713         }
1714 }
1715 const Matrix4& localToParent() const {
1716         return g_matrix4_identity;
1717 }
1718 void aabbChanged(){
1719         m_boundsChanged();
1720 }
1721 const AABB& localAABB() const {
1722         evaluateBRep();
1723         return m_aabb_local;
1724 }
1725
1726 VolumeIntersectionValue intersectVolume( const VolumeTest& test, const Matrix4& localToWorld ) const {
1727         return test.TestAABB( m_aabb_local, localToWorld );
1728 }
1729
1730 void renderComponents( SelectionSystem::EComponentMode mode, Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
1731         switch ( mode )
1732         {
1733         case SelectionSystem::eVertex:
1734                 renderer.addRenderable( m_render_vertices, localToWorld );
1735                 break;
1736         case SelectionSystem::eEdge:
1737                 renderer.addRenderable( m_render_edges, localToWorld );
1738                 break;
1739         case SelectionSystem::eFace:
1740                 renderer.addRenderable( m_render_faces, localToWorld );
1741                 break;
1742         default:
1743                 break;
1744         }
1745 }
1746
1747 void transform( const Matrix4& matrix ){
1748         bool mirror = matrix4_handedness( matrix ) == MATRIX4_LEFTHANDED;
1749
1750         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1751         {
1752                 ( *i )->transform( matrix, mirror );
1753         }
1754 }
1755 void snapto( float snap ){
1756         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1757         {
1758                 ( *i )->snapto( snap );
1759         }
1760 }
1761 void revertTransform(){
1762         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1763         {
1764                 ( *i )->revertTransform();
1765         }
1766 }
1767 void freezeTransform(){
1768         for ( Faces::iterator i = m_faces.begin(); i != m_faces.end(); ++i )
1769         {
1770                 ( *i )->freezeTransform();
1771         }
1772 }
1773
1774 /// \brief Returns the absolute index of the \p faceVertex.
1775 std::size_t absoluteIndex( FaceVertexId faceVertex ){
1776         std::size_t index = 0;
1777         for ( std::size_t i = 0; i < faceVertex.getFace(); ++i )
1778         {
1779                 index += m_faces[i]->getWinding().numpoints;
1780         }
1781         return index + faceVertex.getVertex();
1782 }
1783
1784 void appendFaces( const Faces& other ){
1785         clear();
1786         for ( Faces::const_iterator i = other.begin(); i != other.end(); ++i )
1787         {
1788                 push_back( *i );
1789         }
1790 }
1791
1792 /// \brief The undo memento for a brush stores only the list of face references - the faces are not copied.
1793 class BrushUndoMemento : public UndoMemento
1794 {
1795 public:
1796 BrushUndoMemento( const Faces& faces ) : m_faces( faces ){
1797 }
1798 void release(){
1799         delete this;
1800 }
1801
1802 Faces m_faces;
1803 };
1804
1805 void undoSave(){
1806         if ( m_map != 0 ) {
1807                 m_map->changed();
1808         }
1809         if ( m_undoable_observer != 0 ) {
1810                 m_undoable_observer->save( this );
1811         }
1812 }
1813
1814 UndoMemento* exportState() const {
1815         return new BrushUndoMemento( m_faces );
1816 }
1817
1818 void importState( const UndoMemento* state ){
1819         undoSave();
1820         appendFaces( static_cast<const BrushUndoMemento*>( state )->m_faces );
1821         planeChanged();
1822
1823         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1824         {
1825                 ( *i )->DEBUG_verify();
1826         }
1827 }
1828
1829 bool isDetail(){
1830         return !m_faces.empty() && m_faces.front()->isDetail();
1831 }
1832
1833 /// \brief Appends a copy of \p face to the end of the face list.
1834 Face* addFace( const Face& face ){
1835         if ( m_faces.size() == c_brush_maxFaces ) {
1836                 return 0;
1837         }
1838         undoSave();
1839         push_back( FaceSmartPointer( new Face( face, this ) ) );
1840         m_faces.back()->setDetail( isDetail() );
1841         planeChanged();
1842         return m_faces.back();
1843 }
1844
1845 /// \brief Appends a new face constructed from the parameters to the end of the face list.
1846 Face* addPlane( const Vector3& p0, const Vector3& p1, const Vector3& p2, const char* shader, const TextureProjection& projection ){
1847         if ( m_faces.size() == c_brush_maxFaces ) {
1848                 return 0;
1849         }
1850         undoSave();
1851         push_back( FaceSmartPointer( new Face( p0, p1, p2, shader, projection, this ) ) );
1852         m_faces.back()->setDetail( isDetail() );
1853         planeChanged();
1854         return m_faces.back();
1855 }
1856
1857 static void constructStatic( EBrushType type ){
1858         m_type = type;
1859         Face::m_type = type;
1860         FacePlane::m_type = type;
1861
1862         g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_QUAKE;
1863         if ( m_type == eBrushTypeQuake3BP || m_type == eBrushTypeDoom3 || m_type == eBrushTypeQuake4 ) {
1864                 g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_BRUSHPRIMITIVES;
1865                 // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
1866         }
1867         else if ( m_type == eBrushTypeHalfLife ) {
1868                 g_bp_globals.m_texdefTypeId = TEXDEFTYPEID_HALFLIFE;
1869                 // g_brush_texturelock_enabled = true; // bad idea, this overrides user setting
1870         }
1871
1872         Face::m_quantise = ( m_type == eBrushTypeQuake ) ? quantiseInteger : quantiseFloating;
1873
1874         m_state_point = GlobalShaderCache().capture( "$POINT" );
1875 }
1876 static void destroyStatic(){
1877         GlobalShaderCache().release( "$POINT" );
1878 }
1879
1880 std::size_t DEBUG_size(){
1881         return m_faces.size();
1882 }
1883
1884 typedef Faces::const_iterator const_iterator;
1885
1886 const_iterator begin() const {
1887         return m_faces.begin();
1888 }
1889 const_iterator end() const {
1890         return m_faces.end();
1891 }
1892
1893 Face* back(){
1894         return m_faces.back();
1895 }
1896 const Face* back() const {
1897         return m_faces.back();
1898 }
1899 void reserve( std::size_t count ){
1900         m_faces.reserve( count );
1901         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1902         {
1903                 ( *i )->reserve( count );
1904         }
1905 }
1906 void push_back( Faces::value_type face ){
1907         m_faces.push_back( face );
1908         if ( m_instanceCounter.m_count != 0 ) {
1909                 m_faces.back()->instanceAttach( m_map );
1910         }
1911         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1912         {
1913                 ( *i )->push_back( *face );
1914                 ( *i )->DEBUG_verify();
1915         }
1916 }
1917 void pop_back(){
1918         if ( m_instanceCounter.m_count != 0 ) {
1919                 m_faces.back()->instanceDetach( m_map );
1920         }
1921         m_faces.pop_back();
1922         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1923         {
1924                 ( *i )->pop_back();
1925                 ( *i )->DEBUG_verify();
1926         }
1927 }
1928 void erase( std::size_t index ){
1929         if ( m_instanceCounter.m_count != 0 ) {
1930                 m_faces[index]->instanceDetach( m_map );
1931         }
1932         m_faces.erase( m_faces.begin() + index );
1933         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1934         {
1935                 ( *i )->erase( index );
1936                 ( *i )->DEBUG_verify();
1937         }
1938 }
1939 void connectivityChanged(){
1940         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1941         {
1942                 ( *i )->connectivityChanged();
1943         }
1944 }
1945
1946
1947 void clear(){
1948         undoSave();
1949         if ( m_instanceCounter.m_count != 0 ) {
1950                 forEachFace_instanceDetach( m_map );
1951         }
1952         m_faces.clear();
1953         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
1954         {
1955                 ( *i )->clear();
1956                 ( *i )->DEBUG_verify();
1957         }
1958 }
1959 std::size_t size() const {
1960         return m_faces.size();
1961 }
1962 bool empty() const {
1963         return m_faces.empty();
1964 }
1965
1966 /// \brief Returns true if any face of the brush contributes to the final B-Rep.
1967 bool hasContributingFaces() const {
1968         for ( const_iterator i = begin(); i != end(); ++i )
1969         {
1970                 if ( ( *i )->contributes() ) {
1971                         return true;
1972                 }
1973         }
1974         return false;
1975 }
1976
1977 /// \brief Removes faces that do not contribute to the brush. This is useful for cleaning up after CSG operations on the brush.
1978 /// Note: removal of empty faces is not performed during direct brush manipulations, because it would make a manipulation irreversible if it created an empty face.
1979 void removeEmptyFaces(){
1980         evaluateBRep();
1981
1982         {
1983                 std::size_t i = 0;
1984                 while ( i < m_faces.size() )
1985                 {
1986                         if ( !m_faces[i]->contributes() ) {
1987                                 erase( i );
1988                                 planeChanged();
1989                         }
1990                         else
1991                         {
1992                                 ++i;
1993                         }
1994                 }
1995         }
1996 }
1997
1998 /// \brief Constructs \p winding from the intersection of \p plane with the other planes of the brush.
1999 void windingForClipPlane( Winding& winding, const Plane3& plane ) const {
2000         FixedWinding buffer[2];
2001         bool swap = false;
2002
2003         // get a poly that covers an effectively infinite area
2004         Winding_createInfinite( buffer[swap], plane, m_maxWorldCoord + 1 );
2005
2006         // chop the poly by all of the other faces
2007         {
2008                 for ( std::size_t i = 0; i < m_faces.size(); ++i )
2009                 {
2010                         const Face& clip = *m_faces[i];
2011
2012                         if ( plane3_equal( clip.plane3(), plane )
2013                                  || !plane3_valid( clip.plane3() ) || !plane_unique( i )
2014                                  || plane3_opposing( plane, clip.plane3() ) ) {
2015                                 continue;
2016                         }
2017
2018                         if( buffer[swap].points.empty() ){
2019                                 //globalErrorStream() << "windingForClipPlane: about to feed empty winding\n";
2020                                 break;
2021                         }
2022
2023                         buffer[!swap].clear();
2024
2025 #if BRUSH_CONNECTIVITY_DEBUG
2026                         globalOutputStream() << "clip vs face: " << i << "\n";
2027 #endif
2028
2029                         {
2030                                 // flip the plane, because we want to keep the back side
2031                                 Plane3 clipPlane( vector3_negated( clip.plane3().normal() ), -clip.plane3().dist() );
2032                                 Winding_Clip( buffer[swap], plane, clipPlane, i, buffer[!swap] );
2033                         }
2034
2035 #if BRUSH_CONNECTIVITY_DEBUG
2036                         for ( FixedWinding::Points::iterator k = buffer[!swap].points.begin(), j = buffer[!swap].points.end() - 1; k != buffer[!swap].points.end(); j = k, ++k )
2037                         {
2038                                 if ( vector3_length_squared( vector3_subtracted( ( *k ).vertex, ( *j ).vertex ) ) < 1 ) {
2039                                         globalOutputStream() << "v: " << std::distance( buffer[!swap].points.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n";
2040                                 }
2041                         }
2042 #endif
2043
2044                         //ASSERT_MESSAGE(buffer[!swap].numpoints != 1, "created single-point winding");
2045
2046                         swap = !swap;
2047                 }
2048         }
2049
2050         Winding_forFixedWinding( winding, buffer[swap] );
2051
2052 #if BRUSH_CONNECTIVITY_DEBUG
2053         Winding_printConnectivity( winding );
2054
2055         for ( Winding::iterator i = winding.begin(), j = winding.end() - 1; i != winding.end(); j = i, ++i )
2056         {
2057                 if ( vector3_length_squared( vector3_subtracted( ( *i ).vertex, ( *j ).vertex ) ) < 1 ) {
2058                         globalOutputStream() << "v: " << std::distance( winding.begin(), j ) << " tiny edge adjacent to face " << ( *j ).adjacent << "\n";
2059                 }
2060         }
2061 #endif
2062 }
2063
2064 void update_wireframe( RenderableWireframe& wire, const bool* faces_visible ) const {
2065         wire.m_faceVertex.resize( m_edge_indices.size() );
2066         wire.m_vertices = m_uniqueVertexPoints.data();
2067         wire.m_size = 0;
2068         for ( std::size_t i = 0; i < m_edge_faces.size(); ++i )
2069         {
2070                 if ( faces_visible[m_edge_faces[i].first]
2071                          || faces_visible[m_edge_faces[i].second] ) {
2072                         wire.m_faceVertex[wire.m_size++] = m_edge_indices[i];
2073                 }
2074         }
2075 }
2076
2077
2078 void update_faces_wireframe( Array<PointVertex>& wire, const bool* faces_visible ) const {
2079         std::size_t count = 0;
2080         for ( std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i )
2081         {
2082                 if ( faces_visible[i] ) {
2083                         ++count;
2084                 }
2085         }
2086
2087         wire.resize( count );
2088         Array<PointVertex>::iterator p = wire.begin();
2089         for ( std::size_t i = 0; i < m_faceCentroidPoints.size(); ++i )
2090         {
2091                 if ( faces_visible[i] ) {
2092                         *p++ = m_faceCentroidPoints[i];
2093                 }
2094         }
2095 }
2096
2097 /// \brief Makes this brush a deep-copy of the \p other.
2098 void copy( const Brush& other ){
2099         for ( Faces::const_iterator i = other.m_faces.begin(); i != other.m_faces.end(); ++i )
2100         {
2101                 addFace( *( *i ) );
2102         }
2103         planeChanged();
2104 }
2105
2106 private:
2107 void edge_push_back( FaceVertexId faceVertex ){
2108         m_select_edges.push_back( SelectableEdge( m_faces, faceVertex ) );
2109         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2110         {
2111                 ( *i )->edge_push_back( m_select_edges.back() );
2112         }
2113 }
2114 void edge_clear(){
2115         m_select_edges.clear();
2116         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2117         {
2118                 ( *i )->edge_clear();
2119         }
2120 }
2121 void vertex_push_back( FaceVertexId faceVertex ){
2122         m_select_vertices.push_back( SelectableVertex( m_faces, faceVertex ) );
2123         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2124         {
2125                 ( *i )->vertex_push_back( m_select_vertices.back() );
2126         }
2127 }
2128 void vertex_clear(){
2129         m_select_vertices.clear();
2130         for ( Observers::iterator i = m_observers.begin(); i != m_observers.end(); ++i )
2131         {
2132                 ( *i )->vertex_clear();
2133         }
2134 }
2135
2136 /// \brief Returns true if the face identified by \p index is preceded by another plane that takes priority over it.
2137 bool plane_unique( std::size_t index ) const {
2138         // duplicate plane
2139         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2140         {
2141                 if ( index != i && !plane3_inside( m_faces[index]->plane3(), m_faces[i]->plane3(), index < i ) ) {
2142                         return false;
2143                 }
2144         }
2145         return true;
2146 }
2147
2148 /// \brief Removes edges that are smaller than the tolerance used when generating brush windings.
2149 void removeDegenerateEdges(){
2150         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2151         {
2152                 Winding& winding = m_faces[i]->getWinding();
2153                 for ( Winding::iterator j = winding.begin(); j != winding.end(); )
2154                 {
2155                         std::size_t index = std::distance( winding.begin(), j );
2156                         std::size_t next = Winding_next( winding, index );
2157                         if ( Edge_isDegenerate( winding[index].vertex, winding[next].vertex ) ) {
2158 #if BRUSH_DEGENERATE_DEBUG
2159                                 globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate edge adjacent to " << winding[index].adjacent << "\n";
2160 #endif
2161                                 Winding& other = m_faces[winding[index].adjacent]->getWinding();
2162                                 std::size_t adjacent = Winding_FindAdjacent( other, i );
2163                                 if ( adjacent != c_brush_maxFaces ) {
2164                                         other.erase( other.begin() + adjacent );
2165                                 }
2166                                 winding.erase( j );
2167                         }
2168                         else
2169                         {
2170                                 ++j;
2171                         }
2172                 }
2173         }
2174 }
2175
2176 /// \brief Invalidates faces that have only two vertices in their winding, while preserving edge-connectivity information.
2177 void removeDegenerateFaces(){
2178         // save adjacency info for degenerate faces
2179         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2180         {
2181                 Winding& degen = m_faces[i]->getWinding();
2182
2183                 if ( degen.numpoints == 2 ) {
2184 #if BRUSH_DEGENERATE_DEBUG
2185                         globalOutputStream() << "Brush::buildWindings: face " << i << ": degenerate winding adjacent to " << degen[0].adjacent << ", " << degen[1].adjacent << "\n";
2186 #endif
2187                         // this is an "edge" face, where the plane touches the edge of the brush
2188                         {
2189                                 Winding& winding = m_faces[degen[0].adjacent]->getWinding();
2190                                 std::size_t index = Winding_FindAdjacent( winding, i );
2191                                 if ( index != c_brush_maxFaces ) {
2192 #if BRUSH_DEGENERATE_DEBUG
2193                                         globalOutputStream() << "Brush::buildWindings: face " << degen[0].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[1].adjacent << "\n";
2194 #endif
2195                                         winding[index].adjacent = degen[1].adjacent;
2196                                 }
2197                         }
2198
2199                         {
2200                                 Winding& winding = m_faces[degen[1].adjacent]->getWinding();
2201                                 std::size_t index = Winding_FindAdjacent( winding, i );
2202                                 if ( index != c_brush_maxFaces ) {
2203 #if BRUSH_DEGENERATE_DEBUG
2204                                         globalOutputStream() << "Brush::buildWindings: face " << degen[1].adjacent << ": remapping adjacent " << winding[index].adjacent << " to " << degen[0].adjacent << "\n";
2205 #endif
2206                                         winding[index].adjacent = degen[0].adjacent;
2207                                 }
2208                         }
2209
2210                         degen.resize( 0 );
2211                 }
2212         }
2213 }
2214
2215 /// \brief Removes edges that have the same adjacent-face as their immediate neighbour.
2216 void removeDuplicateEdges(){
2217         // verify face connectivity graph
2218         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2219         {
2220                 //if(m_faces[i]->contributes())
2221                 {
2222                         Winding& winding = m_faces[i]->getWinding();
2223                         for ( std::size_t j = 0; j != winding.numpoints; )
2224                         {
2225                                 std::size_t next = Winding_next( winding, j );
2226                                 if ( winding[j].adjacent == winding[next].adjacent ) {
2227 #if BRUSH_DEGENERATE_DEBUG
2228                                         globalOutputStream() << "Brush::buildWindings: face " << i << ": removed duplicate edge adjacent to face " << winding[j].adjacent << "\n";
2229 #endif
2230                                         winding.erase( winding.begin() + next );
2231                                 }
2232                                 else
2233                                 {
2234                                         ++j;
2235                                 }
2236                         }
2237                 }
2238         }
2239 }
2240
2241 /// \brief Removes edges that do not have a matching pair in their adjacent-face.
2242 void verifyConnectivityGraph(){
2243         // verify face connectivity graph
2244         for ( std::size_t i = 0; i < m_faces.size(); ++i )
2245         {
2246                 //if(m_faces[i]->contributes())
2247                 {
2248                         Winding& winding = m_faces[i]->getWinding();
2249                         for ( Winding::iterator j = winding.begin(); j != winding.end(); )
2250                         {
2251 #if BRUSH_CONNECTIVITY_DEBUG
2252                                 globalOutputStream() << "Brush::buildWindings: face " << i << ": adjacent to face " << ( *j ).adjacent << "\n";
2253 #endif
2254                                 // remove unidirectional graph edges
2255                                 if ( ( *j ).adjacent == c_brush_maxFaces
2256                                          || Winding_FindAdjacent( m_faces[( *j ).adjacent]->getWinding(), i ) == c_brush_maxFaces ) {
2257 #if BRUSH_CONNECTIVITY_DEBUG
2258                                         globalOutputStream() << "Brush::buildWindings: face " << i << ": removing unidirectional connectivity graph edge adjacent to face " << ( *j ).adjacent << "\n";
2259 #endif
2260                                         winding.erase( j );
2261                                 }
2262                                 else
2263                                 {
2264                                         ++j;
2265                                 }
2266                         }
2267                 }
2268         }
2269 }
2270
2271 /// \brief Returns true if the brush is a finite volume. A brush without a finite volume extends past the maximum world bounds and is not valid.
2272 bool isBounded(){
2273         for ( const_iterator i = begin(); i != end(); ++i )
2274         {
2275                 if ( !( *i )->is_bounded() ) {
2276                         return false;
2277                 }
2278         }
2279         return true;
2280 }
2281
2282 /// \brief Constructs the polygon windings for each face of the brush. Also updates the brush bounding-box and face texture-coordinates.
2283 bool buildWindings(){
2284
2285         {
2286                 m_aabb_local = AABB();
2287
2288                 for ( std::size_t i = 0; i < m_faces.size(); ++i )
2289                 {
2290                         Face& f = *m_faces[i];
2291
2292                         if ( !plane3_valid( f.plane3() ) || !plane_unique( i ) ) {
2293                                 f.getWinding().resize( 0 );
2294                         }
2295                         else
2296                         {
2297 #if BRUSH_CONNECTIVITY_DEBUG
2298                                 globalOutputStream() << "face: " << i << "\n";
2299 #endif
2300                                 windingForClipPlane( f.getWinding(), f.plane3() );
2301
2302                                 // update brush bounds
2303                                 const Winding& winding = f.getWinding();
2304                                 for ( Winding::const_iterator i = winding.begin(); i != winding.end(); ++i )
2305                                 {
2306                                         aabb_extend_by_point_safe( m_aabb_local, ( *i ).vertex );
2307                                 }
2308
2309                                 // update texture coordinates
2310                                 f.EmitTextureCoordinates();
2311                         }
2312                 }
2313         }
2314
2315         bool degenerate = !isBounded();
2316
2317         if ( !degenerate ) {
2318                 // clean up connectivity information.
2319                 // these cleanups must be applied in a specific order.
2320                 removeDegenerateEdges();
2321                 removeDegenerateFaces();
2322                 removeDuplicateEdges();
2323                 verifyConnectivityGraph();
2324         }
2325
2326         return degenerate;
2327 }
2328
2329 /// \brief Constructs the face windings and updates anything that depends on them.
2330 void buildBRep();
2331 };
2332
2333
2334
2335 class FaceInstance;
2336
2337 class FaceInstanceSet
2338 {
2339 typedef SelectionList<FaceInstance> FaceInstances;
2340 FaceInstances m_faceInstances;
2341 public:
2342 void insert( FaceInstance& faceInstance ){
2343         m_faceInstances.append( faceInstance );
2344 }
2345 void erase( FaceInstance& faceInstance ){
2346         m_faceInstances.erase( faceInstance );
2347 }
2348
2349 template<typename Functor>
2350 void foreach( Functor functor ){
2351         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
2352         {
2353                 functor( *( *i ) );
2354         }
2355 }
2356
2357 bool empty() const {
2358         return m_faceInstances.empty();
2359 }
2360 FaceInstance& last() const {
2361         return m_faceInstances.back();
2362 }
2363 };
2364
2365 extern FaceInstanceSet g_SelectedFaceInstances;
2366
2367 typedef std::list<std::size_t> VertexSelection;
2368
2369 inline VertexSelection::iterator VertexSelection_find( VertexSelection& self, std::size_t value ){
2370         return std::find( self.begin(), self.end(), value );
2371 }
2372
2373 inline VertexSelection::const_iterator VertexSelection_find( const VertexSelection& self, std::size_t value ){
2374         return std::find( self.begin(), self.end(), value );
2375 }
2376
2377 inline VertexSelection::iterator VertexSelection_insert( VertexSelection& self, std::size_t value ){
2378         VertexSelection::iterator i = VertexSelection_find( self, value );
2379         if ( i == self.end() ) {
2380                 self.push_back( value );
2381                 return --self.end();
2382         }
2383         return i;
2384 }
2385 inline void VertexSelection_erase( VertexSelection& self, std::size_t value ){
2386         VertexSelection::iterator i = VertexSelection_find( self, value );
2387         if ( i != self.end() ) {
2388                 self.erase( i );
2389         }
2390 }
2391
2392 inline bool triangle_reversed( std::size_t x, std::size_t y, std::size_t z ){
2393         return !( ( x < y && y < z ) || ( z < x && x < y ) || ( y < z && z < x ) );
2394 }
2395 template<typename Element>
2396 inline Vector3 triangle_cross( const BasicVector3<Element>& x, const BasicVector3<Element> y, const BasicVector3<Element>& z ){
2397         return vector3_cross( y - x, z - x );
2398 }
2399 template<typename Element>
2400 inline bool triangles_same_winding( const BasicVector3<Element>& x1, const BasicVector3<Element> y1, const BasicVector3<Element>& z1, const BasicVector3<Element>& x2, const BasicVector3<Element> y2, const BasicVector3<Element>& z2 ){
2401         return vector3_dot( triangle_cross( x1, y1, z1 ), triangle_cross( x2, y2, z2 ) ) > 0;
2402 }
2403
2404
2405 class VectorLightList : public LightList
2406 {
2407 typedef std::vector<const RendererLight*> Lights;
2408 Lights m_lights;
2409 public:
2410 void addLight( const RendererLight& light ){
2411         m_lights.push_back( &light );
2412 }
2413 void clear(){
2414         m_lights.clear();
2415 }
2416 void evaluateLights() const {
2417 }
2418 void lightsChanged() const {
2419 }
2420 void forEachLight( const RendererLightCallback& callback ) const {
2421         for ( Lights::const_iterator i = m_lights.begin(); i != m_lights.end(); ++i )
2422         {
2423                 callback( *( *i ) );
2424         }
2425 }
2426 };
2427
2428 class FaceInstance
2429 {
2430 Face* m_face;
2431 ObservedSelectable m_selectable;
2432 ObservedSelectable m_selectableVertices;
2433 ObservedSelectable m_selectableEdges;
2434 SelectionChangeCallback m_selectionChanged;
2435
2436 VertexSelection m_vertexSelection;
2437 VertexSelection m_edgeSelection;
2438
2439 public:
2440 mutable VectorLightList m_lights;
2441
2442 FaceInstance( Face& face, const SelectionChangeCallback& observer ) :
2443         m_face( &face ),
2444         m_selectable( SelectedChangedCaller( *this ) ),
2445         m_selectableVertices( observer ),
2446         m_selectableEdges( observer ),
2447         m_selectionChanged( observer ){
2448 }
2449 FaceInstance( const FaceInstance& other ) :
2450         m_face( other.m_face ),
2451         m_selectable( SelectedChangedCaller( *this ) ),
2452         m_selectableVertices( other.m_selectableVertices ),
2453         m_selectableEdges( other.m_selectableEdges ),
2454         m_selectionChanged( other.m_selectionChanged ){
2455 }
2456 FaceInstance& operator=( const FaceInstance& other ){
2457         m_face = other.m_face;
2458         return *this;
2459 }
2460
2461 Face& getFace(){
2462         return *m_face;
2463 }
2464 const Face& getFace() const {
2465         return *m_face;
2466 }
2467
2468 void selectedChanged( const Selectable& selectable ){
2469         if ( selectable.isSelected() ) {
2470                 g_SelectedFaceInstances.insert( *this );
2471         }
2472         else
2473         {
2474                 g_SelectedFaceInstances.erase( *this );
2475         }
2476         m_selectionChanged( selectable );
2477 }
2478 typedef MemberCaller1<FaceInstance, const Selectable&, &FaceInstance::selectedChanged> SelectedChangedCaller;
2479
2480 bool selectedVertices() const {
2481         return !m_vertexSelection.empty();
2482 }
2483 bool selectedEdges() const {
2484         return !m_edgeSelection.empty();
2485 }
2486 bool isSelected() const {
2487         return m_selectable.isSelected();
2488 }
2489
2490 bool selectedComponents() const {
2491         return selectedVertices() || selectedEdges() || isSelected();
2492 }
2493 bool selectedComponents( SelectionSystem::EComponentMode mode ) const {
2494         switch ( mode )
2495         {
2496         case SelectionSystem::eVertex:
2497                 return selectedVertices();
2498         case SelectionSystem::eEdge:
2499                 return selectedEdges();
2500         case SelectionSystem::eFace:
2501                 return isSelected();
2502         default:
2503                 return false;
2504         }
2505 }
2506 void setSelected( SelectionSystem::EComponentMode mode, bool select ){
2507         switch ( mode )
2508         {
2509         case SelectionSystem::eFace:
2510                 m_selectable.setSelected( select );
2511                 break;
2512         case SelectionSystem::eVertex:
2513                 ASSERT_MESSAGE( !select, "select-all not supported" );
2514
2515                 m_vertexSelection.clear();
2516                 m_selectableVertices.setSelected( false );
2517                 break;
2518         case SelectionSystem::eEdge:
2519                 ASSERT_MESSAGE( !select, "select-all not supported" );
2520
2521                 m_edgeSelection.clear();
2522                 m_selectableEdges.setSelected( false );
2523                 break;
2524         default:
2525                 break;
2526         }
2527 }
2528
2529 template<typename Functor>
2530 void SelectedVertices_foreach( Functor functor ) const {
2531         for ( VertexSelection::const_iterator i = m_vertexSelection.begin(); i != m_vertexSelection.end(); ++i )
2532         {
2533                 std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *i );
2534                 if ( index != c_brush_maxFaces ) {
2535                         functor( getFace().getWinding()[index].vertex );
2536                 }
2537         }
2538 }
2539 template<typename Functor>
2540 void SelectedEdges_foreach( Functor functor ) const {
2541         for ( VertexSelection::const_iterator i = m_edgeSelection.begin(); i != m_edgeSelection.end(); ++i )
2542         {
2543                 std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *i );
2544                 if ( index != c_brush_maxFaces ) {
2545                         const Winding& winding = getFace().getWinding();
2546                         std::size_t adjacent = Winding_next( winding, index );
2547                         functor( vector3_mid( winding[index].vertex, winding[adjacent].vertex ) );
2548                 }
2549         }
2550 }
2551 template<typename Functor>
2552 void SelectedFaces_foreach( Functor functor ) const {
2553         if ( isSelected() ) {
2554                 functor( centroid() );
2555         }
2556 }
2557
2558 template<typename Functor>
2559 void SelectedComponents_foreach( Functor functor ) const {
2560         SelectedVertices_foreach( functor );
2561         SelectedEdges_foreach( functor );
2562         SelectedFaces_foreach( functor );
2563 }
2564
2565 void iterate_selected( AABB& aabb ) const {
2566         SelectedComponents_foreach( AABBExtendByPoint( aabb ) );
2567 }
2568
2569 class RenderablePointVectorPushBack
2570 {
2571 RenderablePointVector& m_points;
2572 public:
2573 RenderablePointVectorPushBack( RenderablePointVector& points ) : m_points( points ){
2574 }
2575 void operator()( const Vector3& point ) const {
2576         const Colour4b colour_selected( 0, 0, 255, 255 );
2577         m_points.push_back( pointvertex_for_windingpoint( point, colour_selected ) );
2578 }
2579 };
2580
2581 void iterate_selected( RenderablePointVector& points ) const {
2582         SelectedComponents_foreach( RenderablePointVectorPushBack( points ) );
2583 }
2584
2585 bool intersectVolume( const VolumeTest& volume, const Matrix4& localToWorld ) const {
2586         return m_face->intersectVolume( volume, localToWorld );
2587 }
2588
2589 void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
2590         if ( !m_face->isFiltered() && m_face->contributes() && intersectVolume( volume, localToWorld ) ) {
2591                 renderer.PushState();
2592                 if ( selectedComponents() ) {
2593                         renderer.Highlight( Renderer::eFace );
2594                 }
2595                 m_face->render( renderer, localToWorld );
2596                 renderer.PopState();
2597         }
2598 }
2599
2600 void testSelect( SelectionTest& test, SelectionIntersection& best ){
2601         if ( !m_face->isFiltered() ) {
2602                 m_face->testSelect( test, best );
2603         }
2604 }
2605 void testSelect( Selector& selector, SelectionTest& test ){
2606         SelectionIntersection best;
2607         testSelect( test, best );
2608         if ( best.valid() ) {
2609                 Selector_add( selector, m_selectable, best );
2610         }
2611 }
2612 void testSelect_centroid( Selector& selector, SelectionTest& test ){
2613         if ( m_face->contributes() && !m_face->isFiltered() ) {
2614                 SelectionIntersection best;
2615                 m_face->testSelect_centroid( test, best );
2616                 if ( best.valid() ) {
2617                         Selector_add( selector, m_selectable, best );
2618                 }
2619         }
2620 }
2621
2622 void selectPlane( Selector& selector, const Line& line, const PlaneCallback& selectedPlaneCallback ){
2623         for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i )
2624         {
2625                 Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
2626                 double dot = vector3_dot( getFace().plane3().normal(), v );
2627                 if ( dot <= 0 ) {
2628                         return;
2629                 }
2630         }
2631
2632         Selector_add( selector, m_selectable );
2633
2634         selectedPlaneCallback( getFace().plane3() );
2635 }
2636 void selectReversedPlane( Selector& selector, const SelectedPlanes& selectedPlanes ){
2637         if ( selectedPlanes.contains( plane3_flipped( getFace().plane3() ) ) ) {
2638                 Selector_add( selector, m_selectable );
2639         }
2640 }
2641
2642 bool trySelectPlane( const Line& line ){
2643         for ( Winding::const_iterator i = getFace().getWinding().begin(); i != getFace().getWinding().end(); ++i ){
2644                 Vector3 v( vector3_subtracted( line_closest_point( line, ( *i ).vertex ), ( *i ).vertex ) );
2645                 double dot = vector3_dot( getFace().plane3().normal(), v );
2646                 if ( dot <= 0 ) {
2647                         return false;
2648                 }
2649         }
2650         return true;
2651 }
2652
2653 void transformComponents( const Matrix4& matrix ){
2654         if ( isSelected() ) {
2655                 m_face->transform( matrix, false );
2656         }
2657         if ( selectedVertices() ) {
2658                 if ( m_vertexSelection.size() == 1 ) {
2659                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2660                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2661                 }
2662                 else if ( m_vertexSelection.size() == 2 ) {
2663                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2664                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2665                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2666                 }
2667                 else if ( m_vertexSelection.size() >= 3 ) {
2668                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2669                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2670                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2671                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2672                 }
2673         }
2674         if ( selectedEdges() ) {
2675                 if ( m_edgeSelection.size() == 1 ) {
2676                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2677                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2678                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2679                 }
2680                 else if ( m_edgeSelection.size() >= 2 ) {
2681                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[0] );
2682                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[1] );
2683                         matrix4_transform_point( matrix, m_face->m_move_planeptsTransformed[2] );
2684                         m_face->assign_planepts( m_face->m_move_planeptsTransformed );
2685                 }
2686         }
2687 }
2688
2689 void snapto( float snap ){
2690         m_face->snapto( snap );
2691 }
2692
2693 void snapComponents( float snap ){
2694         if ( isSelected() ) {
2695                 snapto( snap );
2696         }
2697         if ( selectedVertices() ) {
2698                 vector3_snap( m_face->m_move_planepts[0], snap );
2699                 vector3_snap( m_face->m_move_planepts[1], snap );
2700                 vector3_snap( m_face->m_move_planepts[2], snap );
2701                 m_face->assign_planepts( m_face->m_move_planepts );
2702                 planepts_assign( m_face->m_move_planeptsTransformed, m_face->m_move_planepts );
2703                 m_face->freezeTransform();
2704         }
2705         if ( selectedEdges() ) {
2706                 vector3_snap( m_face->m_move_planepts[0], snap );
2707                 vector3_snap( m_face->m_move_planepts[1], snap );
2708                 vector3_snap( m_face->m_move_planepts[2], snap );
2709                 m_face->assign_planepts( m_face->m_move_planepts );
2710                 planepts_assign( m_face->m_move_planeptsTransformed, m_face->m_move_planepts );
2711                 m_face->freezeTransform();
2712         }
2713 }
2714 void update_move_planepts_vertex( std::size_t index ){
2715         m_face->update_move_planepts_vertex( index, m_face->m_move_planepts );
2716 }
2717 void update_move_planepts_vertex2( std::size_t index, std::size_t other ){
2718         const std::size_t numpoints = m_face->getWinding().numpoints;
2719         ASSERT_MESSAGE( index < numpoints, "select_vertex: invalid index" );
2720
2721         const std::size_t opposite = Winding_Opposite( m_face->getWinding(), index, other );
2722
2723         if ( triangle_reversed( index, other, opposite ) ) {
2724                 std::swap( index, other );
2725         }
2726
2727         ASSERT_MESSAGE(
2728                 triangles_same_winding(
2729                         m_face->getWinding()[opposite].vertex,
2730                         m_face->getWinding()[index].vertex,
2731                         m_face->getWinding()[other].vertex,
2732                         m_face->getWinding()[0].vertex,
2733                         m_face->getWinding()[1].vertex,
2734                         m_face->getWinding()[2].vertex
2735                         ),
2736                 "update_move_planepts_vertex2: error"
2737                 );
2738
2739         m_face->m_move_planepts[0] = m_face->getWinding()[opposite].vertex;
2740         m_face->m_move_planepts[1] = m_face->getWinding()[index].vertex;
2741         m_face->m_move_planepts[2] = m_face->getWinding()[other].vertex;
2742         planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
2743 }
2744 void update_selection_vertex(){
2745         if ( m_vertexSelection.size() == 0 ) {
2746                 m_selectableVertices.setSelected( false );
2747         }
2748         else
2749         {
2750                 m_selectableVertices.setSelected( true );
2751
2752                 if ( m_vertexSelection.size() == 1 ) {
2753                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_vertexSelection.begin() );
2754
2755                         if ( index != c_brush_maxFaces ) {
2756                                 update_move_planepts_vertex( index );
2757                         }
2758                 }
2759                 else if ( m_vertexSelection.size() == 2 ) {
2760                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_vertexSelection.begin() );
2761                         std::size_t other = Winding_FindAdjacent( getFace().getWinding(), *( ++m_vertexSelection.begin() ) );
2762
2763                         if ( index != c_brush_maxFaces
2764                                  && other != c_brush_maxFaces ) {
2765                                 update_move_planepts_vertex2( index, other );
2766                         }
2767                 }
2768         }
2769 }
2770 void select_vertex( std::size_t index, bool select ){
2771         if ( select ) {
2772                 VertexSelection_insert( m_vertexSelection, getFace().getWinding()[index].adjacent );
2773         }
2774         else
2775         {
2776                 VertexSelection_erase( m_vertexSelection, getFace().getWinding()[index].adjacent );
2777         }
2778
2779         SceneChangeNotify();
2780         update_selection_vertex();
2781 }
2782
2783 bool selected_vertex( std::size_t index ) const {
2784         return VertexSelection_find( m_vertexSelection, getFace().getWinding()[index].adjacent ) != m_vertexSelection.end();
2785 }
2786
2787 void update_move_planepts_edge( std::size_t index ){
2788         std::size_t numpoints = m_face->getWinding().numpoints;
2789         ASSERT_MESSAGE( index < numpoints, "select_edge: invalid index" );
2790
2791         std::size_t adjacent = Winding_next( m_face->getWinding(), index );
2792         std::size_t opposite = Winding_Opposite( m_face->getWinding(), index );
2793         m_face->m_move_planepts[0] = m_face->getWinding()[index].vertex;
2794         m_face->m_move_planepts[1] = m_face->getWinding()[adjacent].vertex;
2795         m_face->m_move_planepts[2] = m_face->getWinding()[opposite].vertex;
2796         planepts_quantise( m_face->m_move_planepts, GRID_MIN ); // winding points are very inaccurate
2797 }
2798 void update_selection_edge(){
2799         if ( m_edgeSelection.size() == 0 ) {
2800                 m_selectableEdges.setSelected( false );
2801         }
2802         else
2803         {
2804                 m_selectableEdges.setSelected( true );
2805
2806                 if ( m_edgeSelection.size() == 1 ) {
2807                         std::size_t index = Winding_FindAdjacent( getFace().getWinding(), *m_edgeSelection.begin() );
2808
2809                         if ( index != c_brush_maxFaces ) {
2810                                 update_move_planepts_edge( index );
2811                         }
2812                 }
2813         }
2814 }
2815 void select_edge( std::size_t index, bool select ){
2816         if ( select ) {
2817                 VertexSelection_insert( m_edgeSelection, getFace().getWinding()[index].adjacent );
2818         }
2819         else
2820         {
2821                 VertexSelection_erase( m_edgeSelection, getFace().getWinding()[index].adjacent );
2822         }
2823
2824         SceneChangeNotify();
2825         update_selection_edge();
2826 }
2827
2828 bool selected_edge( std::size_t index ) const {
2829         return VertexSelection_find( m_edgeSelection, getFace().getWinding()[index].adjacent ) != m_edgeSelection.end();
2830 }
2831
2832 const Vector3& centroid() const {
2833         return m_face->centroid();
2834 }
2835
2836 void connectivityChanged(){
2837         // This occurs when a face is added or removed.
2838         // The current vertex and edge selections no longer valid and must be cleared.
2839         m_vertexSelection.clear();
2840         m_selectableVertices.setSelected( false );
2841         m_edgeSelection.clear();
2842         m_selectableEdges.setSelected( false );
2843 }
2844 };
2845
2846 class BrushClipPlane : public OpenGLRenderable
2847 {
2848 Plane3 m_plane;
2849 Winding m_winding;
2850 static Shader* m_state;
2851 public:
2852 static void constructStatic(){
2853         m_state = GlobalShaderCache().capture( "$CLIPPER_OVERLAY" );
2854 }
2855 static void destroyStatic(){
2856         GlobalShaderCache().release( "$CLIPPER_OVERLAY" );
2857 }
2858
2859 void setPlane( const Brush& brush, const Plane3& plane ){
2860         m_plane = plane;
2861         if ( plane3_valid( m_plane ) ) {
2862                 brush.windingForClipPlane( m_winding, m_plane );
2863         }
2864         else
2865         {
2866                 m_winding.resize( 0 );
2867         }
2868 }
2869
2870 void render( RenderStateFlags state ) const {
2871         if ( ( state & RENDER_FILL ) != 0 ) {
2872                 Winding_Draw( m_winding, m_plane.normal(), state );
2873         }
2874         else
2875         {
2876                 Winding_DrawWireframe( m_winding );
2877
2878                 // also draw a line indicating the direction of the cut
2879                 Vector3 lineverts[2];
2880                 Winding_Centroid( m_winding, m_plane, lineverts[0] );
2881                 lineverts[1] = vector3_added( lineverts[0], vector3_scaled( m_plane.normal(), Brush::m_maxWorldCoord * 4 ) );
2882
2883                 glVertexPointer( 3, GL_FLOAT, sizeof( Vector3 ), &lineverts[0] );
2884                 glDrawArrays( GL_LINES, 0, GLsizei( 2 ) );
2885         }
2886 }
2887
2888 void render( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
2889         renderer.SetState( m_state, Renderer::eWireframeOnly );
2890         renderer.SetState( m_state, Renderer::eFullMaterials );
2891         renderer.addRenderable( *this, localToWorld );
2892 }
2893 };
2894
2895 inline void Face_addLight( const FaceInstance& face, const Matrix4& localToWorld, const RendererLight& light ){
2896         const Plane3& facePlane = face.getFace().plane3();
2897         const Vector3& origin = light.aabb().origin;
2898         Plane3 tmp( plane3_transformed( Plane3( facePlane.normal(), -facePlane.dist() ), localToWorld ) );
2899         if ( !plane3_test_point( tmp, origin )
2900                  || !plane3_test_point( tmp, vector3_added( origin, light.offset() ) ) ) {
2901                 face.m_lights.addLight( light );
2902         }
2903 }
2904
2905
2906
2907 typedef std::vector<FaceInstance> FaceInstances;
2908
2909 class EdgeInstance : public Selectable
2910 {
2911 FaceInstances& m_faceInstances;
2912 SelectableEdge* m_edge;
2913
2914 void select_edge( bool select ){
2915         FaceVertexId faceVertex = m_edge->m_faceVertex;
2916         m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select );
2917         faceVertex = next_edge( m_edge->m_faces, faceVertex );
2918         m_faceInstances[faceVertex.getFace()].select_edge( faceVertex.getVertex(), select );
2919 }
2920 bool selected_edge() const {
2921         FaceVertexId faceVertex = m_edge->m_faceVertex;
2922         if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) {
2923                 return false;
2924         }
2925         faceVertex = next_edge( m_edge->m_faces, faceVertex );
2926         if ( !m_faceInstances[faceVertex.getFace()].selected_edge( faceVertex.getVertex() ) ) {
2927                 return false;
2928         }
2929
2930         return true;
2931 }
2932
2933 public:
2934 EdgeInstance( FaceInstances& faceInstances, SelectableEdge& edge )
2935         : m_faceInstances( faceInstances ), m_edge( &edge ){
2936 }
2937 EdgeInstance& operator=( const EdgeInstance& other ){
2938         m_edge = other.m_edge;
2939         return *this;
2940 }
2941
2942 void setSelected( bool select ){
2943         select_edge( select );
2944 }
2945 bool isSelected() const {
2946         return selected_edge();
2947 }
2948
2949
2950 void testSelect( Selector& selector, SelectionTest& test ){
2951         SelectionIntersection best;
2952         m_edge->testSelect( test, best );
2953         if ( best.valid() ) {
2954                 Selector_add( selector, *this, best );
2955         }
2956 }
2957 };
2958
2959 class VertexInstance : public Selectable
2960 {
2961 FaceInstances& m_faceInstances;
2962 SelectableVertex* m_vertex;
2963
2964 void select_vertex( bool select ){
2965         FaceVertexId faceVertex = m_vertex->m_faceVertex;
2966         do
2967         {
2968                 m_faceInstances[faceVertex.getFace()].select_vertex( faceVertex.getVertex(), select );
2969                 faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
2970         }
2971         while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
2972 }
2973 bool selected_vertex() const {
2974         FaceVertexId faceVertex = m_vertex->m_faceVertex;
2975         do
2976         {
2977                 if ( !m_faceInstances[faceVertex.getFace()].selected_vertex( faceVertex.getVertex() ) ) {
2978                         return false;
2979                 }
2980                 faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
2981         }
2982         while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
2983         return true;
2984 }
2985
2986 public:
2987 VertexInstance( FaceInstances& faceInstances, SelectableVertex& vertex )
2988         : m_faceInstances( faceInstances ), m_vertex( &vertex ){
2989 }
2990 VertexInstance& operator=( const VertexInstance& other ){
2991         m_vertex = other.m_vertex;
2992         return *this;
2993 }
2994
2995 void setSelected( bool select ){
2996         select_vertex( select );
2997 }
2998 bool isSelected() const {
2999         return selected_vertex();
3000 }
3001
3002 void testSelect( Selector& selector, SelectionTest& test ){
3003         SelectionIntersection best;
3004         m_vertex->testSelect( test, best );
3005         if ( best.valid() ) {
3006                 Selector_add( selector, *this, best );
3007         }
3008 }
3009
3010 void selectVerticesOnPlanes( SelectionTest& test ){
3011         Line line( test.getNear(), test.getFar() );
3012         FaceVertexId faceVertex = m_vertex->m_faceVertex;
3013         do
3014         {
3015                 if( m_faceInstances[faceVertex.getFace()].trySelectPlane( line ) ){
3016                         //m_faceInstances[faceVertex.getFace()].select_vertex( faceVertex.getVertex(), true );
3017                         setSelected( true );
3018                 }
3019                 faceVertex = next_vertex( m_vertex->m_faces, faceVertex );
3020         }
3021         while ( faceVertex.getFace() != m_vertex->m_faceVertex.getFace() );
3022 }
3023 };
3024
3025 class BrushInstanceVisitor
3026 {
3027 public:
3028 virtual void visit( FaceInstance& face ) const = 0;
3029 };
3030
3031 class BrushInstance :
3032         public BrushObserver,
3033         public scene::Instance,
3034         public Selectable,
3035         public Renderable,
3036         public SelectionTestable,
3037         public ComponentSelectionTestable,
3038         public ComponentEditable,
3039         public ComponentSnappable,
3040         public PlaneSelectable,
3041         public LightCullable
3042 {
3043 class TypeCasts
3044 {
3045 InstanceTypeCastTable m_casts;
3046 public:
3047 TypeCasts(){
3048         InstanceStaticCast<BrushInstance, Selectable>::install( m_casts );
3049         InstanceContainedCast<BrushInstance, Bounded>::install( m_casts );
3050         InstanceContainedCast<BrushInstance, Cullable>::install( m_casts );
3051         InstanceStaticCast<BrushInstance, Renderable>::install( m_casts );
3052         InstanceStaticCast<BrushInstance, SelectionTestable>::install( m_casts );
3053         InstanceStaticCast<BrushInstance, ComponentSelectionTestable>::install( m_casts );
3054         InstanceStaticCast<BrushInstance, ComponentEditable>::install( m_casts );
3055         InstanceStaticCast<BrushInstance, ComponentSnappable>::install( m_casts );
3056         InstanceStaticCast<BrushInstance, PlaneSelectable>::install( m_casts );
3057         InstanceIdentityCast<BrushInstance>::install( m_casts );
3058         InstanceContainedCast<BrushInstance, Transformable>::install( m_casts );
3059 }
3060 InstanceTypeCastTable& get(){
3061         return m_casts;
3062 }
3063 };
3064
3065
3066 Brush& m_brush;
3067
3068 FaceInstances m_faceInstances;
3069
3070 typedef std::vector<EdgeInstance> EdgeInstances;
3071 EdgeInstances m_edgeInstances;
3072 typedef std::vector<VertexInstance> VertexInstances;
3073 VertexInstances m_vertexInstances;
3074
3075 ObservedSelectable m_selectable;
3076
3077 mutable RenderableWireframe m_render_wireframe;
3078 mutable RenderablePointVector m_render_selected;
3079 mutable AABB m_aabb_component;
3080 mutable Array<PointVertex> m_faceCentroidPointsCulled;
3081 RenderablePointArray m_render_faces_wireframe;
3082 mutable bool m_viewChanged;   // requires re-evaluation of view-dependent cached data
3083
3084 BrushClipPlane m_clipPlane;
3085
3086 static Shader* m_state_selpoint;
3087
3088 const LightList* m_lightList;
3089
3090 TransformModifier m_transform;
3091
3092 BrushInstance( const BrushInstance& other ); // NOT COPYABLE
3093 BrushInstance& operator=( const BrushInstance& other ); // NOT ASSIGNABLE
3094 public:
3095 static Counter* m_counter;
3096
3097 typedef LazyStatic<TypeCasts> StaticTypeCasts;
3098
3099 void lightsChanged(){
3100         m_lightList->lightsChanged();
3101 }
3102 typedef MemberCaller<BrushInstance, &BrushInstance::lightsChanged> LightsChangedCaller;
3103
3104 STRING_CONSTANT( Name, "BrushInstance" );
3105
3106 BrushInstance( const scene::Path& path, scene::Instance* parent, Brush& brush ) :
3107         Instance( path, parent, this, StaticTypeCasts::instance().get() ),
3108         m_brush( brush ),
3109         m_selectable( SelectedChangedCaller( *this ) ),
3110         m_render_selected( GL_POINTS ),
3111         m_render_faces_wireframe( m_faceCentroidPointsCulled, GL_POINTS ),
3112         m_viewChanged( false ),
3113         m_transform( Brush::TransformChangedCaller( m_brush ), ApplyTransformCaller( *this ) ){
3114         m_brush.instanceAttach( Instance::path() );
3115         m_brush.attach( *this );
3116         m_counter->increment();
3117
3118         m_lightList = &GlobalShaderCache().attach( *this );
3119         m_brush.m_lightsChanged = LightsChangedCaller( *this ); ///\todo Make this work with instancing.
3120
3121         Instance::setTransformChangedCallback( LightsChangedCaller( *this ) );
3122 }
3123 ~BrushInstance(){
3124         Instance::setTransformChangedCallback( Callback() );
3125
3126         m_brush.m_lightsChanged = Callback();
3127         GlobalShaderCache().detach( *this );
3128
3129         m_counter->decrement();
3130         m_brush.detach( *this );
3131         m_brush.instanceDetach( Instance::path() );
3132 }
3133
3134 Brush& getBrush(){
3135         return m_brush;
3136 }
3137 const Brush& getBrush() const {
3138         return m_brush;
3139 }
3140
3141 Bounded& get( NullType<Bounded>){
3142         return m_brush;
3143 }
3144 Cullable& get( NullType<Cullable>){
3145         return m_brush;
3146 }
3147 Transformable& get( NullType<Transformable>){
3148         return m_transform;
3149 }
3150
3151 void selectedChanged( const Selectable& selectable ){
3152         GlobalSelectionSystem().getObserver ( SelectionSystem::ePrimitive )( selectable );
3153         GlobalSelectionSystem().onSelectedChanged( *this, selectable );
3154
3155         Instance::selectedChanged();
3156 }
3157 typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChanged> SelectedChangedCaller;
3158
3159 void selectedChangedComponent( const Selectable& selectable ){
3160         GlobalSelectionSystem().getObserver ( SelectionSystem::eComponent )( selectable );
3161         GlobalSelectionSystem().onComponentSelection( *this, selectable );
3162 }
3163 typedef MemberCaller1<BrushInstance, const Selectable&, &BrushInstance::selectedChangedComponent> SelectedChangedComponentCaller;
3164
3165 const BrushInstanceVisitor& forEachFaceInstance( const BrushInstanceVisitor& visitor ){
3166         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3167         {
3168                 visitor.visit( *i );
3169         }
3170         return visitor;
3171 }
3172
3173 static void constructStatic(){
3174         m_state_selpoint = GlobalShaderCache().capture( "$SELPOINT" );
3175 }
3176 static void destroyStatic(){
3177         GlobalShaderCache().release( "$SELPOINT" );
3178 }
3179
3180 void clear(){
3181         m_faceInstances.clear();
3182 }
3183 void reserve( std::size_t size ){
3184         m_faceInstances.reserve( size );
3185 }
3186
3187 void push_back( Face& face ){
3188         m_faceInstances.push_back( FaceInstance( face, SelectedChangedComponentCaller( *this ) ) );
3189 }
3190 void pop_back(){
3191         ASSERT_MESSAGE( !m_faceInstances.empty(), "erasing invalid element" );
3192         m_faceInstances.pop_back();
3193 }
3194 void erase( std::size_t index ){
3195         ASSERT_MESSAGE( index < m_faceInstances.size(), "erasing invalid element" );
3196         m_faceInstances.erase( m_faceInstances.begin() + index );
3197 }
3198 void connectivityChanged(){
3199         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3200         {
3201                 ( *i ).connectivityChanged();
3202         }
3203 }
3204
3205 void edge_clear(){
3206         m_edgeInstances.clear();
3207 }
3208 void edge_push_back( SelectableEdge& edge ){
3209         m_edgeInstances.push_back( EdgeInstance( m_faceInstances, edge ) );
3210 }
3211
3212 void vertex_clear(){
3213         m_vertexInstances.clear();
3214 }
3215 void vertex_push_back( SelectableVertex& vertex ){
3216         m_vertexInstances.push_back( VertexInstance( m_faceInstances, vertex ) );
3217 }
3218
3219 void DEBUG_verify() const {
3220         ASSERT_MESSAGE( m_faceInstances.size() == m_brush.DEBUG_size(), "FATAL: mismatch" );
3221 }
3222
3223 bool isSelected() const {
3224         return m_selectable.isSelected();
3225 }
3226 void setSelected( bool select ){
3227         m_selectable.setSelected( select );
3228         if ( !select && parent() ){
3229                 Selectable* sel_parent = Instance_getSelectable( *parent() );
3230                 if ( sel_parent && sel_parent->isSelected() )
3231                         sel_parent->setSelected( false );
3232         }
3233 }
3234
3235 void update_selected() const {
3236         m_render_selected.clear();
3237         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3238         {
3239                 if ( ( *i ).getFace().contributes() ) {
3240                         ( *i ).iterate_selected( m_render_selected );
3241                 }
3242         }
3243 }
3244
3245 void evaluateViewDependent( const VolumeTest& volume, const Matrix4& localToWorld ) const {
3246         if ( m_viewChanged ) {
3247                 m_viewChanged = false;
3248
3249                 bool faces_visible[c_brush_maxFaces];
3250                 {
3251                         bool* j = faces_visible;
3252                         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i, ++j )
3253                         {
3254                                 *j = ( *i ).intersectVolume( volume, localToWorld );
3255                         }
3256                 }
3257
3258                 m_brush.update_wireframe( m_render_wireframe, faces_visible );
3259                 m_brush.update_faces_wireframe( m_faceCentroidPointsCulled, faces_visible );
3260         }
3261 }
3262
3263 void renderComponentsSelected( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3264         m_brush.evaluateBRep();
3265
3266         update_selected();
3267         if ( !m_render_selected.empty() ) {
3268                 renderer.Highlight( Renderer::ePrimitive, false );
3269                 renderer.SetState( m_state_selpoint, Renderer::eWireframeOnly );
3270                 renderer.SetState( m_state_selpoint, Renderer::eFullMaterials );
3271                 renderer.addRenderable( m_render_selected, localToWorld );
3272         }
3273 }
3274
3275 void renderComponents( Renderer& renderer, const VolumeTest& volume ) const {
3276         m_brush.evaluateBRep();
3277
3278         const Matrix4& localToWorld = Instance::localToWorld();
3279
3280         renderer.SetState( m_brush.m_state_point, Renderer::eWireframeOnly );
3281         renderer.SetState( m_brush.m_state_point, Renderer::eFullMaterials );
3282
3283         if ( volume.fill() && GlobalSelectionSystem().ComponentMode() == SelectionSystem::eFace ) {
3284                 evaluateViewDependent( volume, localToWorld );
3285                 renderer.addRenderable( m_render_faces_wireframe, localToWorld );
3286         }
3287         else
3288         {
3289                 m_brush.renderComponents( GlobalSelectionSystem().ComponentMode(), renderer, volume, localToWorld );
3290         }
3291 }
3292
3293 void renderClipPlane( Renderer& renderer, const VolumeTest& volume ) const {
3294         if ( GlobalSelectionSystem().ManipulatorMode() == SelectionSystem::eClip && isSelected() ) {
3295                 m_clipPlane.render( renderer, volume, localToWorld() );
3296         }
3297 }
3298
3299 void renderCommon( Renderer& renderer, const VolumeTest& volume ) const {
3300         bool componentMode = GlobalSelectionSystem().Mode() == SelectionSystem::eComponent;
3301
3302         if ( componentMode && isSelected() ) {
3303                 renderComponents( renderer, volume );
3304         }
3305
3306         if ( parentSelected() ) {
3307                 if ( !componentMode ) {
3308                         renderer.Highlight( Renderer::eFace );
3309                 }
3310                 renderer.Highlight( Renderer::ePrimitive );
3311         }
3312 }
3313
3314 void renderSolid( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3315         //renderCommon(renderer, volume);
3316
3317         m_lightList->evaluateLights();
3318
3319         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3320         {
3321                 renderer.setLights( ( *i ).m_lights );
3322                 ( *i ).render( renderer, volume, localToWorld );
3323         }
3324
3325         renderComponentsSelected( renderer, volume, localToWorld );
3326 }
3327
3328 void renderWireframe( Renderer& renderer, const VolumeTest& volume, const Matrix4& localToWorld ) const {
3329         //renderCommon(renderer, volume);
3330
3331         evaluateViewDependent( volume, localToWorld );
3332
3333         if ( m_render_wireframe.m_size != 0 ) {
3334                 renderer.addRenderable( m_render_wireframe, localToWorld );
3335         }
3336
3337         renderComponentsSelected( renderer, volume, localToWorld );
3338 }
3339
3340 void renderSolid( Renderer& renderer, const VolumeTest& volume ) const {
3341         m_brush.evaluateBRep();
3342
3343         renderClipPlane( renderer, volume );
3344
3345         renderSolid( renderer, volume, localToWorld() );
3346 }
3347
3348 void renderWireframe( Renderer& renderer, const VolumeTest& volume ) const {
3349         m_brush.evaluateBRep();
3350
3351         renderClipPlane( renderer, volume );
3352
3353         renderWireframe( renderer, volume, localToWorld() );
3354 }
3355
3356 void viewChanged() const {
3357         m_viewChanged = true;
3358 }
3359
3360 void testSelect( Selector& selector, SelectionTest& test ){
3361         test.BeginMesh( localToWorld() );
3362
3363         SelectionIntersection best;
3364         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3365         {
3366                 ( *i ).testSelect( test, best );
3367         }
3368         if ( best.valid() ) {
3369                 selector.addIntersection( best );
3370         }
3371 }
3372
3373 bool isSelectedComponents() const {
3374         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3375         {
3376                 if ( ( *i ).selectedComponents() ) {
3377                         return true;
3378                 }
3379         }
3380         return false;
3381 }
3382 void setSelectedComponents( bool select, SelectionSystem::EComponentMode mode ){
3383         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3384         {
3385                 ( *i ).setSelected( mode, select );
3386         }
3387 }
3388 void testSelectComponents( Selector& selector, SelectionTest& test, SelectionSystem::EComponentMode mode ){
3389         test.BeginMesh( localToWorld() );
3390
3391         switch ( mode )
3392         {
3393         case SelectionSystem::eVertex:
3394         {
3395                 for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i )
3396                 {
3397                         ( *i ).testSelect( selector, test );
3398                 }
3399         }
3400         break;
3401         case SelectionSystem::eEdge:
3402         {
3403                 for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
3404                 {
3405                         ( *i ).testSelect( selector, test );
3406                 }
3407         }
3408         break;
3409         case SelectionSystem::eFace:
3410         {
3411                 if ( test.getVolume().fill() ) {
3412                         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3413                         {
3414                                 ( *i ).testSelect( selector, test );
3415                         }
3416                 }
3417                 else
3418                 {
3419                         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3420                         {
3421                                 ( *i ).testSelect_centroid( selector, test );
3422                         }
3423                 }
3424         }
3425         break;
3426         default:
3427                 break;
3428         }
3429 }
3430
3431 void invertComponentSelection( SelectionSystem::EComponentMode mode ){
3432         switch ( mode )
3433         {
3434         case SelectionSystem::eVertex:
3435         {
3436                 for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i )
3437                 {
3438                         ( *i ).setSelected( !( *i ).isSelected() );
3439                 }
3440         }
3441         break;
3442         case SelectionSystem::eEdge:
3443         {
3444                 for ( EdgeInstances::iterator i = m_edgeInstances.begin(); i != m_edgeInstances.end(); ++i )
3445                 {
3446                         ( *i ).setSelected( !( *i ).isSelected() );
3447                 }
3448         }
3449         break;
3450         case SelectionSystem::eFace:
3451         {
3452                 for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3453                 {
3454                         if( !( *i ).getFace().isFiltered() )
3455                                 ( *i ).setSelected( mode, !( *i ).isSelected() );
3456                 }
3457         }
3458         break;
3459         default:
3460                 break;
3461         }
3462 }
3463
3464 void selectPlanes( Selector& selector, SelectionTest& test, const PlaneCallback& selectedPlaneCallback ){
3465         test.BeginMesh( localToWorld() );
3466
3467         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3468         {
3469                 ( *i ).selectPlane( selector, Line( test.getNear(), test.getFar() ), selectedPlaneCallback );
3470         }
3471 }
3472 void selectReversedPlanes( Selector& selector, const SelectedPlanes& selectedPlanes ){
3473         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3474         {
3475                 ( *i ).selectReversedPlane( selector, selectedPlanes );
3476         }
3477 }
3478
3479
3480 void selectVerticesOnPlanes( SelectionTest& test ){
3481         test.BeginMesh( localToWorld() );
3482
3483         for ( VertexInstances::iterator i = m_vertexInstances.begin(); i != m_vertexInstances.end(); ++i ){
3484                 ( *i ).selectVerticesOnPlanes( test );
3485         }
3486 }
3487
3488
3489 void transformComponents( const Matrix4& matrix ){
3490         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3491         {
3492                 ( *i ).transformComponents( matrix );
3493         }
3494 }
3495 const AABB& getSelectedComponentsBounds() const {
3496         m_aabb_component = AABB();
3497
3498         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3499         {
3500                 ( *i ).iterate_selected( m_aabb_component );
3501         }
3502
3503         return m_aabb_component;
3504 }
3505
3506 void snapComponents( float snap ){
3507         for ( FaceInstances::iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3508         {
3509                 ( *i ).snapComponents( snap );
3510         }
3511 }
3512 void evaluateTransform(){
3513         Matrix4 matrix( m_transform.calculateTransform() );
3514         //globalOutputStream() << "matrix: " << matrix << "\n";
3515
3516         if ( m_transform.getType() == TRANSFORM_PRIMITIVE ) {
3517                 m_brush.transform( matrix );
3518         }
3519         else
3520         {
3521                 transformComponents( matrix );
3522         }
3523 }
3524 void applyTransform(){
3525         m_brush.revertTransform();
3526         evaluateTransform();
3527         m_brush.freezeTransform();
3528 }
3529 typedef MemberCaller<BrushInstance, &BrushInstance::applyTransform> ApplyTransformCaller;
3530
3531 void setClipPlane( const Plane3& plane ){
3532         m_clipPlane.setPlane( m_brush, plane );
3533 }
3534
3535 bool testLight( const RendererLight& light ) const {
3536         return light.testAABB( worldAABB() );
3537 }
3538 void insertLight( const RendererLight& light ){
3539         const Matrix4& localToWorld = Instance::localToWorld();
3540         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3541         {
3542                 Face_addLight( *i, localToWorld, light );
3543         }
3544 }
3545 void clearLights(){
3546         for ( FaceInstances::const_iterator i = m_faceInstances.begin(); i != m_faceInstances.end(); ++i )
3547         {
3548                 ( *i ).m_lights.clear();
3549         }
3550 }
3551 };
3552
3553 inline BrushInstance* Instance_getBrush( scene::Instance& instance ){
3554         return InstanceTypeCast<BrushInstance>::cast( instance );
3555 }
3556
3557
3558 template<typename Functor>
3559 class BrushSelectedVisitor : public SelectionSystem::Visitor
3560 {
3561 const Functor& m_functor;
3562 public:
3563 BrushSelectedVisitor( const Functor& functor ) : m_functor( functor ){
3564 }
3565 void visit( scene::Instance& instance ) const {
3566         BrushInstance* brush = Instance_getBrush( instance );
3567         if ( brush != 0 ) {
3568                 m_functor( *brush );
3569         }
3570 }
3571 };
3572
3573 template<typename Functor>
3574 inline const Functor& Scene_forEachSelectedBrush( const Functor& functor ){
3575         GlobalSelectionSystem().foreachSelected( BrushSelectedVisitor<Functor>( functor ) );
3576         return functor;
3577 }
3578
3579 template<typename Functor>
3580 class BrushVisibleSelectedVisitor : public SelectionSystem::Visitor
3581 {
3582 const Functor& m_functor;
3583 public:
3584 BrushVisibleSelectedVisitor( const Functor& functor ) : m_functor( functor ){
3585 }
3586 void visit( scene::Instance& instance ) const {
3587         BrushInstance* brush = Instance_getBrush( instance );
3588         if ( brush != 0
3589                  && instance.path().top().get().visible() ) {
3590                 m_functor( *brush );
3591         }
3592 }
3593 };
3594
3595 template<typename Functor>
3596 inline const Functor& Scene_forEachVisibleSelectedBrush( const Functor& functor ){
3597         GlobalSelectionSystem().foreachSelected( BrushVisibleSelectedVisitor<Functor>( functor ) );
3598         return functor;
3599 }
3600
3601 class BrushForEachFace
3602 {
3603 const BrushInstanceVisitor& m_visitor;
3604 public:
3605 BrushForEachFace( const BrushInstanceVisitor& visitor ) : m_visitor( visitor ){
3606 }
3607 void operator()( BrushInstance& brush ) const {
3608         brush.forEachFaceInstance( m_visitor );
3609 }
3610 };
3611
3612 template<class Functor>
3613 class FaceInstanceVisitFace : public BrushInstanceVisitor
3614 {
3615 const Functor& functor;
3616 public:
3617 FaceInstanceVisitFace( const Functor& functor )
3618         : functor( functor ){
3619 }
3620 void visit( FaceInstance& face ) const {
3621         functor( face.getFace() );
3622 }
3623 };
3624
3625 template<typename Functor>
3626 inline const Functor& Brush_forEachFace( BrushInstance& brush, const Functor& functor ){
3627         brush.forEachFaceInstance( FaceInstanceVisitFace<Functor>( functor ) );
3628         return functor;
3629 }
3630
3631 template<class Functor>
3632 class FaceVisitAll : public BrushVisitor
3633 {
3634 const Functor& functor;
3635 public:
3636 FaceVisitAll( const Functor& functor )
3637         : functor( functor ){
3638 }
3639 void visit( Face& face ) const {
3640         functor( face );
3641 }
3642 };
3643
3644 template<typename Functor>
3645 inline const Functor& Brush_forEachFace( const Brush& brush, const Functor& functor ){
3646         brush.forEachFace( FaceVisitAll<Functor>( functor ) );
3647         return functor;
3648 }
3649
3650 template<typename Functor>
3651 inline const Functor& Brush_forEachFace( Brush& brush, const Functor& functor ){
3652         brush.forEachFace( FaceVisitAll<Functor>( functor ) );
3653         return functor;
3654 }
3655
3656 template<class Functor>
3657 class FaceInstanceVisitAll : public BrushInstanceVisitor
3658 {
3659 const Functor& functor;
3660 public:
3661 FaceInstanceVisitAll( const Functor& functor )
3662         : functor( functor ){
3663 }
3664 void visit( FaceInstance& face ) const {
3665         functor( face );
3666 }
3667 };
3668
3669 template<typename Functor>
3670 inline const Functor& Brush_ForEachFaceInstance( BrushInstance& brush, const Functor& functor ){
3671         brush.forEachFaceInstance( FaceInstanceVisitAll<Functor>( functor ) );
3672         return functor;
3673 }
3674
3675 template<typename Functor>
3676 inline const Functor& Scene_forEachBrush( scene::Graph& graph, const Functor& functor ){
3677         graph.traverse( InstanceWalker< InstanceApply<BrushInstance, Functor> >( functor ) );
3678         return functor;
3679 }
3680
3681 template<typename Type, typename Functor>
3682 class InstanceIfVisible : public Functor
3683 {
3684 public:
3685 InstanceIfVisible( const Functor& functor ) : Functor( functor ){
3686 }
3687 void operator()( scene::Instance& instance ){
3688         if ( instance.path().top().get().visible() ) {
3689                 Functor::operator()( instance );
3690         }
3691 }
3692 };
3693
3694 template<typename Functor>
3695 class BrushVisibleWalker : public scene::Graph::Walker
3696 {
3697 const Functor& m_functor;
3698 public:
3699 BrushVisibleWalker( const Functor& functor ) : m_functor( functor ){
3700 }
3701 bool pre( const scene::Path& path, scene::Instance& instance ) const {
3702         if ( path.top().get().visible() ) {
3703                 BrushInstance* brush = Instance_getBrush( instance );
3704                 if ( brush != 0 ) {
3705                         m_functor( *brush );
3706                 }
3707         }
3708         return true;
3709 }
3710 };
3711
3712 template<typename Functor>
3713 inline const Functor& Scene_forEachVisibleBrush( scene::Graph& graph, const Functor& functor ){
3714         graph.traverse( BrushVisibleWalker<Functor>( functor ) );
3715         return functor;
3716 }
3717
3718 template<typename Functor>
3719 inline const Functor& Scene_ForEachBrush_ForEachFace( scene::Graph& graph, const Functor& functor ){
3720         Scene_forEachBrush( graph, BrushForEachFace( FaceInstanceVisitFace<Functor>( functor ) ) );
3721         return functor;
3722 }
3723
3724 // d1223m
3725 template<typename Functor>
3726 inline const Functor& Scene_ForEachBrush_ForEachFaceInstance( scene::Graph& graph, const Functor& functor ){
3727         Scene_forEachBrush( graph, BrushForEachFace( FaceInstanceVisitAll<Functor>( functor ) ) );
3728         return functor;
3729 }
3730
3731 template<typename Functor>
3732 inline const Functor& Scene_ForEachSelectedBrush_ForEachFace( scene::Graph& graph, const Functor& functor ){
3733         Scene_forEachSelectedBrush( BrushForEachFace( FaceInstanceVisitFace<Functor>( functor ) ) );
3734         return functor;
3735 }
3736
3737 template<typename Functor>
3738 inline const Functor& Scene_ForEachSelectedBrush_ForEachFaceInstance( scene::Graph& graph, const Functor& functor ){
3739         Scene_forEachSelectedBrush( BrushForEachFace( FaceInstanceVisitAll<Functor>( functor ) ) );
3740         return functor;
3741 }
3742
3743 template<typename Functor>
3744 class FaceVisitorWrapper
3745 {
3746 const Functor& functor;
3747 public:
3748 FaceVisitorWrapper( const Functor& functor ) : functor( functor ){
3749 }
3750
3751 void operator()( FaceInstance& faceInstance ) const {
3752         functor( faceInstance.getFace() );
3753 }
3754 };
3755
3756 template<typename Functor>
3757 inline const Functor& Scene_ForEachSelectedBrushFace( scene::Graph& graph, const Functor& functor ){
3758         g_SelectedFaceInstances.foreach( FaceVisitorWrapper<Functor>( functor ) );
3759         return functor;
3760 }
3761
3762
3763 #endif