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