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