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