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