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