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)
31 // parse the optional contents/flags/value
32 RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_contentFlags));
33 RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_surfaceFlags));
34 RETURN_FALSE_IF_FAIL(Tokeniser_getInteger(tokeniser, faceShader.m_flags.m_value));
38 inline bool FaceTexdef_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser)
41 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0]));
42 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1]));
43 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate));
44 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0]));
45 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1]));
47 ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef");
51 inline bool FaceTexdef_BP_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser)
53 // parse alternate texdef
54 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
56 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
57 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][0]));
58 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][1]));
59 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[0][2]));
60 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
63 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
64 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][0]));
65 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][1]));
66 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_brushprimit_texdef.coords[1][2]));
67 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
69 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
73 inline bool FaceTexdef_HalfLife_importTokens(FaceTexdef &texdef, Tokeniser &tokeniser)
76 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "["));
77 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.x()));
78 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.y()));
79 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_s.z()));
80 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[0]));
81 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]"));
82 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "["));
83 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.x()));
84 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.y()));
85 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_basis_t.z()));
86 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.shift[1]));
87 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "]"));
88 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.rotate));
89 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[0]));
90 RETURN_FALSE_IF_FAIL(Tokeniser_getFloat(tokeniser, texdef.m_projection.m_texdef.scale[1]));
92 texdef.m_projection.m_texdef.rotate = -texdef.m_projection.m_texdef.rotate;
94 ASSERT_MESSAGE(texdef_sane(texdef.m_projection.m_texdef), "FaceTexdef_importTokens: bad texdef");
98 inline bool FacePlane_importTokens(FacePlane &facePlane, Tokeniser &tokeniser)
101 for (std::size_t i = 0; i < 3; i++) {
102 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
103 for (std::size_t j = 0; j < 3; ++j) {
104 RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, facePlane.planePoints()[i][j]));
106 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
108 facePlane.MakePlane();
112 inline bool FacePlane_Doom3_importTokens(FacePlane &facePlane, Tokeniser &tokeniser)
115 // parse plane equation
116 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "("));
117 RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.a));
118 RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.b));
119 RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.c));
120 RETURN_FALSE_IF_FAIL(Tokeniser_getDouble(tokeniser, plane.d));
122 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, ")"));
124 facePlane.setDoom3Plane(plane);
128 inline bool FaceShader_Doom3_importTokens(FaceShader &faceShader, Tokeniser &tokeniser)
130 const char *shader = tokeniser.getToken();
132 Tokeniser_unexpectedError(tokeniser, shader, "#shader-name");
135 if (string_equal(shader, "_emptyname")) {
136 shader = texdef_name_default();
138 faceShader.setShader(shader);
142 inline bool FaceShader_importTokens(FaceShader &faceShader, Tokeniser &tokeniser)
144 const char *texture = tokeniser.getToken();
146 Tokeniser_unexpectedError(tokeniser, texture, "#texture-name");
149 if (string_equal(texture, "NULL")) {
150 faceShader.setShader(texdef_name_default());
152 StringOutputStream shader(string_length(GlobalTexturePrefix_get()) + string_length(texture));
153 shader << GlobalTexturePrefix_get() << texture;
154 faceShader.setShader(shader.c_str());
160 class Doom3FaceTokenImporter {
163 Doom3FaceTokenImporter(Face &face) : m_face(face)
167 bool importTokens(Tokeniser &tokeniser)
169 RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser));
170 RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser));
171 RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser));
172 RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser));
174 m_face.getTexdef().m_projectionInitialised = true;
175 m_face.getTexdef().m_scaleApplied = true;
181 class Quake4FaceTokenImporter {
184 Quake4FaceTokenImporter(Face &face) : m_face(face)
188 bool importTokens(Tokeniser &tokeniser)
190 RETURN_FALSE_IF_FAIL(FacePlane_Doom3_importTokens(m_face.getPlane(), tokeniser));
191 RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser));
192 RETURN_FALSE_IF_FAIL(FaceShader_Doom3_importTokens(m_face.getShader(), tokeniser));
194 m_face.getTexdef().m_projectionInitialised = true;
195 m_face.getTexdef().m_scaleApplied = true;
201 class Quake2FaceTokenImporter {
204 Quake2FaceTokenImporter(Face &face) : m_face(face)
208 bool importTokens(Tokeniser &tokeniser)
210 RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser));
211 RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser));
212 RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser));
213 if (Tokeniser_nextTokenIsDigit(tokeniser)) {
214 m_face.getShader().m_flags.m_specified = true;
215 RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser));
217 m_face.getTexdef().m_scaleApplied = true;
222 class Quake3FaceTokenImporter {
225 Quake3FaceTokenImporter(Face &face) : m_face(face)
229 bool importTokens(Tokeniser &tokeniser)
231 RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser));
232 RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser));
233 RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser));
234 RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser));
235 m_face.getTexdef().m_scaleApplied = true;
240 class Quake3BPFaceTokenImporter {
243 Quake3BPFaceTokenImporter(Face &face) : m_face(face)
247 bool importTokens(Tokeniser &tokeniser)
249 RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser));
250 RETURN_FALSE_IF_FAIL(FaceTexdef_BP_importTokens(m_face.getTexdef(), tokeniser));
251 RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser));
252 RETURN_FALSE_IF_FAIL(FaceShader_importContentsFlagsValue(m_face.getShader(), tokeniser));
254 m_face.getTexdef().m_projectionInitialised = true;
255 m_face.getTexdef().m_scaleApplied = true;
261 class QuakeFaceTokenImporter {
264 QuakeFaceTokenImporter(Face &face) : m_face(face)
268 bool importTokens(Tokeniser &tokeniser)
270 RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser));
271 RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser));
272 RETURN_FALSE_IF_FAIL(FaceTexdef_importTokens(m_face.getTexdef(), tokeniser));
273 m_face.getTexdef().m_scaleApplied = true;
278 class HalfLifeFaceTokenImporter {
281 HalfLifeFaceTokenImporter(Face &face) : m_face(face)
285 bool importTokens(Tokeniser &tokeniser)
287 RETURN_FALSE_IF_FAIL(FacePlane_importTokens(m_face.getPlane(), tokeniser));
288 RETURN_FALSE_IF_FAIL(FaceShader_importTokens(m_face.getShader(), tokeniser));
289 RETURN_FALSE_IF_FAIL(FaceTexdef_HalfLife_importTokens(m_face.getTexdef(), tokeniser));
290 m_face.getTexdef().m_scaleApplied = true;
296 inline void FacePlane_Doom3_exportTokens(const FacePlane &facePlane, TokenWriter &writer)
298 // write plane equation
299 writer.writeToken("(");
300 writer.writeFloat(facePlane.getDoom3Plane().a);
301 writer.writeFloat(facePlane.getDoom3Plane().b);
302 writer.writeFloat(facePlane.getDoom3Plane().c);
303 writer.writeFloat(-facePlane.getDoom3Plane().d);
304 writer.writeToken(")");
307 inline void FacePlane_exportTokens(const FacePlane &facePlane, TokenWriter &writer)
310 for (std::size_t i = 0; i < 3; i++) {
311 writer.writeToken("(");
312 for (std::size_t j = 0; j < 3; j++) {
313 writer.writeFloat(Face::m_quantise(facePlane.planePoints()[i][j]));
315 writer.writeToken(")");
319 inline void FaceTexdef_BP_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer)
321 // write alternate texdef
322 writer.writeToken("(");
324 writer.writeToken("(");
325 for (std::size_t i = 0; i < 3; i++) {
326 writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[0][i]);
328 writer.writeToken(")");
331 writer.writeToken("(");
332 for (std::size_t i = 0; i < 3; i++) {
333 writer.writeFloat(faceTexdef.m_projection.m_brushprimit_texdef.coords[1][i]);
335 writer.writeToken(")");
337 writer.writeToken(")");
340 inline void FaceTexdef_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer)
342 ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef");
344 writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]);
345 writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]);
346 writer.writeFloat(faceTexdef.m_projection.m_texdef.rotate);
347 writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]);
348 writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]);
351 inline void FaceTexdef_HalfLife_exportTokens(const FaceTexdef &faceTexdef, TokenWriter &writer)
353 ASSERT_MESSAGE(texdef_sane(faceTexdef.m_projection.m_texdef), "FaceTexdef_exportTokens: bad texdef");
355 writer.writeToken("[");
356 writer.writeFloat(faceTexdef.m_projection.m_basis_s.x());
357 writer.writeFloat(faceTexdef.m_projection.m_basis_s.y());
358 writer.writeFloat(faceTexdef.m_projection.m_basis_s.z());
359 writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[0]);
360 writer.writeToken("]");
361 writer.writeToken("[");
362 writer.writeFloat(faceTexdef.m_projection.m_basis_t.x());
363 writer.writeFloat(faceTexdef.m_projection.m_basis_t.y());
364 writer.writeFloat(faceTexdef.m_projection.m_basis_t.z());
365 writer.writeFloat(faceTexdef.m_projection.m_texdef.shift[1]);
366 writer.writeToken("]");
367 writer.writeFloat(-faceTexdef.m_projection.m_texdef.rotate);
368 writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[0]);
369 writer.writeFloat(faceTexdef.m_projection.m_texdef.scale[1]);
372 inline void FaceShader_ContentsFlagsValue_exportTokens(const FaceShader &faceShader, TokenWriter &writer)
374 // write surface flags
375 writer.writeInteger(faceShader.m_flags.m_contentFlags);
376 writer.writeInteger(faceShader.m_flags.m_surfaceFlags);
377 writer.writeInteger(faceShader.m_flags.m_value);
380 inline void FaceShader_exportTokens(const FaceShader &faceShader, TokenWriter &writer)
383 if (string_empty(shader_get_textureName(faceShader.getShader()))) {
384 writer.writeToken("NULL");
386 writer.writeToken(shader_get_textureName(faceShader.getShader()));
390 inline void FaceShader_Doom3_exportTokens(const FaceShader &faceShader, TokenWriter &writer)
393 if (string_empty(shader_get_textureName(faceShader.getShader()))) {
394 writer.writeString("_emptyname");
396 writer.writeString(faceShader.getShader());
400 class Doom3FaceTokenExporter {
403 Doom3FaceTokenExporter(const Face &face) : m_face(face)
407 void exportTokens(TokenWriter &writer) const
409 FacePlane_Doom3_exportTokens(m_face.getPlane(), writer);
410 FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer);
411 FaceShader_Doom3_exportTokens(m_face.getShader(), writer);
412 FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer);
417 class Quake4FaceTokenExporter {
420 Quake4FaceTokenExporter(const Face &face) : m_face(face)
424 void exportTokens(TokenWriter &writer) const
426 FacePlane_Doom3_exportTokens(m_face.getPlane(), writer);
427 FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer);
428 FaceShader_Doom3_exportTokens(m_face.getShader(), writer);
433 class Quake2FaceTokenExporter {
436 Quake2FaceTokenExporter(const Face &face) : m_face(face)
440 void exportTokens(TokenWriter &writer) const
442 FacePlane_exportTokens(m_face.getPlane(), writer);
443 FaceShader_exportTokens(m_face.getShader(), writer);
444 FaceTexdef_exportTokens(m_face.getTexdef(), writer);
445 if (m_face.getShader().m_flags.m_specified || m_face.isDetail()) {
446 FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer);
452 class Quake3FaceTokenExporter {
455 Quake3FaceTokenExporter(const Face &face) : m_face(face)
459 void exportTokens(TokenWriter &writer) const
461 FacePlane_exportTokens(m_face.getPlane(), writer);
462 FaceShader_exportTokens(m_face.getShader(), writer);
463 FaceTexdef_exportTokens(m_face.getTexdef(), writer);
464 FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer);
469 class Quake3BPFaceTokenExporter {
472 Quake3BPFaceTokenExporter(const Face &face) : m_face(face)
476 void exportTokens(TokenWriter &writer) const
478 FacePlane_exportTokens(m_face.getPlane(), writer);
479 FaceTexdef_BP_exportTokens(m_face.getTexdef(), writer);
480 FaceShader_exportTokens(m_face.getShader(), writer);
481 FaceShader_ContentsFlagsValue_exportTokens(m_face.getShader(), writer);
486 class QuakeFaceTokenExporter {
489 QuakeFaceTokenExporter(const Face &face) : m_face(face)
493 void exportTokens(TokenWriter &writer) const
495 FacePlane_exportTokens(m_face.getPlane(), writer);
496 FaceShader_exportTokens(m_face.getShader(), writer);
497 FaceTexdef_exportTokens(m_face.getTexdef(), writer);
502 class HalfLifeFaceTokenExporter {
505 HalfLifeFaceTokenExporter(const Face &face) : m_face(face)
509 void exportTokens(TokenWriter &writer) const
511 FacePlane_exportTokens(m_face.getPlane(), writer);
512 FaceShader_exportTokens(m_face.getShader(), writer);
513 FaceTexdef_HalfLife_exportTokens(m_face.getTexdef(), writer);
519 class BrushTokenImporter : public MapImporter {
523 BrushTokenImporter(Brush &brush) : m_brush(brush)
527 bool importTokens(Tokeniser &tokeniser)
529 if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 ||
530 Brush::m_type == eBrushTypeQuake4) {
531 tokeniser.nextLine();
532 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "{"));
535 // check for end of brush
536 tokeniser.nextLine();
537 const char *token = tokeniser.getToken();
538 if (string_equal(token, "}")) {
542 tokeniser.ungetToken();
544 m_brush.push_back(FaceSmartPointer(new Face(&m_brush)));
547 tokeniser.nextLine();
549 Face &face = *m_brush.back();
551 switch (Brush::m_type) {
552 case eBrushTypeDoom3: {
553 Doom3FaceTokenImporter importer(face);
554 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
557 case eBrushTypeQuake4: {
558 Quake4FaceTokenImporter importer(face);
559 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
562 case eBrushTypeQuake2: {
563 Quake2FaceTokenImporter importer(face);
564 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
567 case eBrushTypeQuake3: {
568 Quake3FaceTokenImporter importer(face);
569 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
572 case eBrushTypeQuake3BP: {
573 Quake3BPFaceTokenImporter importer(face);
574 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
577 case eBrushTypeQuake: {
578 QuakeFaceTokenImporter importer(face);
579 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
582 case eBrushTypeHalfLife: {
583 HalfLifeFaceTokenImporter importer(face);
584 RETURN_FALSE_IF_FAIL(importer.importTokens(tokeniser));
590 if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 ||
591 Brush::m_type == eBrushTypeQuake4) {
592 tokeniser.nextLine();
593 RETURN_FALSE_IF_FAIL(Tokeniser_parseToken(tokeniser, "}"));
596 m_brush.planeChanged();
597 m_brush.shaderChanged();
604 class BrushTokenExporter : public MapExporter {
605 const Brush &m_brush;
608 BrushTokenExporter(const Brush &brush) : m_brush(brush)
612 void exportTokens(TokenWriter &writer) const
614 m_brush.evaluateBRep(); // ensure b-rep is up-to-date, so that non-contributing faces can be identified.
616 if (!m_brush.hasContributingFaces()) {
620 writer.writeToken("{");
623 if (Brush::m_type == eBrushTypeQuake3BP) {
624 writer.writeToken("brushDef");
626 writer.writeToken("{");
630 if (Brush::m_type == eBrushTypeDoom3 || Brush::m_type == eBrushTypeQuake4) {
631 writer.writeToken("brushDef3");
633 writer.writeToken("{");
637 for (Brush::const_iterator i = m_brush.begin(); i != m_brush.end(); ++i) {
638 const Face &face = *(*i);
640 if (face.contributes()) {
641 switch (Brush::m_type) {
642 case eBrushTypeDoom3: {
643 Doom3FaceTokenExporter exporter(face);
644 exporter.exportTokens(writer);
647 case eBrushTypeQuake4: {
648 Quake4FaceTokenExporter exporter(face);
649 exporter.exportTokens(writer);
652 case eBrushTypeQuake2: {
653 Quake2FaceTokenExporter exporter(face);
654 exporter.exportTokens(writer);
657 case eBrushTypeQuake3: {
658 Quake3FaceTokenExporter exporter(face);
659 exporter.exportTokens(writer);
662 case eBrushTypeQuake3BP: {
663 Quake3BPFaceTokenExporter exporter(face);
664 exporter.exportTokens(writer);
667 case eBrushTypeQuake: {
668 QuakeFaceTokenExporter exporter(face);
669 exporter.exportTokens(writer);
672 case eBrushTypeHalfLife: {
673 HalfLifeFaceTokenExporter exporter(face);
674 exporter.exportTokens(writer);
681 if (Brush::m_type == eBrushTypeQuake3BP || Brush::m_type == eBrushTypeDoom3 ||
682 Brush::m_type == eBrushTypeQuake4) {
683 writer.writeToken("}");
687 writer.writeToken("}");