2 Copyright (C) 2001-2006, William Joseph.
5 This file is part of GtkRadiant.
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.
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.
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
22 #if !defined( INCLUDED_BRUSHTOKENS_H )
23 #define INCLUDED_BRUSHTOKENS_H
26 #include "stream/stringstream.h"
29 inline bool FaceShader_importContentsFlagsValue( FaceShader& faceShader, Tokeniser& tokeniser ){
30 // parse the optional contents/flags/value
31 RETURN_FALSE_IF_FAIL( Tokeniser_getInteger( tokeniser, faceShader.m_flags.m_contentFlags ) );
32 RETURN_FALSE_IF_FAIL( Tokeniser_getInteger( tokeniser, faceShader.m_flags.m_surfaceFlags ) );
33 RETURN_FALSE_IF_FAIL( Tokeniser_getInteger( tokeniser, faceShader.m_flags.m_value ) );
37 inline bool FaceTexdef_importTokens( FaceTexdef& texdef, Tokeniser& tokeniser ){
39 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.shift[0] ) );
40 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.shift[1] ) );
41 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.rotate ) );
42 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.scale[0] ) );
43 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.scale[1] ) );
45 ASSERT_MESSAGE( texdef_sane( texdef.m_projection.m_texdef ), "FaceTexdef_importTokens: bad texdef" );
49 inline bool FaceTexdef_BP_importTokens( FaceTexdef& texdef, Tokeniser& tokeniser ){
50 // parse alternate texdef
51 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) );
53 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) );
54 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][0] ) );
55 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][1] ) );
56 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][2] ) );
57 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) );
60 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) );
61 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][0] ) );
62 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][1] ) );
63 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][2] ) );
64 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) );
66 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) );
70 inline bool FaceTexdef_HalfLife_importTokens( FaceTexdef& texdef, Tokeniser& tokeniser ){
72 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "[" ) );
73 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_s.x() ) );
74 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_s.y() ) );
75 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_s.z() ) );
76 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.shift[0] ) );
77 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "]" ) );
78 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "[" ) );
79 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_t.x() ) );
80 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_t.y() ) );
81 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_basis_t.z() ) );
82 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.shift[1] ) );
83 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "]" ) );
84 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.rotate ) );
85 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.scale[0] ) );
86 RETURN_FALSE_IF_FAIL( Tokeniser_getFloat( tokeniser, texdef.m_projection.m_texdef.scale[1] ) );
88 texdef.m_projection.m_texdef.rotate = -texdef.m_projection.m_texdef.rotate;
90 ASSERT_MESSAGE( texdef_sane( texdef.m_projection.m_texdef ), "FaceTexdef_importTokens: bad texdef" );
94 inline bool FacePlane_importTokens( FacePlane& facePlane, Tokeniser& tokeniser ){
96 for ( std::size_t i = 0; i < 3; i++ )
98 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) );
99 for ( std::size_t j = 0; j < 3; ++j )
101 RETURN_FALSE_IF_FAIL( Tokeniser_getDouble( tokeniser, facePlane.planePoints()[i][j] ) );
103 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) );
105 facePlane.MakePlane();
109 inline bool FacePlane_Doom3_importTokens( FacePlane& facePlane, Tokeniser& tokeniser ){
111 // parse plane equation
112 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "(" ) );
113 RETURN_FALSE_IF_FAIL( Tokeniser_getDouble( tokeniser, plane.a ) );
114 RETURN_FALSE_IF_FAIL( Tokeniser_getDouble( tokeniser, plane.b ) );
115 RETURN_FALSE_IF_FAIL( Tokeniser_getDouble( tokeniser, plane.c ) );
116 RETURN_FALSE_IF_FAIL( Tokeniser_getDouble( tokeniser, plane.d ) );
118 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, ")" ) );
120 facePlane.setDoom3Plane( plane );
124 inline bool FaceShader_Doom3_importTokens( FaceShader& faceShader, Tokeniser& tokeniser ){
125 const char *shader = tokeniser.getToken();
127 Tokeniser_unexpectedError( tokeniser, shader, "#shader-name" );
130 if ( string_equal( shader, "_emptyname" ) ) {
131 shader = texdef_name_default();
133 faceShader.setShader( shader );
137 inline bool FaceShader_importTokens( FaceShader& faceShader, Tokeniser& tokeniser ){
138 const char* texture = tokeniser.getToken();
139 if ( texture == 0 ) {
140 Tokeniser_unexpectedError( tokeniser, texture, "#texture-name" );
143 if ( string_equal( texture, "NULL" ) ) {
144 faceShader.setShader( texdef_name_default() );
148 StringOutputStream shader( string_length( GlobalTexturePrefix_get() ) + string_length( texture ) );
149 shader << GlobalTexturePrefix_get() << texture;
150 faceShader.setShader( shader.c_str() );
158 class Doom3FaceTokenImporter
162 Doom3FaceTokenImporter( Face& face ) : m_face( face ){
164 bool importTokens( Tokeniser& tokeniser ){
165 RETURN_FALSE_IF_FAIL( FacePlane_Doom3_importTokens( m_face.getPlane(), tokeniser ) );
166 RETURN_FALSE_IF_FAIL( FaceTexdef_BP_importTokens( m_face.getTexdef(), tokeniser ) );
167 RETURN_FALSE_IF_FAIL( FaceShader_Doom3_importTokens( m_face.getShader(), tokeniser ) );
168 RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
170 m_face.getTexdef().m_projectionInitialised = true;
171 m_face.getTexdef().m_scaleApplied = true;
177 class Quake4FaceTokenImporter
181 Quake4FaceTokenImporter( Face& face ) : m_face( face ){
183 bool importTokens( Tokeniser& tokeniser ){
184 RETURN_FALSE_IF_FAIL( FacePlane_Doom3_importTokens( m_face.getPlane(), tokeniser ) );
185 RETURN_FALSE_IF_FAIL( FaceTexdef_BP_importTokens( m_face.getTexdef(), tokeniser ) );
186 RETURN_FALSE_IF_FAIL( FaceShader_Doom3_importTokens( m_face.getShader(), tokeniser ) );
188 m_face.getTexdef().m_projectionInitialised = true;
189 m_face.getTexdef().m_scaleApplied = true;
195 class Quake2FaceTokenImporter
199 Quake2FaceTokenImporter( Face& face ) : m_face( face ){
201 bool importTokens( Tokeniser& tokeniser ){
202 RETURN_FALSE_IF_FAIL( FacePlane_importTokens( m_face.getPlane(), tokeniser ) );
203 RETURN_FALSE_IF_FAIL( FaceShader_importTokens( m_face.getShader(), tokeniser ) );
204 RETURN_FALSE_IF_FAIL( FaceTexdef_importTokens( m_face.getTexdef(), tokeniser ) );
205 if ( Tokeniser_nextTokenIsDigit( tokeniser ) ) {
206 m_face.getShader().m_flags.m_specified = true;
207 RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
209 m_face.getTexdef().m_scaleApplied = true;
214 class Quake3FaceTokenImporter
218 Quake3FaceTokenImporter( Face& face ) : m_face( face ){
220 bool importTokens( Tokeniser& tokeniser ){
221 RETURN_FALSE_IF_FAIL( FacePlane_importTokens( m_face.getPlane(), tokeniser ) );
222 RETURN_FALSE_IF_FAIL( FaceShader_importTokens( m_face.getShader(), tokeniser ) );
223 RETURN_FALSE_IF_FAIL( FaceTexdef_importTokens( m_face.getTexdef(), tokeniser ) );
224 RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
225 m_face.getTexdef().m_scaleApplied = true;
230 class Quake3BPFaceTokenImporter
234 Quake3BPFaceTokenImporter( Face& face ) : m_face( face ){
236 bool importTokens( Tokeniser& tokeniser ){
237 RETURN_FALSE_IF_FAIL( FacePlane_importTokens( m_face.getPlane(), tokeniser ) );
238 RETURN_FALSE_IF_FAIL( FaceTexdef_BP_importTokens( m_face.getTexdef(), tokeniser ) );
239 RETURN_FALSE_IF_FAIL( FaceShader_importTokens( m_face.getShader(), tokeniser ) );
240 RETURN_FALSE_IF_FAIL( FaceShader_importContentsFlagsValue( m_face.getShader(), tokeniser ) );
242 m_face.getTexdef().m_projectionInitialised = true;
243 m_face.getTexdef().m_scaleApplied = true;
249 class QuakeFaceTokenImporter
253 QuakeFaceTokenImporter( Face& face ) : m_face( face ){
255 bool importTokens( Tokeniser& tokeniser ){
256 RETURN_FALSE_IF_FAIL( FacePlane_importTokens( m_face.getPlane(), tokeniser ) );
257 RETURN_FALSE_IF_FAIL( FaceShader_importTokens( m_face.getShader(), tokeniser ) );
258 RETURN_FALSE_IF_FAIL( FaceTexdef_importTokens( m_face.getTexdef(), tokeniser ) );
259 m_face.getTexdef().m_scaleApplied = true;
264 class HalfLifeFaceTokenImporter
268 HalfLifeFaceTokenImporter( Face& face ) : m_face( face ){
270 bool importTokens( Tokeniser& tokeniser ){
271 RETURN_FALSE_IF_FAIL( FacePlane_importTokens( m_face.getPlane(), tokeniser ) );
272 RETURN_FALSE_IF_FAIL( FaceShader_importTokens( m_face.getShader(), tokeniser ) );
273 RETURN_FALSE_IF_FAIL( FaceTexdef_HalfLife_importTokens( m_face.getTexdef(), tokeniser ) );
274 m_face.getTexdef().m_scaleApplied = true;
280 inline void FacePlane_Doom3_exportTokens( const FacePlane& facePlane, TokenWriter& writer ){
281 // write plane equation
282 writer.writeToken( "(" );
283 writer.writeFloat( facePlane.getDoom3Plane().a );
284 writer.writeFloat( facePlane.getDoom3Plane().b );
285 writer.writeFloat( facePlane.getDoom3Plane().c );
286 writer.writeFloat( -facePlane.getDoom3Plane().d );
287 writer.writeToken( ")" );
290 inline void FacePlane_exportTokens( const FacePlane& facePlane, TokenWriter& writer ){
292 for ( std::size_t i = 0; i < 3; i++ )
294 writer.writeToken( "(" );
295 for ( std::size_t j = 0; j < 3; j++ )
297 writer.writeFloat( Face::m_quantise( facePlane.planePoints()[i][j] ) );
299 writer.writeToken( ")" );
303 inline void FaceTexdef_BP_exportTokens( const FaceTexdef& faceTexdef, TokenWriter& writer ){
304 // write alternate texdef
305 writer.writeToken( "(" );
307 writer.writeToken( "(" );
308 for ( std::size_t i = 0; i < 3; i++ )
310 writer.writeFloat( faceTexdef.m_projection.m_brushprimit_texdef.coords[0][i] );
312 writer.writeToken( ")" );
315 writer.writeToken( "(" );
316 for ( std::size_t i = 0; i < 3; i++ )
318 writer.writeFloat( faceTexdef.m_projection.m_brushprimit_texdef.coords[1][i] );
320 writer.writeToken( ")" );
322 writer.writeToken( ")" );
325 inline void FaceTexdef_exportTokens( const FaceTexdef& faceTexdef, TokenWriter& writer ){
326 ASSERT_MESSAGE( texdef_sane( faceTexdef.m_projection.m_texdef ), "FaceTexdef_exportTokens: bad texdef" );
328 writer.writeFloat( faceTexdef.m_projection.m_texdef.shift[0] );
329 writer.writeFloat( faceTexdef.m_projection.m_texdef.shift[1] );
330 writer.writeFloat( faceTexdef.m_projection.m_texdef.rotate );
331 writer.writeFloat( faceTexdef.m_projection.m_texdef.scale[0] );
332 writer.writeFloat( faceTexdef.m_projection.m_texdef.scale[1] );
335 inline void FaceTexdef_HalfLife_exportTokens( const FaceTexdef& faceTexdef, TokenWriter& writer ){
336 ASSERT_MESSAGE( texdef_sane( faceTexdef.m_projection.m_texdef ), "FaceTexdef_exportTokens: bad texdef" );
338 writer.writeToken( "[" );
339 writer.writeFloat( faceTexdef.m_projection.m_basis_s.x() );
340 writer.writeFloat( faceTexdef.m_projection.m_basis_s.y() );
341 writer.writeFloat( faceTexdef.m_projection.m_basis_s.z() );
342 writer.writeFloat( faceTexdef.m_projection.m_texdef.shift[0] );
343 writer.writeToken( "]" );
344 writer.writeToken( "[" );
345 writer.writeFloat( faceTexdef.m_projection.m_basis_t.x() );
346 writer.writeFloat( faceTexdef.m_projection.m_basis_t.y() );
347 writer.writeFloat( faceTexdef.m_projection.m_basis_t.z() );
348 writer.writeFloat( faceTexdef.m_projection.m_texdef.shift[1] );
349 writer.writeToken( "]" );
350 writer.writeFloat( -faceTexdef.m_projection.m_texdef.rotate );
351 writer.writeFloat( faceTexdef.m_projection.m_texdef.scale[0] );
352 writer.writeFloat( faceTexdef.m_projection.m_texdef.scale[1] );
355 inline void FaceShader_ContentsFlagsValue_exportTokens( const FaceShader& faceShader, TokenWriter& writer ){
356 // write surface flags
357 writer.writeInteger( faceShader.m_flags.m_contentFlags );
358 writer.writeInteger( faceShader.m_flags.m_surfaceFlags );
359 writer.writeInteger( faceShader.m_flags.m_value );
362 inline void FaceShader_exportTokens( const FaceShader& faceShader, TokenWriter& writer ){
364 if ( string_empty( shader_get_textureName( faceShader.getShader() ) ) ) {
365 writer.writeToken( "NULL" );
369 writer.writeToken( shader_get_textureName( faceShader.getShader() ) );
373 inline void FaceShader_Doom3_exportTokens( const FaceShader& faceShader, TokenWriter& writer ){
375 if ( string_empty( shader_get_textureName( faceShader.getShader() ) ) ) {
376 writer.writeString( "_emptyname" );
380 writer.writeString( faceShader.getShader() );
384 class Doom3FaceTokenExporter
388 Doom3FaceTokenExporter( const Face& face ) : m_face( face ){
390 void exportTokens( TokenWriter& writer ) const {
391 FacePlane_Doom3_exportTokens( m_face.getPlane(), writer );
392 FaceTexdef_BP_exportTokens( m_face.getTexdef(), writer );
393 FaceShader_Doom3_exportTokens( m_face.getShader(), writer );
394 FaceShader_ContentsFlagsValue_exportTokens( m_face.getShader(), writer );
399 class Quake4FaceTokenExporter
403 Quake4FaceTokenExporter( const Face& face ) : m_face( face ){
405 void exportTokens( TokenWriter& writer ) const {
406 FacePlane_Doom3_exportTokens( m_face.getPlane(), writer );
407 FaceTexdef_BP_exportTokens( m_face.getTexdef(), writer );
408 FaceShader_Doom3_exportTokens( m_face.getShader(), writer );
413 class Quake2FaceTokenExporter
417 Quake2FaceTokenExporter( const Face& face ) : m_face( face ){
419 void exportTokens( TokenWriter& writer ) const {
420 FacePlane_exportTokens( m_face.getPlane(), writer );
421 FaceShader_exportTokens( m_face.getShader(), writer );
422 FaceTexdef_exportTokens( m_face.getTexdef(), writer );
423 if ( m_face.getShader().m_flags.m_specified || m_face.isDetail() ) {
424 FaceShader_ContentsFlagsValue_exportTokens( m_face.getShader(), writer );
430 class Quake3FaceTokenExporter
434 Quake3FaceTokenExporter( const Face& face ) : m_face( face ){
436 void exportTokens( TokenWriter& writer ) const {
437 FacePlane_exportTokens( m_face.getPlane(), writer );
438 FaceShader_exportTokens( m_face.getShader(), writer );
439 FaceTexdef_exportTokens( m_face.getTexdef(), writer );
440 FaceShader_ContentsFlagsValue_exportTokens( m_face.getShader(), writer );
445 class Quake3BPFaceTokenExporter
449 Quake3BPFaceTokenExporter( const Face& face ) : m_face( face ){
451 void exportTokens( TokenWriter& writer ) const {
452 FacePlane_exportTokens( m_face.getPlane(), writer );
453 FaceTexdef_BP_exportTokens( m_face.getTexdef(), writer );
454 FaceShader_exportTokens( m_face.getShader(), writer );
455 FaceShader_ContentsFlagsValue_exportTokens( m_face.getShader(), writer );
460 class QuakeFaceTokenExporter
464 QuakeFaceTokenExporter( const Face& face ) : m_face( face ){
466 void exportTokens( TokenWriter& writer ) const {
467 FacePlane_exportTokens( m_face.getPlane(), writer );
468 FaceShader_exportTokens( m_face.getShader(), writer );
469 FaceTexdef_exportTokens( m_face.getTexdef(), writer );
474 class HalfLifeFaceTokenExporter
478 HalfLifeFaceTokenExporter( const Face& face ) : m_face( face ){
480 void exportTokens( TokenWriter& writer ) const {
481 FacePlane_exportTokens( m_face.getPlane(), writer );
482 FaceShader_exportTokens( m_face.getShader(), writer );
483 FaceTexdef_HalfLife_exportTokens( m_face.getTexdef(), writer );
489 class BrushTokenImporter : public MapImporter
494 BrushTokenImporter( Brush& brush ) : m_brush( brush ){
496 bool importTokens( Tokeniser& tokeniser ){
497 if ( Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
498 tokeniser.nextLine();
499 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "{" ) );
503 // check for end of brush
504 tokeniser.nextLine();
505 const char* token = tokeniser.getToken();
506 if ( string_equal( token, "}" ) ) {
510 tokeniser.ungetToken();
512 std::shared_ptr<Face> face = std::make_shared<Face>( &m_brush );
513 m_brush.push_back( face );
516 tokeniser.nextLine();
518 switch ( Brush::m_type )
520 case eBrushTypeDoom3:
522 Doom3FaceTokenImporter importer( *face );
523 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
526 case eBrushTypeQuake4:
528 Quake4FaceTokenImporter importer( *face );
529 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
532 case eBrushTypeQuake2:
534 Quake2FaceTokenImporter importer( *face );
535 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
538 case eBrushTypeQuake3:
540 Quake3FaceTokenImporter importer( *face );
541 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
544 case eBrushTypeQuake3BP:
546 Quake3BPFaceTokenImporter importer( *face );
547 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
550 case eBrushTypeQuake:
552 QuakeFaceTokenImporter importer( *face );
553 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
556 case eBrushTypeHalfLife:
558 HalfLifeFaceTokenImporter importer( *face );
559 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
563 face->planeChanged();
565 if ( Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
566 tokeniser.nextLine();
567 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "}" ) );
570 m_brush.planeChanged();
571 m_brush.shaderChanged();
578 class BrushTokenExporter : public MapExporter
580 const Brush& m_brush;
583 BrushTokenExporter( const Brush& brush ) : m_brush( brush ){
585 void exportTokens( TokenWriter& writer ) const {
586 m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified.
588 if ( !m_brush.hasContributingFaces() ) {
592 writer.writeToken( "{" );
595 if ( Brush::m_type == eBrushTypeQuake3BP ) {
596 writer.writeToken( "brushDef" );
598 writer.writeToken( "{" );
602 if ( Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
603 writer.writeToken( "brushDef3" );
605 writer.writeToken( "{" );
609 for ( Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i )
611 const Face& face = *( *i );
613 if ( face.contributes() ) {
614 switch ( Brush::m_type )
616 case eBrushTypeDoom3:
618 Doom3FaceTokenExporter exporter( face );
619 exporter.exportTokens( writer );
622 case eBrushTypeQuake4:
624 Quake4FaceTokenExporter exporter( face );
625 exporter.exportTokens( writer );
628 case eBrushTypeQuake2:
630 Quake2FaceTokenExporter exporter( face );
631 exporter.exportTokens( writer );
634 case eBrushTypeQuake3:
636 Quake3FaceTokenExporter exporter( face );
637 exporter.exportTokens( writer );
640 case eBrushTypeQuake3BP:
642 Quake3BPFaceTokenExporter exporter( face );
643 exporter.exportTokens( writer );
646 case eBrushTypeQuake:
648 QuakeFaceTokenExporter exporter( face );
649 exporter.exportTokens( writer );
652 case eBrushTypeHalfLife:
654 HalfLifeFaceTokenExporter exporter( face );
655 exporter.exportTokens( writer );
662 if ( Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
663 writer.writeToken( "}" );
667 writer.writeToken( "}" );