/
Face.h
225 lines (156 loc) · 6.07 KB
/
Face.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
#pragma once
#include "irender.h"
#include "iundo.h"
#include "mapfile.h"
#include "iselectiontest.h"
#include <sigc++/connection.h>
#include "math/Vector3.h"
#include "TextureProjection.h"
#include "SurfaceShader.h"
#include "PlanePoints.h"
#include "FacePlane.h"
#include <memory>
#include "util/Noncopyable.h"
#include <sigc++/signal.h>
#include "selection/algorithm/Shader.h"
const double GRID_MIN = 0.125;
class Face;
typedef std::shared_ptr<Face> FacePtr;
typedef std::vector<FacePtr> Faces;
/// A single planar face of a brush
class Face :
public IFace,
public IUndoable,
public util::Noncopyable
{
private:
// The structure which is saved to the undo stack
class SavedState;
public:
PlanePoints m_move_planepts;
PlanePoints m_move_planeptsTransformed;
private:
// The parent brush
Brush& _owner;
FacePlane m_plane;
FacePlane m_planeTransformed;
// Face shader, stores material name and GL shader object
SurfaceShader _shader;
// Connected to the SurfaceShader signals
sigc::connection _surfaceShaderRealised;
TextureProjection _texdef;
TextureProjection m_texdefTransformed;
Winding m_winding;
Vector3 m_centroid;
IUndoStateSaver* _undoStateSaver;
// Cached visibility flag, queried during front end rendering
bool _faceIsVisible;
public:
// Constructors
Face(Brush& owner);
Face(Brush& owner, const Vector3& p0, const Vector3& p1, const Vector3& p2,
const std::string& shader, const TextureProjection& projection);
Face(Brush& owner, const Plane3& plane);
Face(Brush& owner, const Plane3& plane, const Matrix4& texdef,
const std::string& shader);
// Copy Constructor
Face(Brush& owner, const Face& other);
// Destructor
virtual ~Face();
// Get the parent brush object
IBrush& getBrush() override;
Brush& getBrushInternal();
void planeChanged();
// greebo: Emits the updated normals to the Winding class.
void updateWinding();
void connectUndoSystem(IMapFileChangeTracker& changeTracker);
void disconnectUndoSystem(IMapFileChangeTracker& changeTracker);
void undoSave();
// undoable
IUndoMementoPtr exportState() const;
void importState(const IUndoMementoPtr& data);
/// Translate the face by the given vector
void translate(const Vector3& translation);
void flipWinding();
bool intersectVolume(const VolumeTest& volume) const;
bool intersectVolume(const VolumeTest& volume, const Matrix4& localToWorld) const;
// Frontend render methods for submitting the face winding
void renderWireframe(RenderableCollector& collector, const Matrix4& localToWorld,
const IRenderEntity& entity) const;
void setRenderSystem(const RenderSystemPtr& renderSystem);
void transform(const Matrix4& matrix) override;
void assign_planepts(const PlanePoints planepts);
/// \brief Reverts the transformable state of the brush to identity.
void revertTransform() override;
void freezeTransform() override;
void update_move_planepts_vertex(std::size_t index, PlanePoints planePoints);
void snapto(float snap);
void testSelect(SelectionTest& test, SelectionIntersection& best);
void testSelect_centroid(SelectionTest& test, SelectionIntersection& best);
void shaderChanged();
const std::string& getShader() const;
void setShader(const std::string& name);
void revertTexdef();
void texdefChanged();
const TextureProjection& getProjection() const;
TextureProjection& getProjection();
void GetTexdef(TextureProjection& projection) const;
void SetTexdef(const TextureProjection& projection);
// Applies the given shift/scale/rotation values to this face's texture projection
// The incoming values are measured in pixels and will be scaled internally.
void setTexdef(const TexDef& texDef);
// Constructs the texture projection matrix from the given (world) vertex and texture coords.
// Three vertices and their UV coordinates are enough to construct the texdef.
void setTexDefFromPoints(const Vector3 points[3], const Vector2 uvs[3]);
ShiftScaleRotation getShiftScaleRotation() const override;
void setShiftScaleRotation(const ShiftScaleRotation& scr) override;
/**
* greebo: Copies the shader (texdef) from the other face,
* and attempts to move the texture such that the transition
* between the faces are seamless.
*/
void applyShaderFromFace(const Face& other);
// s and t are texture coordinates
void shiftTexdef(float s, float t) override;
// Same as above, but with pixel values
void shiftTexdefByPixels(float sPixels, float tPixels) override;
// Scale the texdef by the given factors in s and t direction
// Passing s=1.05 will scale the texture to 105% in the s dimension
void scaleTexdef(float sFactor, float tFactor) override;
void rotateTexdef(float angle) override;
void fitTexture(float s_repeat, float t_repeat) override;
void flipTexture(unsigned int flipAxis) override;
void alignTexture(AlignEdge alignType) override;
/** greebo: This translates the texture as much towards
* the origin as possible. The face appearance stays unchanged.
*/
void normaliseTexture();
void EmitTextureCoordinates();
// When constructing faces with a default-constructed TextureProjection the scale is very small
// fix that by calling this method.
void applyDefaultTextureScale();
const Vector3& centroid() const;
void construct_centroid();
const Winding& getWinding() const;
Winding& getWinding();
const Plane3& plane3() const;
// Returns the Doom 3 plane
const Plane3& getPlane3() const;
FacePlane& getPlane();
const FacePlane& getPlane() const;
Matrix4 getTexDefMatrix() const;
Matrix4 getProjectionMatrix() override;
void setProjectionMatrix(const Matrix4& projection) override;
SurfaceShader& getFaceShader();
const SurfaceShader& getFaceShader() const;
bool contributes() const;
bool is_bounded() const;
bool isVisible() const override;
void updateFaceVisibility();
// Signal for external code to get notified each time the texdef of any face changes
static sigc::signal<void>& signal_texdefChanged();
private:
void realiseShader();
// Connects surface shader signals and calls realiseShader() if possible
void setupSurfaceShader();
}; // class Face