Skip to content

Commit afbed3d

Browse files
Geometry Primitives: added sphere
1 parent c3e72f4 commit afbed3d

File tree

3 files changed

+90
-20
lines changed

3 files changed

+90
-20
lines changed

Common/interface/GeometryPrimitives.h

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,12 @@ DILIGENT_TYPED_ENUM(GEOMETRY_PRIMITIVE_TYPE, Uint32)
7272
GEOMETRY_PRIMITIVE_TYPE_UNDEFINED = 0u,
7373

7474
/// Cube geometry primitive type.
75-
GEOMETRY_PRIMITIVE_TYPE_CUBE = 1u,
75+
GEOMETRY_PRIMITIVE_TYPE_CUBE,
7676

77-
GEOMETRY_PRIMITIVE_TYPE_LAST = GEOMETRY_PRIMITIVE_TYPE_CUBE
77+
/// Sphere geometry primitive type.
78+
GEOMETRY_PRIMITIVE_TYPE_SPHERE,
79+
80+
GEOMETRY_PRIMITIVE_TYPE_COUNT
7881
};
7982
// clang-format on
8083

@@ -130,6 +133,25 @@ struct CubeGeometryPrimitiveAttributes DILIGENT_DERIVE(GeometryPrimitiveAttribut
130133
};
131134
// clang-format on
132135

