UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
Polys.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3//
4// List of FPolys.
5//
6
7#pragma once
8
9#include "CoreMinimal.h"
12#include "UObject/Object.h"
13#include "Engine/EngineTypes.h"
14#include "Polys.generated.h"
15
16class ABrush;
18class UModel;
19
20// Results from FPoly.SplitWithPlane, describing the result of splitting
21// an arbitrary FPoly with an arbitrary plane.
23{
24 SP_Coplanar = 0, // Poly wasn't split, but is coplanar with plane
25 SP_Front = 1, // Poly wasn't split, but is entirely in front of plane
26 SP_Back = 2, // Poly wasn't split, but is entirely in back of plane
27 SP_Split = 3, // Poly was split into two new editor polygons
28};
29
30//
31// A general-purpose polygon used by the editor. An FPoly is a free-standing
32// class which exists independently of any particular level, unlike the polys
33// associated with Bsp nodes which rely on scads of other objects. FPolys are
34// used in UnrealEd for internal work, such as building the Bsp and performing
35// boolean operations.
36//
37class FPoly
38{
39public:
40 // Store up to 16 vertices inline.
42
43 FVector3f Base; // Base point of polygon.
44 FVector3f Normal; // Normal of polygon.
45 FVector3f TextureU; // Texture U vector.
46 FVector3f TextureV; // Texture V vector.
48 uint32 PolyFlags; // FPoly & Bsp poly bit flags (PF_).
49 TObjectPtr<ABrush> Actor; // Brush where this originated, or NULL.
51 FName RulesetVariation; // Name of variation within a ProcBuilding Ruleset for this face
52 FName ItemName; // Item name.
53 int32 iLink; // iBspSurf, or brush fpoly index of first identical polygon, or MAX_uint16.
55 int32 iBrushPoly; // Index of editor solid's polygon this originated from.
56 uint32 SmoothingMask; // A mask used to determine which smoothing groups this polygon is in. SmoothingMask & (1 << GroupNumber)
57 float LightMapScale; // The number of units/shadowmap texel on this surface.
58
59 // This MUST be the format of FLightmassPrimitiveSettings
60 // The Lightmass settings for surfaces generated from this poly
62
67
72 ENGINE_API void Init();
73
77 ENGINE_API void Reverse();
78
83
88
92 ENGINE_API void Scale(const FVector3f &Scale);
93
99
105 ENGINE_API int32 CalcNormal( bool bSilent = 0 );
106
111
114
120
123
126
132 int32 Faces(const FPoly &Test) const;
133
135 ENGINE_API float Area();
136
141 bool DoesLineIntersect( FVector Start, FVector End, FVector* Intersect = NULL );
142
149 bool OnPoly( FVector InVtx );
150
153
156
159
161 ENGINE_API bool IsCoplanar();
162
168 ENGINE_API bool IsConvex();
169
179
188
191
203
204#if WITH_EDITOR
205
207
213
220 template<typename ArrayType>
221 static void OptimizeIntoConvexPolys(ABrush* InOwnerBrush, ArrayType& InPolygons);
222
233 template<typename ArrayType>
234 static void GetOutsideWindings( ABrush* InOwnerBrush, ArrayType& InPolygons, TArray< TArray<FVector3f> >& InWindings )
235 {
236 InWindings.Empty();
238
239 // Break up every polygon passed into triangles
240
241 TArray<FPoly> Triangles;
242
243 for( int32 p = 0 ; p < InPolygons.Num() ; ++p )
244 {
245 FPoly* Poly = &InPolygons[p];
246
248
249 TArray<FPoly> Polys;
250 Poly->Triangulate( InOwnerBrush, Polys );
251
252 Triangles.Append( Polys );
253 }
254
255 // Generate a list of ordered edges that represent the outside winding
256
258
259 for( int32 p = 0 ; p < Triangles.Num() ; ++p )
260 {
261 FPoly* Poly = &Triangles[p];
262
263 // Create a list of edges that are in this shape and set their counts to the number of times they are used.
264
265 for( int32 v = 0 ; v < Poly->Vertices.Num() ; ++v )
266 {
267 const FVector3f vtx0 = Poly->Vertices[v];
268 const FVector3f vtx1 = Poly->Vertices[ (v+1) % Poly->Vertices.Num() ];
269
271
272 int32 idx;
273 if( EdgePool.Find( Edge, idx ) )
274 {
275 EdgePool[idx].Count++;
276 }
277 else
278 {
279 Edge.Count = 1;
280 EdgePool.AddUnique( Edge );
281 }
282 }
283 }
284
285 // Remove any edges from the list that are used more than once. This will leave us with a collection of edges that represents the outside of the brush shape.
286
287 for( int32 e = 0 ; e < EdgePool.Num() ; ++e )
288 {
289 const FEdge* Edge = &EdgePool[e];
290
291 if( Edge->Count > 1 )
292 {
293 EdgePool.RemoveAt( e );
294 e = -1;
295 }
296 }
297
298 // Organize the remaining edges in the list so that the vertices will meet up, start to end, properly to form a continuous outline around the brush shape.
299
300 while( EdgePool.Num() )
301 {
303
304 FEdge Edge0 = EdgePool[0];
305
306 OrderedEdges.Add( Edge0 );
307
308 for( int32 e = 1 ; e < EdgePool.Num() ; ++e )
309 {
310 FEdge Edge1 = EdgePool[e];
311
312 if( Edge0.Vertex[1].Equals( Edge1.Vertex[0] ) )
313 {
314 // If these edges are already lined up correctly then add Edge1 into the ordered array, remove it from the pool and start over.
315
316 OrderedEdges.Add( Edge1 );
317 Edge0 = Edge1;
318 EdgePool.RemoveAt( e );
319 e = -1;
320 }
321 else if( Edge0.Vertex[1].Equals( Edge1.Vertex[1] ) )
322 {
323 // If these edges are lined up but the verts are backwards, swap the verts on Edge1, add it into the ordered array, remove it from the pool and start over.
324
325 Exchange( Edge1.Vertex[0], Edge1.Vertex[1] );
326
327 OrderedEdges.Add( Edge1 );
328 Edge0 = Edge1;
329 EdgePool.RemoveAt( e );
330 e = -1;
331 }
332 }
333
334 // Create a polygon from the first 3 edges. Compare the normal of the original brush shape polygon and see if they match. If
335 // they don't, the list of edges will need to be flipped so it faces the other direction.
336
337 if( OrderedEdges.Num() > 2 )
338 {
340 TestPoly.Init();
341
342 TestPoly.Vertices.Add( (FVector3f)OrderedEdges[0].Vertex[0] );
343 TestPoly.Vertices.Add( (FVector3f)OrderedEdges[1].Vertex[0] );
344 TestPoly.Vertices.Add( (FVector3f)OrderedEdges[2].Vertex[0] );
345
346 if( TestPoly.Finalize( InOwnerBrush, 1 ) == 0 )
347 {
348 if( TestPoly.Normal.Equals( SaveNormal ) == false )
349 {
352
353 for( int32 e = SavedEdges.Num() - 1 ; e > -1 ; --e )
354 {
355 FEdge* Edge = &SavedEdges[e];
356
357 Exchange( Edge->Vertex[0], Edge->Vertex[1] );
358 OrderedEdges.Add( *Edge );
359 }
360 }
361 }
362 }
363
364 // Create the winding array
365
367 for( int32 e = 0 ; e < OrderedEdges.Num() ; ++e )
368 {
369 FEdge* Edge = &OrderedEdges[e];
370
371 WindingVerts.Add( (FVector3f)Edge->Vertex[0] );
372 }
373
375 }
376 }
377#endif // WITH_EDITOR
378
379 // Serializer.
381
382 // Inlines.
384 {return ((Point-Base) | Normal) < 0.f;}
385 int32 IsCoplanar( const FPoly &Test ) const
386 {return FMath::Abs((Base - Test.Base)|Normal)<0.01f && FMath::Abs(Normal|Test.Normal)>0.9999f;}
387
388 friend bool operator==(const FPoly& A,const FPoly& B)
389 {
390 if(A.Vertices.Num() != B.Vertices.Num())
391 {
392 return false;
393 }
394
395 for(int32 VertexIndex = 0;VertexIndex < A.Vertices.Num();VertexIndex++)
396 {
397 if(A.Vertices[VertexIndex] != B.Vertices[VertexIndex])
398 {
399 return false;
400 }
401 }
402
403 return true;
404 }
405 friend bool operator!=(const FPoly& A,const FPoly& B)
406 {
407 return !(A == B);
408 }
409};
410
411UCLASS(customConstructor, MinimalAPI)
413{
415 // Elements.
416 TArray<FPoly> Element;
417
418 // Constructors.
421 , Element( )
422 {}
423
425 UPolys(FVTableHelper& Helper)
426 : Super(Helper)
427 , Element()
428 {}
429
430 //~ Begin UObject Interface
431#if WITH_EDITOR
432 ENGINE_API virtual bool Modify(bool bAlwaysMarkDirty = true) override;
433#endif
434 ENGINE_API virtual void Serialize( FArchive& Ar ) override;
435 virtual bool IsAsset() const override { return false; }
436 static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector);
437 //~ End UObject Interface
438};
#define NULL
Definition oodle2base.h:134
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
@ Vertex
Definition MetalRHIPrivate.h:223
#define GENERATED_UCLASS_BODY(...)
Definition ObjectMacros.h:768
#define UCLASS(...)
Definition ObjectMacros.h:776
ESplitType
Definition Polys.h:23
@ SP_Coplanar
Definition Polys.h:24
@ SP_Split
Definition Polys.h:27
@ SP_Front
Definition Polys.h:25
@ SP_Back
Definition Polys.h:26
#define Split(a, ahi, alo)
Definition Predicates.inl:204
UE_REWRITE constexpr void Exchange(T &A, T &B)
Definition UnrealTemplate.h:627
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition NameTypes.h:617
Definition UObjectGlobals.h:1292
static COREUOBJECT_API FObjectInitializer & Get()
Definition UObjectGlobals.cpp:5001
Definition Polys.h:38
ENGINE_API int32 GetVertexIndex(FVector3f &InVtx)
Definition Polygon.cpp:788
ENGINE_API bool OnPlane(FVector InVtx)
Definition Polygon.cpp:868
FLightmassPrimitiveSettings LightmassSettings
Definition Polys.h:61
uint32 PolyFlags
Definition Polys.h:48
ENGINE_API int32 SplitWithPlaneFast(const FPlane &Plane, FPoly *FrontPoly, FPoly *BackPoly) const
Definition Polygon.cpp:340
ENGINE_API int32 Triangulate(ABrush *InOwnerBrush, TArray< FPoly > &OutTriangles)
Definition Polygon.cpp:724
ENGINE_API FVector GetMidPoint()
Definition Polygon.cpp:806
FVector3f TextureV
Definition Polys.h:46
int32 iBrushPoly
Definition Polys.h:55
ENGINE_API bool IsConvex()
Definition Polygon.cpp:693
ENGINE_API friend FArchive & operator<<(FArchive &Ar, FPoly &Poly)
Definition Model.cpp:130
int32 iLink
Definition Polys.h:53
float LightMapScale
Definition Polys.h:57
ENGINE_API void RemoveVertex(FVector InVtx)
Definition Polygon.cpp:659
int32 IsBackfaced(const FVector3f &Point) const
Definition Polys.h:383
friend bool operator==(const FPoly &A, const FPoly &B)
Definition Polys.h:388
ENGINE_API int32 Fix()
Definition Polygon.cpp:116
ENGINE_API void Reverse()
Definition Polygon.cpp:97
int32 Faces(const FPoly &Test) const
Definition Polygon.cpp:1130
static ENGINE_API FPoly BuildInfiniteFPoly(const FPlane &InPlane)
Definition Polygon.cpp:819
FVector3f Normal
Definition Polys.h:44
bool DoesLineIntersect(FVector Start, FVector End, FVector *Intersect=NULL)
Definition Polygon.cpp:604
int32 iLinkSurf
Definition Polys.h:54
ENGINE_API int32 CalcNormal(bool bSilent=0)
Definition Polygon.cpp:442
FName RulesetVariation
Definition Polys.h:51
FVector3f Base
Definition Polys.h:43
ENGINE_API int32 SplitWithNode(const UModel *Model, int32 iNode, FPoly *FrontPoly, FPoly *BackPoly, int32 VeryPrecise) const
Definition Polygon.cpp:317
ENGINE_API int32 SplitWithPlane(const FVector3f &InBase, const FVector3f &InNormal, FPoly *FrontPoly, FPoly *BackPoly, int32 VeryPrecise) const
Definition Polygon.cpp:169
TArray< FVector3f, TInlineAllocator< 16 > > VerticesArrayType
Definition Polys.h:41
friend bool operator!=(const FPoly &A, const FPoly &B)
Definition Polys.h:405
ENGINE_API void InsertVertex(int32 InPos, FVector InVtx)
Definition Polygon.cpp:651
VerticesArrayType Vertices
Definition Polys.h:47
TObjectPtr< UMaterialInterface > Material
Definition Polys.h:50
ENGINE_API float Area()
Definition Polygon.cpp:144
ENGINE_API void Init()
Definition Polygon.cpp:75
FName ItemName
Definition Polys.h:52
FVector3f TextureU
Definition Polys.h:45
bool OnPoly(FVector InVtx)
Definition Polygon.cpp:628
ENGINE_API int32 RemoveColinears()
Definition Polygon.cpp:526
int32 IsCoplanar(const FPoly &Test) const
Definition Polys.h:385
uint32 SmoothingMask
Definition Polys.h:56
ENGINE_API bool IsCoplanar()
Definition Polygon.cpp:666
ENGINE_API FPoly()
Definition Polygon.cpp:58
TObjectPtr< ABrush > Actor
Definition Polys.h:49
Definition UObjectGlobals.h:2492
Definition ObjectMacros.h:180
Definition Array.h:670
UE_REWRITE SizeType Num() const
Definition Array.h:1144
void Append(const TArray< OtherElementType, OtherAllocatorType > &Source)
Definition Array.h:2412
void Empty(SizeType Slack=0)
Definition Array.h:2273
Definition MaterialInterface.h:296
Definition Model.h:401
Definition Object.h:95
Definition Polys.h:413
Definition TestUtils.cpp:8
float v
Definition radaudio_mdct.cpp:62
Definition Edge.h:12
Definition EngineTypes.h:2167
Definition ObjectPtr.h:488