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