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