136+
137+
/// Sphere geometry primitive attributes.
138+
// clang-format off
139+
struct SphereGeometryPrimitiveAttributes DILIGENT_DERIVE(GeometryPrimitiveAttributes)
140+
141+
/// Sphere radius.
142+
float Radius DEFAULT_INITIALIZER(1.f);
143+
144+
#if DILIGENT_CPP_INTERFACE
145+
explicit SphereGeometryPrimitiveAttributes(float _Radius = 1,
146+
GEOMETRY_PRIMITIVE_VERTEX_FLAGS _VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_ALL,
147+
Uint32 _NumSubdivision = 1) noexcept :
148+
GeometryPrimitiveAttributes{GEOMETRY_PRIMITIVE_TYPE_SPHERE, _VertexFlags, _NumSubdivision},
149+
Radius{_Radius}
150+
{}
151+
#endif
152+
};
153+
// clang-format on
154+
133155
/// Geometry primitive info.
134156
struct GeometryPrimitiveInfo
135157
{
@@ -154,7 +176,7 @@ Uint32 GetGeometryPrimitiveVertexSize(GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlag
154176
/// The vertex components are stored as interleaved floating-point values.
155177
/// For example, if VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_POS_NORM, the vertex data will
156178
/// be stored as follows:
157-
/// P0, N0, P1, N1, ..., Pn, Nn.
179+
/// P0, N0, P1, N1, ..., Pn, Nn.
158180
/// \param [out] ppIndices - Address of the memory location where the pointer to the output index data blob will be stored.
159181
/// Index data is stored as 32-bit unsigned integers representing the triangle list.
160182
/// \param [out] pInfo - A pointer to the structure that will receive information about the created geometry primitive.

Common/src/GeometryPrimitives.cpp

Lines changed: 63 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,14 @@ Uint32 GetGeometryPrimitiveVertexSize(GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlag
4242
((VertexFlags & GEOMETRY_PRIMITIVE_VERTEX_FLAG_TEXCOORD) ? sizeof(float2) : 0));
4343
}
4444

45-
void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
46-
IDataBlob** ppVertices,
47-
IDataBlob** ppIndices,
48-
GeometryPrimitiveInfo* pInfo)
45+
template <typename VertexHandlerType>
46+
void CreateCubeGeometryInternal(Uint32 NumSubdivisions,
47+
GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlags,
48+
IDataBlob** ppVertices,
49+
IDataBlob** ppIndices,
50+
GeometryPrimitiveInfo* pInfo,
51+
VertexHandlerType&& HandleVertex)
4952
{
50-
const float Size = Attribs.Size;
51-
const Uint32 NumSubdivisions = Attribs.NumSubdivisions;
52-
const GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlags = Attribs.VertexFlags;
53-
54-
if (Size <= 0)
55-
{
56-
UNEXPECTED("Size must be positive");
57-
return;
58-
}
5953
if (NumSubdivisions == 0)
6054
{
6155
UNEXPECTED("NumSubdivisions must be positive");
@@ -123,7 +117,6 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
123117
{
124118
if (pVert != nullptr)
125119
{
126-
const float3& Normal = FaceNormals[FaceIndex];
127120
// 6 ______7______ 8
128121
// | .'| .'|
129122
// | .' | .' |
@@ -158,9 +151,11 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
158151
case 5: Pos = float3{+XY.x, XY.y, -0.5f}; break;
159152
}
160153

154+
float3 Normal = FaceNormals[FaceIndex];
155+
HandleVertex(Pos, Normal, UV);
156+
161157
if (VertexFlags & GEOMETRY_PRIMITIVE_VERTEX_FLAG_POSITION)
162158
{
163-
Pos *= Size;
164159
memcpy(pVert, &Pos, sizeof(Pos));
165160
pVert += sizeof(Pos);
166161
}
@@ -214,6 +209,54 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
214209
VERIFY_EXPR(pIdx == nullptr || pIdx == pIndexData->GetConstDataPtr<Uint32>() + IndexDataSize / sizeof(Uint32));
215210
}
216211

212+
void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
213+
IDataBlob** ppVertices,
214+
IDataBlob** ppIndices,
215+
GeometryPrimitiveInfo* pInfo)
216+
{
217+
const float Size = Attribs.Size;
218+
if (Size <= 0)
219+
{
220+
UNEXPECTED("Size must be positive");
221+
return;
222+
}
223+
224+
CreateCubeGeometryInternal(Attribs.NumSubdivisions,
225+
Attribs.VertexFlags,
226+
ppVertices,
227+
ppIndices,
228+
pInfo,
229+
[&](float3& Pos, float3& Normal, float2& UV) {
230+
Pos *= Size;
231+
});
232+
}
233+
234+
void CreateSphereGeometry(const SphereGeometryPrimitiveAttributes& Attribs,
235+
IDataBlob** ppVertices,
236+
IDataBlob** ppIndices,
237+
GeometryPrimitiveInfo* pInfo)
238+
{
239+
const float Radius = Attribs.Radius;
240+
if (Radius <= 0)
241+
{
242+
UNEXPECTED("Radius must be positive");
243+
return;
244+
}
245+
246+
CreateCubeGeometryInternal(Attribs.NumSubdivisions,
247+
Attribs.VertexFlags,
248+
ppVertices,
249+
ppIndices,
250+
pInfo,
251+
[&](float3& Pos, float3& Normal, float2& UV) {
252+
Normal = normalize(Pos);
253+
Pos = Normal * Radius;
254+
255+
UV.x = 0.5f + atan2(Normal.z, Normal.x) / (2 * PI_F);
256+
UV.y = 0.5f - asin(Normal.y) / PI_F;
257+
});
258+
}
259+
217260
void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
218261
IDataBlob** ppVertices,
219262
IDataBlob** ppIndices,
@@ -222,7 +265,7 @@ void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
222265
DEV_CHECK_ERR(ppVertices == nullptr || *ppVertices == nullptr, "*ppVertices is not null which may cause memory leaks");
223266
DEV_CHECK_ERR(ppIndices == nullptr || *ppIndices == nullptr, "*ppIndices is not null which may cause memory leaks");
224267

225-
static_assert(GEOMETRY_PRIMITIVE_TYPE_LAST == 1, "Please update the switch below to handle the new geometry primitive type");
268+
static_assert(GEOMETRY_PRIMITIVE_TYPE_COUNT == 3, "Please update the switch below to handle the new geometry primitive type");
226269
switch (Attribs.Type)
227270
{
228271
case GEOMETRY_PRIMITIVE_TYPE_UNDEFINED:
@@ -233,6 +276,10 @@ void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
233276
CreateCubeGeometry(static_cast<const CubeGeometryPrimitiveAttributes&>(Attribs), ppVertices, ppIndices, pInfo);
234277
break;
235278

279+
case GEOMETRY_PRIMITIVE_TYPE_SPHERE:
280+
CreateSphereGeometry(static_cast<const SphereGeometryPrimitiveAttributes&>(Attribs), ppVertices, ppIndices, pInfo);
281+
break;
282+
236283
default:
237284
UNEXPECTED("Unknown geometry primitive type");
238285
}

Graphics/GraphicsTools/src/GraphicsUtilities.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,7 +667,7 @@ void CreateGeometryPrimitiveBuffers(IRenderDevice* pD
667667
IBuffer** ppIndices,
668668
GeometryPrimitiveInfo* pInfo)
669669
{
670-
static_assert(GEOMETRY_PRIMITIVE_TYPE_LAST == 1, "Please handle the new primitive type");
670+
static_assert(GEOMETRY_PRIMITIVE_TYPE_COUNT == 3, "Please handle the new primitive type");
671671

672672
RefCntAutoPtr<IDataBlob> pVertexData;
673673
RefCntAutoPtr<IDataBlob> pIndexData;
@@ -684,6 +684,7 @@ void CreateGeometryPrimitiveBuffers(IRenderDevice* pD
684684
switch (Attribs.Type)
685685
{
686686
case GEOMETRY_PRIMITIVE_TYPE_CUBE: PrimTypeStr = "Cube"; break;
687+
case GEOMETRY_PRIMITIVE_TYPE_SPHERE: PrimTypeStr = "Sphere"; break;
687688
default: UNEXPECTED("Unexpected primitive type");
688689
}
689690

0 commit comments

Comments
 (0)