/
LegacyBrushDefExporter.h
132 lines (108 loc) · 3.62 KB
/
LegacyBrushDefExporter.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#pragma once
#include "ibrush.h"
#include "math/Plane3.h"
#include "math/Matrix4.h"
#include "shaderlib.h"
#include "string/predicate.h"
#include "ExportUtil.h"
namespace map
{
class LegacyBrushDefExporter
{
public:
// Writes an old Q3-style brush definition from the given brush to the given stream
static void exportBrush(std::ostream& stream, const IBrushNodePtr& brushNode)
{
const IBrush& brush = brushNode->getIBrush();
// Curly braces surround the brush contents
stream << "{" << std::endl;
// Iterate over each brush face, exporting the tokens from all faces
for (std::size_t i = 0; i < brush.getNumFaces(); ++i)
{
writeFace(stream, brush.getFace(i), brush.getDetailFlag());
}
// Close brush contents
stream << "}" << std::endl;
}
/*
{
( 16 192 96 ) ( 16 128 96 ) ( 0 192 96 ) shared_vega/trim03a 0 0 0 0.125 0.125 134217728 0 0
( 0 208 96 ) ( 0 208 80 ) ( 16 192 96 ) common/caulk 0 0 0 0.5 0.5 134217728 0 0
( 0 208 80 ) ( 0 208 96 ) ( 0 112 96 ) shared_vega/trim03a 64 0 90 0.125 0.125 134217728 0 0
( 0 112 80 ) ( 16 128 80 ) ( 0 192 80 ) common/caulk 0 0 0 0.5 0.5 134217728 0 0
( 16 128 96 ) ( 16 128 80 ) ( 0 112 96 ) shared_vega/trim03a 64 0 90 0.125 0.125 134217728 0 0
( 16 128 80 ) ( 16 128 96 ) ( 16 192 80 ) common/caulk 0 0 0 0.5 0.5 134217728 0 0
}
*/
private:
static void writeFace(std::ostream& stream, const IFace& face, IBrush::DetailFlag detailFlag)
{
// greebo: Don't export faces with degenerate or empty windings (they are "non-contributing")
const IWinding& winding = face.getWinding();
if (winding.size() <= 2)
{
return;
}
// ( 16 192 96 ) ( 16 128 96 ) ( 0 192 96 ) shared_vega/trim03a 0 0 0 0.125 0.125 134217728 0 0
// ( Point 1 ) ( Point 2 ) ( Point 3 ) path/to/material shiftS shiftT rotate scaleS scaleT DetailFlag 0 0
// Each face plane is defined by three points
stream << "( ";
writeDoubleSafe(winding[2].vertex.x(), stream);
stream << " ";
writeDoubleSafe(winding[2].vertex.y(), stream);
stream << " ";
writeDoubleSafe(winding[2].vertex.z(), stream);
stream << " ";
stream << ") ";
stream << "( ";
writeDoubleSafe(winding[0].vertex.x(), stream);
stream << " ";
writeDoubleSafe(winding[0].vertex.y(), stream);
stream << " ";
writeDoubleSafe(winding[0].vertex.z(), stream);
stream << " ";
stream << ") ";
stream << "( ";
writeDoubleSafe(winding[1].vertex.x(), stream);
stream << " ";
writeDoubleSafe(winding[1].vertex.y(), stream);
stream << " ";
writeDoubleSafe(winding[1].vertex.z(), stream);
stream << " ";
stream << ") ";
// Write Shader (without quotes)
const std::string& shaderName = face.getShader();
if (shaderName.empty())
{
stream << "_default ";
}
else
{
if (string::starts_with(shaderName, GlobalTexturePrefix_get()))
{
// Q3 has an implicit "textures/" not written to the map, cut it off
stream << shader_get_textureName(shaderName.c_str()) << " ";
}
else
{
stream << shaderName << " ";
}
}
// Write Texture Shift/Scale/Rotation
auto shiftScaleRotate = face.getShiftScaleRotation();
writeDoubleSafe(shiftScaleRotate.shift[0], stream);
stream << " ";
writeDoubleSafe(shiftScaleRotate.shift[1], stream);
stream << " ";
writeDoubleSafe(shiftScaleRotate.rotate, stream);
stream << " ";
writeDoubleSafe(shiftScaleRotate.scale[0], stream);
stream << " ";
writeDoubleSafe(shiftScaleRotate.scale[1], stream);
stream << " ";
// Export contents flags and the two zeroes at the end
stream << detailFlag << " 0 0";
stream << std::endl;
}
};
}