UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
SphereGenerator.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
6#include "OrientedBoxTypes.h"
7#include "Util/IndexUtil.h"
8
9namespace UE
10{
11namespace Geometry
12{
13
17class /*GEOMETRYCORE_API*/ FSphereGenerator : public FMeshShapeGenerator
18{
19public:
21 double Radius = 1;
22
23 int NumPhi = 3; // number of vertices along vertical extent from north pole to south pole
24 int NumTheta = 3; // number of vertices around circles
25
27 bool bPolygroupPerQuad = false;
28
29private:
30 static FVector3d SphericalToCartesian(double r, double theta, double phi)
31 {
32 double Sphi = sin(phi);
33 double Cphi = cos(phi);
34 double Ctheta = cos(theta);
35 double Stheta = sin(theta);
36
37 return FVector3d(r * Ctheta * Sphi, r * Stheta * Sphi, r * Cphi);
38 }
39
40 void GenerateVertices()
41 {
42 auto SetVertex = [this](int32 VtxIdx,
44 {
45 Vertices[VtxIdx] = Pos;
48 };
49 {
50 const double Dphi = FMathd::Pi / double(NumPhi - 1);
51 const double Dtheta = FMathd::TwoPi / double(NumTheta);
52
53 int32 p,t;
54 double Phi, Theta;
55 int32 VtxIdx = 0;
56
57 // Add points between the poles
58 for (p = 1, Phi = Dphi; p < NumPhi - 1; ++p, Phi += Dphi) // NB: this skips the poles.
59 {
60 for (t = 0, Theta = 0; t < NumTheta; ++t, ++VtxIdx, Theta += Dtheta)
61 {
62 FVector3d Normal = SphericalToCartesian(1., Theta, Phi);
64 }
65 }
66 // add a single point at the North Pole
68 // add a single point at the South Pole
70 }
71 }
72
73 void GenerateUVVertices()
74 {
75 // generate the UV's
76 const float DUVphi = 1.f / float(NumPhi - 1);
77 const float DUVtheta = -1.f / float(NumTheta);
78
79 int32 UVIdx = 0;
80 int32 p,t;
81 float UVPhi, UVTheta;
82 for ( p = 1, UVPhi = DUVphi; p < NumPhi - 1; ++p, UVPhi += DUVphi)
83 {
84 for (t = 0, UVTheta = 1; t < NumTheta; ++t, ++UVIdx, UVTheta += DUVtheta)
85 {
87 UVParentVertex[UVIdx] = (p - 1) * NumTheta + t;
88 }
90 UVParentVertex[UVIdx] = (p - 1) * NumTheta; // Wrap around
91 ++UVIdx;
92 }
94 for (t = 0, UVTheta = 1 + DUVtheta; t < NumTheta; ++t, ++UVIdx, UVTheta += DUVtheta)
95 {
96 UVs[UVIdx] = FVector2f(UVTheta, 0.0);
98 }
100 for (t = 0, UVTheta = 1 + DUVtheta; t < NumTheta; ++t, ++UVIdx, UVTheta += DUVtheta)
101 {
102 UVs[UVIdx] = FVector2f(UVTheta, 1.0);
104 }
105 }
106
107 using CornerIndices = FVector3i;
108 void OutputTriangle(int TriIdx, int PolyIdx, CornerIndices Corners, CornerIndices UVCorners)
109 {
110 SetTriangle(TriIdx, Corners.X, Corners.Y, Corners.Z);
113 SetTriangleNormals(TriIdx, Corners.X, Corners.Y, Corners.Z);
114 }
115
116 void OutputEquatorialTriangles()
117 {
118 int32 TriIdx = 0, PolyIdx = 0;
119
120 // Generate equatorial triangles
121 int32 Corners[4] = { 0, 1, NumTheta + 1, NumTheta};
122 int32 UVCorners[4] = { 0, 1, NumTheta + 2, NumTheta + 1};
123 for (int32 p = 1; p < NumPhi - 2; ++p)
124 {
125 for (int32 t = 0; t < NumTheta - 1; ++t)
126 {
127 // convert each quad into 2 triangles.
128 OutputTriangle(TriIdx++, PolyIdx,
129 {Corners[0], Corners[1], Corners[2]},
130 {UVCorners[0], UVCorners[1], UVCorners[2]});
131 OutputTriangle(TriIdx++, PolyIdx,
132 {Corners[2], Corners[3], Corners[0]},
133 {UVCorners[2], UVCorners[3], UVCorners[0]});
134 for (auto& i : Corners) ++i;
135 for (auto& i : UVCorners) ++i;
137 {
138 PolyIdx++;
139 }
140 }
141 OutputTriangle(TriIdx++, PolyIdx,
142 {Corners[0], Corners[1] - NumTheta, Corners[2] - NumTheta},
143 {UVCorners[0] , UVCorners[1], UVCorners[2] });
144 OutputTriangle(TriIdx++, PolyIdx,
145 {Corners[2] - NumTheta, Corners[3], Corners[0]},
146 {UVCorners[2], UVCorners[3], UVCorners[0]});
147 for (auto& i : Corners) ++i;
148 for (auto& i : UVCorners) i += 2;
150 {
151 PolyIdx++;
152 }
153 }
154 }
155
156 void OutputPolarTriangles()
157 {
158 const int32 NumEquatorialVtx = (NumPhi - 2) * NumTheta;
159 const int32 NumEquatorialUVVtx = (NumPhi - 2) * (NumTheta + 1);
162 int32 PolyIdx = NumTheta * (NumPhi - 3);
163 int32 TriIdx = PolyIdx * 2;
164 if (bPolygroupPerQuad == false)
165 {
166 PolyIdx = 0;
167 }
168
169 // Triangles that connect to north pole
170 for (int32 t = 0; t < NumTheta; ++t)
171 {
172 OutputTriangle(TriIdx++, PolyIdx,
173 {t, NorthPoleVtxIdx, (t + 1) % NumTheta},
174 {t, NumEquatorialUVVtx + t, t + 1});
176 {
177 PolyIdx++;
178 }
179 }
180
181 // Triangles that connect to South pole
184 for (int32 t = 0; t < NumTheta; ++t)
185 {
186 OutputTriangle(TriIdx++, PolyIdx,
187 {t + Offset, ((t + 1) % NumTheta) + Offset, SouthPoleVtxIdx},
188 {t + OffsetUV, t + 1 + OffsetUV , NumEquatorialUVVtx + NumTheta + t});
190 {
191 PolyIdx++;
192 }
193 }
194 }
195public:
198 {
199 // enforce sane values for vertex counts
200 NumPhi = FMath::Max(NumPhi, 3);
201 NumTheta = FMath::Max(NumTheta, 3);
202 const int32 NumVertices = (NumPhi - 2) * NumTheta + 2;
203 const int32 NumUVs = (NumPhi - 2) * (NumTheta + 1) + (2 * NumTheta);
204 const int32 NumTris = (NumPhi - 2) * NumTheta * 2;
205 SetBufferSizes(NumVertices, NumTris, NumUVs, NumVertices);
206
207 GenerateVertices();
208 GenerateUVVertices();
209 OutputEquatorialTriangles();
210 OutputPolarTriangles();
211 return *this;
212 }
213
214
215};
216
217
218} // end namespace UE::Geometry
219} // end namespace UE
@ Normal
Definition AndroidInputInterface.h:116
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
UE::Math::TVector2< float > FVector2f
Definition MathFwd.h:74
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
UE::Math::TVector< double > FVector3d
Definition MathFwd.h:60
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
uint32 Offset
Definition VulkanMemory.cpp:4033
Definition MeshShapeGenerator.h:19
TArray< FVector2f > UVs
Definition MeshShapeGenerator.h:25
TArray< int > UVParentVertex
Definition MeshShapeGenerator.h:27
TArray< FVector3d > Vertices
Definition MeshShapeGenerator.h:22
TArray< FVector3f > Normals
Definition MeshShapeGenerator.h:30
void SetTriangle(int Index, const FIndex3i &Tri)
Definition MeshShapeGenerator.h:193
void SetVertex(int Index, const FVector3d &Position)
Definition MeshShapeGenerator.h:155
void SetTriangleUVs(int Index, const FIndex3i &Tri)
Definition MeshShapeGenerator.h:217
TArray< int > NormalParentVertex
Definition MeshShapeGenerator.h:32
void SetTrianglePolygon(int Index, int PolygonID)
Definition MeshShapeGenerator.h:244
void SetTriangleNormals(int Index, const FIndex3i &Tri)
Definition MeshShapeGenerator.h:231
void SetBufferSizes(int NumVertices, int NumTriangles, int NumUVs, int NumNormals)
Definition MeshShapeGenerator.h:97
Definition SphereGenerator.h:18
FMeshShapeGenerator & Generate() override
Definition SphereGenerator.h:197
int NumTheta
Definition SphereGenerator.h:24
int NumPhi
Definition SphereGenerator.h:23
bool bPolygroupPerQuad
Definition SphereGenerator.h:27
double Radius
Definition SphereGenerator.h:21
Definition AdvancedWidgetsModule.cpp:13
static TVector< double > UnitZ()
Definition Vector.h:124