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