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