/
ibrush.h
340 lines (267 loc) · 9.44 KB
/
ibrush.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
#pragma once
#include "inode.h"
#include "imodule.h"
#include "math/Vector2.h"
#include "math/Vector3.h"
#include "math/Matrix4.h"
#include <vector>
class Plane3;
const std::string RKEY_ENABLE_TEXTURE_LOCK("user/ui/brush/textureLock");
namespace brush
{
// Helper class hosting brush-related settings
class IBrushSettings
{
public:
virtual ~IBrushSettings() {}
virtual const Vector3& getVertexColour() const = 0;
virtual void setVertexColour(const Vector3& colour) = 0;
virtual sigc::signal<void>& signal_settingsChanged() = 0;
};
class BrushCreator :
public RegisterableModule
{
public:
virtual scene::INodePtr createBrush() = 0;
virtual IBrushSettings& getSettings() = 0;
};
enum class PrefabType : int
{
Cuboid = 0,
Prism,
Cone,
Sphere,
NumPrefabTypes,
};
// Public constants
const std::size_t c_brush_maxFaces = 1024;
const std::size_t PRISM_MIN_SIDES = 3;
const std::size_t PRISM_MAX_SIDES = c_brush_maxFaces - 2;
const std::size_t CONE_MIN_SIDES = 3;
const std::size_t CONE_MAX_SIDES = 32;
const std::size_t SPHERE_MIN_SIDES = 3;
const std::size_t SPHERE_MAX_SIDES = 7;
}
// The structure defining a single corner point of an IWinding
struct WindingVertex
{
Vector3 vertex; // The 3D coordinates of the point
Vector2 texcoord; // The UV coordinates
Vector3 tangent; // The tangent
Vector3 bitangent; // The bitangent
Vector3 normal; // The normals
std::size_t adjacent; // The index of the adjacent WindingVertex
// greebo: This operator is needed to enable scripting support
// using boost::python's vector_indexing_suite.
bool operator==(const WindingVertex& other) const
{
return (vertex == other.vertex && texcoord == other.texcoord &&
tangent == other.tangent && bitangent == other.bitangent &&
normal == other.normal && adjacent == other.adjacent);
}
};
// A Winding consists of several connected WindingVertex objects,
// each of which holding information about a single corner point.
typedef std::vector<WindingVertex> IWinding;
/**
* greebo: The texture definition structure containing the scale,
* rotation and shift values of an applied texture.
* At some places this is referred to as "fake" texture coordinates.
* This is not what is actually saved to the .map file, but it makes
* texture manipulations in the Surface Inspector much more human-readable.
*/
struct ShiftScaleRotation
{
double shift[2];
double rotate;
double scale[2];
ShiftScaleRotation()
{
shift[0] = shift[1] = 0;
rotate = 0;
scale[0] = scale[1] = 1;
}
};
// Interface for a face plane
class IFace
{
public:
// Destructor
virtual ~IFace() {}
// Submits the current state to the UndoSystem, to make further actions undo-able
virtual void undoSave() = 0;
// Returns true if the texture of this face is not filtered out
// This doesn't take into account whether the owning brush is visible or not
virtual bool isVisible() const = 0;
// Shader accessors
virtual const std::string& getShader() const = 0;
virtual void setShader(const std::string& name) = 0;
// Shifts the texture by the given s,t amount in texture space
virtual void shiftTexdef(float s, float t) = 0;
// Convenience wrapper to shift the assigned texture by the given amount of pixels
// the passed values are scaled accordingly and passed on to shiftTexdef()
virtual void shiftTexdefByPixels(float s, float t) = 0;
// Scales the tex def by the given factors in texture space
virtual void scaleTexdef(float s, float t) = 0;
// Rotates the texture by the given angle
virtual void rotateTexdef(float angle) = 0;
// Fits the texture on this face
virtual void fitTexture(float s_repeat, float t_repeat) = 0;
// Flips the texture by the given flipAxis (0 == x-axis, 1 == y-axis)
virtual void flipTexture(unsigned int flipAxis) = 0;
// This translates the texture as much towards the origin in texture space as possible without changing the world appearance.
virtual void normaliseTexture() = 0;
enum class AlignEdge
{
Top,
Bottom,
Left,
Right,
};
// If possible, aligns the assigned texture at the given anchor edge
virtual void alignTexture(AlignEdge alignType) = 0;
// Get access to the actual Winding object
virtual IWinding& getWinding() = 0;
virtual const IWinding& getWinding() const = 0;
virtual const Plane3& getPlane3() const = 0;
/**
* Returns the 3x3 texture matrix for this face, containing shift, scale and rotation.
*
* xx, yx, xy and yy hold the scale and rotation
* tx and ty hold the shift
*/
virtual Matrix4 getTexDefMatrix() const = 0;
/**
* The matrix used to project world coordinates to U/V space.
*/
virtual Matrix4 getProjectionMatrix() = 0;
virtual void setProjectionMatrix(const Matrix4& projection) = 0;
/**
* Calculates and returns the texture definition as shift/scale/rotate.
* This is not what is actually saved to the .map file, but it makes
* texture manipulations in the Surface Inspector much more human-readable.
*/
virtual ShiftScaleRotation getShiftScaleRotation() const = 0;
virtual void setShiftScaleRotation(const ShiftScaleRotation& scr) = 0;
// Transforms this face plane with the given transformation matrix
virtual void transform(const Matrix4& transformation) = 0;
};
// Plane classification info used by splitting and CSG algorithms
struct BrushSplitType
{
std::size_t counts[3];
BrushSplitType()
{
counts[0] = 0;
counts[1] = 0;
counts[2] = 0;
}
BrushSplitType& operator+=(const BrushSplitType& other)
{
counts[0] += other.counts[0];
counts[1] += other.counts[1];
counts[2] += other.counts[2];
return *this;
}
};
// Brush Interface
class IBrush
{
public:
virtual ~IBrush() {}
// Returns the number of faces for this brush
virtual std::size_t getNumFaces() const = 0;
// Get a reference to the face by index in [0..getNumFaces).
virtual IFace& getFace(std::size_t index) = 0;
// Const variant of the above
virtual const IFace& getFace(std::size_t index) const = 0;
// Add a new face to this brush, using the given plane object, returns a reference to the new face
virtual IFace& addFace(const Plane3& plane) = 0;
// Add a new face to this brush, using the given plane, texdef matrix and shader name
virtual IFace& addFace(const Plane3& plane, const Matrix4& texDef, const std::string& shader) = 0;
// Removes all faces from this brush
virtual void clear() = 0;
// Returns true when this brush has no faces
virtual bool empty() const = 0;
// Returns true if any face of the brush contributes to the final B-Rep.
virtual bool hasContributingFaces() const = 0;
// Removes faces that do not contribute to the brush.
// This is useful for cleaning up after CSG operations on the brush.
// 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.
virtual void removeEmptyFaces() = 0;
// Sets the shader of all faces to the given name
virtual void setShader(const std::string& newShader) = 0;
// Returns TRUE if any of the faces has the given shader
virtual bool hasShader(const std::string& name) = 0;
// Returns TRUE if any of the brush's faces has a visible material, FALSE if all faces are effectively hidden
virtual bool hasVisibleMaterial() const = 0;
/**
* greebo: This is used by the filter system (for example) to trigger
* an update of the cached visibility flags. This enables a brush
* to quickly cull its hidden faces without issuing lots of internal calls.
*/
virtual void updateFaceVisibility() = 0;
// Saves the current state to the undo stack.
// Call this before manipulating the brush to make your action undo-able.
virtual void undoSave() = 0;
enum DetailFlag
{
Structural = 0,
Detail = 1 << 27, // 134217728
};
/**
* Q3-compatibility feature, get the value of the detail/structural flag
*/
virtual DetailFlag getDetailFlag() const = 0;
/**
* Q3-compatibility feature, set the detail/structural flag
*/
virtual void setDetailFlag(DetailFlag newValue) = 0;
// Classify this brush against the given plane, used by clipper and CSG algorithms
virtual BrushSplitType classifyPlane(const Plane3& plane) const = 0;
// Method used internally to recalculate the brush windings
virtual void evaluateBRep() const = 0;
};
// Forward-declare the Brush object, only accessible from main binary
class Brush;
class IBrushNode
{
public:
virtual ~IBrushNode() {}
/** greebo: Retrieves the contained Brush from the BrushNode
*/
virtual Brush& getBrush() = 0;
// Returns the IBrush interface
virtual IBrush& getIBrush() = 0;
};
typedef std::shared_ptr<IBrushNode> IBrushNodePtr;
inline bool Node_isBrush(const scene::INodePtr& node)
{
return node->getNodeType() == scene::INode::Type::Brush;
//return std::dynamic_pointer_cast<IBrushNode>(node) != NULL;
}
// Casts the node onto a BrushNode and returns the Brush pointer
inline Brush* Node_getBrush(const scene::INodePtr& node)
{
IBrushNodePtr brushNode = std::dynamic_pointer_cast<IBrushNode>(node);
if (brushNode != NULL) {
return &brushNode->getBrush();
}
return NULL;
}
// Casts the node onto a BrushNode and returns the IBrush pointer
inline IBrush* Node_getIBrush(const scene::INodePtr& node)
{
IBrushNodePtr brushNode = std::dynamic_pointer_cast<IBrushNode>(node);
if (brushNode != NULL) {
return &brushNode->getIBrush();
}
return NULL;
}
const char* const MODULE_BRUSHCREATOR("Doom3BrushCreator");
inline brush::BrushCreator& GlobalBrushCreator()
{
static module::InstanceReference<brush::BrushCreator> _reference(MODULE_BRUSHCREATOR);
return _reference;
}