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 m_brush.push_back( FaceSmartPointer( new Face( &m_brush ) ) );
515 tokeniser.nextLine();
517 Face& face = *m_brush.back();
519 switch ( Brush::m_type )
521 case eBrushTypeDoom3:
523 Doom3FaceTokenImporter importer( face );
524 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
527 case eBrushTypeQuake4:
529 Quake4FaceTokenImporter importer( face );
530 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
533 case eBrushTypeQuake2:
535 Quake2FaceTokenImporter importer( face );
536 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
539 case eBrushTypeQuake3:
541 Quake3FaceTokenImporter importer( face );
542 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
545 case eBrushTypeQuake3BP:
547 Quake3BPFaceTokenImporter importer( face );
548 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
551 case eBrushTypeQuake:
553 QuakeFaceTokenImporter importer( face );
554 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
557 case eBrushTypeHalfLife:
559 HalfLifeFaceTokenImporter importer( face );
560 RETURN_FALSE_IF_FAIL( importer.importTokens( tokeniser ) );
566 if ( Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
567 tokeniser.nextLine();
568 RETURN_FALSE_IF_FAIL( Tokeniser_parseToken( tokeniser, "}" ) );
571 m_brush.planeChanged();
572 m_brush.shaderChanged();
579 class BrushTokenExporter : public MapExporter
581 const Brush& m_brush;
584 BrushTokenExporter( const Brush& brush ) : m_brush( brush ){
586 void exportTokens( TokenWriter& writer ) const {
587 m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified.
589 if ( !m_brush.hasContributingFaces() ) {
593 writer.writeToken( "{" );
596 if ( Brush::m_type == eBrushTypeQuake3BP ) {
597 writer.writeToken( "brushDef" );
599 writer.writeToken( "{" );
603 if ( Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
604 writer.writeToken( "brushDef3" );
606 writer.writeToken( "{" );
610 for ( Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i )
612 const Face& face = *( *i );
614 if ( face.contributes() ) {
615 switch ( Brush::m_type )
617 case eBrushTypeDoom3:
619 Doom3FaceTokenExporter exporter( face );
620 exporter.exportTokens( writer );
623 case eBrushTypeQuake4:
625 Quake4FaceTokenExporter exporter( face );
626 exporter.exportTokens( writer );
629 case eBrushTypeQuake2:
631 Quake2FaceTokenExporter exporter( face );
632 exporter.exportTokens( writer );
635 case eBrushTypeQuake3:
637 Quake3FaceTokenExporter exporter( face );
638 exporter.exportTokens( writer );
641 case eBrushTypeQuake3BP:
643 Quake3BPFaceTokenExporter exporter( face );
644 exporter.exportTokens( writer );
647 case eBrushTypeQuake:
649 QuakeFaceTokenExporter exporter( face );
650 exporter.exportTokens( writer );
653 case eBrushTypeHalfLife:
655 HalfLifeFaceTokenExporter exporter( face );
656 exporter.exportTokens( writer );
663 if ( Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4 ) {
664 writer.writeToken( "}" );
668 writer.writeToken( "}" );