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