UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
CapsuleGenerator.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
14
26class /*GEOMETRYCORE_API*/ FCapsuleGenerator : public FMeshShapeGenerator
27{
28public:
30 double Radius = 1.0;
31
33 double SegmentLength = 1.0;
34
37
40
43
45 bool bPolygroupPerQuad = false;
46
47private:
48 static FVector3d SphericalToCartesian(double r, double theta, double phi)
49 {
50 double Sphi = sin(phi);
51 double Cphi = cos(phi);
52 double Ctheta = cos(theta);
53 double Stheta = sin(theta);
54
55 return FVector3d(r * Ctheta * Sphi, r * Stheta * Sphi, r * Cphi);
56 }
57
58 void GenerateVertices()
59 {
60 auto SetVertex = [this](int32 VtxIdx,
62 {
63 Vertices[VtxIdx] = Pos;
66 };
67 {
68 const double Dphi = FMathd::HalfPi / double(NumHemisphereArcSteps - 1);
69 const double Dtheta = FMathd::TwoPi / double(NumCircleSteps);
70
71 int32 VtxIdx = 0;
72 double Phi, Theta;
73 int32 p, t;
74
76
77 // add points for first arc section
78 for (p = 1, Phi = Dphi; p < NumHemisphereArcSteps; ++p, Phi += Dphi) // NB: this skips the poles.
79 {
80 for (t = 0, Theta = 0; t < NumCircleSteps; ++t, ++VtxIdx, Theta += Dtheta)
81 {
82 FVector3d Normal = SphericalToCartesian(1., Theta, Phi);
84 }
85 }
86
87 // add intermediate loops along the cylindrical section
88 double SegStepSize = 1.0 / (double)(NumSegmentSteps + 1.0);
89 double SegAlong = SegStepSize;
91 {
92 for (t = 0, Theta = 0; t < NumCircleSteps; ++t, ++VtxIdx, Theta += Dtheta)
93 {
94 FVector3d Normal(FMath::Cos(Theta), FMath::Sin(Theta), 0.0);
96 }
97 }
98
99 // add points for second arc section
100 for (p = 1, Phi = FMathd::HalfPi; p < NumHemisphereArcSteps; ++p, Phi += Dphi) // NB: this skips the poles.
101 {
102 for (t = 0, Theta = 0; t < NumCircleSteps; ++t, ++VtxIdx, Theta += Dtheta)
103 {
104 FVector3d Normal = SphericalToCartesian(1., Theta, Phi);
106 }
107 }
108 // add a single point at the North Pole
110 // add a single point at the South Pole
112 }
113 }
114
115 void GenerateUVVertices()
116 {
117 // generate the UVs
119 const float DUVtheta = -1.0f / float(NumCircleSteps);
120 int32 UVIdx = 0;
121
122 // helper to add UVs for a given range in Phi
123 auto AddUVSpan = [this, &UVIdx, DUVtheta](int32 StepStart, int32 NumSteps, float PhiStart, float PhiStepSize)
124 {
125 float UVPhi = PhiStart;
127 for (; PIdx < StepStart + NumSteps; ++PIdx, UVPhi += PhiStepSize)
128 {
129 float UVTheta = 1;
130 for (int32 t = 0; t < NumCircleSteps; ++t, ++UVIdx, UVTheta += DUVtheta)
131 {
134 }
136 UVParentVertex[UVIdx] = PIdx * NumCircleSteps; // Wrap around
137 ++UVIdx;
138 }
139 return PIdx;
140 };
141
142 const float PhiSpan = static_cast<float>(2 * Radius + SegmentLength);
143 const float HemisphereStepSize = static_cast<float>(Radius) / (PhiSpan * static_cast<float>(NumHemisphereArcSteps - 1));
144 // add the first hemisphere cap (except the pole)
146
147 // add the cylindrical section
148 const float SegmentStepSize = static_cast<float>(SegmentLength) / (PhiSpan * static_cast<float>(NumSegmentSteps + 1));
150
151 // add the closing hemisphere end-cap (except the pole)
153
155 float UVTheta;
156 int32 t;
157 for (t = 0, UVTheta = 1 + DUVtheta; t < NumCircleSteps; ++t, ++UVIdx, UVTheta += DUVtheta)
158 {
159 UVs[UVIdx] = FVector2f(UVTheta, 0.0);
161 }
163 for (t = 0, UVTheta = 1 + DUVtheta; t < NumCircleSteps; ++t, ++UVIdx, UVTheta += DUVtheta)
164 {
165 UVs[UVIdx] = FVector2f(UVTheta, 1.0);
167 }
168 }
169
170 using CornerIndices = FVector3i;
171 void OutputTriangle(int TriIdx, int PolyIdx, CornerIndices Corners, CornerIndices UVCorners)
172 {
173 SetTriangle(TriIdx, Corners.X, Corners.Y, Corners.Z);
176 SetTriangleNormals(TriIdx, Corners.X, Corners.Y, Corners.Z);
177 }
178
179 void OutputEquatorialTriangles()
180 {
182 int32 TriIdx = 0, PolyIdx = 0;
183
184 // Generate equatorial triangles
185 int32 Corners[4] = { 0, 1, NumCircleSteps + 1, NumCircleSteps};
186 int32 UVCorners[4] = { 0, 1, NumCircleSteps + 2, NumCircleSteps + 1};
187 for (int32 p = 1; p < NumPhi - 2; ++p)
188 {
189 for (int32 t = 0; t < NumCircleSteps - 1; ++t)
190 {
191 // convert each quad into 2 triangles.
192 OutputTriangle(TriIdx++, PolyIdx,
193 {Corners[0], Corners[1], Corners[2]},
194 {UVCorners[0], UVCorners[1], UVCorners[2]});
195 OutputTriangle(TriIdx++, PolyIdx,
196 {Corners[2], Corners[3], Corners[0]},
197 {UVCorners[2], UVCorners[3], UVCorners[0]});
198 for (int32& i : Corners) ++i;
199 for (int32& i : UVCorners) ++i;
201 {
202 PolyIdx++;
203 }
204 }
205 OutputTriangle(TriIdx++, PolyIdx,
206 {Corners[0], Corners[1] - NumCircleSteps, Corners[2] - NumCircleSteps},
207 {UVCorners[0] , UVCorners[1], UVCorners[2] });
208 OutputTriangle(TriIdx++, PolyIdx,
209 {Corners[2] - NumCircleSteps, Corners[3], Corners[0]},
210 {UVCorners[2], UVCorners[3], UVCorners[0]});
211 for (int32& i : Corners) ++i;
212 for (int32& i : UVCorners) i += 2;
214 {
215 PolyIdx++;
216 }
217 }
218 }
219
220 void OutputPolarTriangles()
221 {
223 const int32 NumEquatorialVtx = (NumPhi - 2) * NumCircleSteps;
224 const int32 NumEquatorialUVVtx = (NumPhi - 2) * (NumCircleSteps + 1);
227 int32 PolyIdx = (NumCircleSteps * (NumPhi - 3));
228 int32 TriIdx = PolyIdx * 2;
229 if (bPolygroupPerQuad == false)
230 {
231 PolyIdx = 0;
232 }
233
234 // Triangles that connect to north pole
235 for (int32 t = 0; t < NumCircleSteps; ++t)
236 {
237 OutputTriangle(TriIdx++, PolyIdx,
238 {t, NorthPoleVtxIdx, (t + 1) % NumCircleSteps},
239 {t, NumEquatorialUVVtx + t, t + 1});
241 {
242 PolyIdx++;
243 }
244 }
245
246 // Triangles that connect to South pole
249 for (int32 t = 0; t < NumCircleSteps; ++t)
250 {
251 OutputTriangle(TriIdx++, PolyIdx,
252 {t + Offset, ((t + 1) % NumCircleSteps) + Offset, SouthPoleVtxIdx},
253 {t + OffsetUV, t + 1 + OffsetUV , NumEquatorialUVVtx + NumCircleSteps + t});
255 {
256 PolyIdx++;
257 }
258 }
259 }
260public:
263 {
264 // enforce sane values for vertex counts
266 int32 NumPhi = (2 * NumHemisphereArcSteps);
267 NumCircleSteps = FMath::Max(NumCircleSteps, 3);
268 const int32 NumVertices = (NumPhi - 2 + NumSegmentSteps) * NumCircleSteps + 2;
269 const int32 NumUVs = (NumPhi - 2 + NumSegmentSteps) * (NumCircleSteps + 1) + (2 * NumCircleSteps);
270 const int32 NumTris = (NumPhi - 2 + NumSegmentSteps) * NumCircleSteps * 2;
271 SetBufferSizes(NumVertices, NumTris, NumUVs, NumVertices);
272
273 GenerateVertices();
274 GenerateUVVertices();
275 OutputEquatorialTriangles();
276 OutputPolarTriangles();
277 return *this;
278 }
279};
280
281
282} // end namespace UE::Geometry
283} // 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 CapsuleGenerator.h:27
int NumCircleSteps
Definition CapsuleGenerator.h:39
int NumSegmentSteps
Definition CapsuleGenerator.h:42
int NumHemisphereArcSteps
Definition CapsuleGenerator.h:36
FMeshShapeGenerator & Generate() override
Definition CapsuleGenerator.h:262
double SegmentLength
Definition CapsuleGenerator.h:33
bool bPolygroupPerQuad
Definition CapsuleGenerator.h:45
double Radius
Definition CapsuleGenerator.h:30
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 AdvancedWidgetsModule.cpp:13
static TVector< double > UnitZ()
Definition Vector.h:124