Skip to content

Commit

Permalink
Geometry Primitives: added sphere
Browse files Browse the repository at this point in the history
  • Loading branch information
TheMostDiligent committed Dec 29, 2024
1 parent c3e72f4 commit afbed3d
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 20 deletions.
28 changes: 25 additions & 3 deletions Common/interface/GeometryPrimitives.h
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,12 @@ DILIGENT_TYPED_ENUM(GEOMETRY_PRIMITIVE_TYPE, Uint32)
GEOMETRY_PRIMITIVE_TYPE_UNDEFINED = 0u,

/// Cube geometry primitive type.
GEOMETRY_PRIMITIVE_TYPE_CUBE = 1u,
GEOMETRY_PRIMITIVE_TYPE_CUBE,

GEOMETRY_PRIMITIVE_TYPE_LAST = GEOMETRY_PRIMITIVE_TYPE_CUBE
/// Sphere geometry primitive type.
GEOMETRY_PRIMITIVE_TYPE_SPHERE,

GEOMETRY_PRIMITIVE_TYPE_COUNT
};
// clang-format on

Expand Down Expand Up @@ -130,6 +133,25 @@ struct CubeGeometryPrimitiveAttributes DILIGENT_DERIVE(GeometryPrimitiveAttribut
};
// clang-format on


/// Sphere geometry primitive attributes.
// clang-format off
struct SphereGeometryPrimitiveAttributes DILIGENT_DERIVE(GeometryPrimitiveAttributes)

/// Sphere radius.
float Radius DEFAULT_INITIALIZER(1.f);

#if DILIGENT_CPP_INTERFACE
explicit SphereGeometryPrimitiveAttributes(float _Radius = 1,
GEOMETRY_PRIMITIVE_VERTEX_FLAGS _VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_ALL,
Uint32 _NumSubdivision = 1) noexcept :
GeometryPrimitiveAttributes{GEOMETRY_PRIMITIVE_TYPE_SPHERE, _VertexFlags, _NumSubdivision},
Radius{_Radius}
{}
#endif
};
// clang-format on

/// Geometry primitive info.
struct GeometryPrimitiveInfo
{
Expand All @@ -154,7 +176,7 @@ Uint32 GetGeometryPrimitiveVertexSize(GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlag
/// The vertex components are stored as interleaved floating-point values.
/// For example, if VertexFlags = GEOMETRY_PRIMITIVE_VERTEX_FLAG_POS_NORM, the vertex data will
/// be stored as follows:
/// P0, N0, P1, N1, ..., Pn, Nn.
/// P0, N0, P1, N1, ..., Pn, Nn.
/// \param [out] ppIndices - Address of the memory location where the pointer to the output index data blob will be stored.
/// Index data is stored as 32-bit unsigned integers representing the triangle list.
/// \param [out] pInfo - A pointer to the structure that will receive information about the created geometry primitive.
Expand Down
79 changes: 63 additions & 16 deletions Common/src/GeometryPrimitives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,20 +42,14 @@ Uint32 GetGeometryPrimitiveVertexSize(GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlag
((VertexFlags & GEOMETRY_PRIMITIVE_VERTEX_FLAG_TEXCOORD) ? sizeof(float2) : 0));
}

void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
GeometryPrimitiveInfo* pInfo)
template <typename VertexHandlerType>
void CreateCubeGeometryInternal(Uint32 NumSubdivisions,
GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlags,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
GeometryPrimitiveInfo* pInfo,
VertexHandlerType&& HandleVertex)
{
const float Size = Attribs.Size;
const Uint32 NumSubdivisions = Attribs.NumSubdivisions;
const GEOMETRY_PRIMITIVE_VERTEX_FLAGS VertexFlags = Attribs.VertexFlags;

if (Size <= 0)
{
UNEXPECTED("Size must be positive");
return;
}
if (NumSubdivisions == 0)
{
UNEXPECTED("NumSubdivisions must be positive");
Expand Down Expand Up @@ -123,7 +117,6 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
{
if (pVert != nullptr)
{
const float3& Normal = FaceNormals[FaceIndex];
// 6 ______7______ 8
// | .'| .'|
// | .' | .' |
Expand Down Expand Up @@ -158,9 +151,11 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
case 5: Pos = float3{+XY.x, XY.y, -0.5f}; break;
}

float3 Normal = FaceNormals[FaceIndex];
HandleVertex(Pos, Normal, UV);

if (VertexFlags & GEOMETRY_PRIMITIVE_VERTEX_FLAG_POSITION)
{
Pos *= Size;
memcpy(pVert, &Pos, sizeof(Pos));
pVert += sizeof(Pos);
}
Expand Down Expand Up @@ -214,6 +209,54 @@ void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
VERIFY_EXPR(pIdx == nullptr || pIdx == pIndexData->GetConstDataPtr<Uint32>() + IndexDataSize / sizeof(Uint32));
}

void CreateCubeGeometry(const CubeGeometryPrimitiveAttributes& Attribs,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
GeometryPrimitiveInfo* pInfo)
{
const float Size = Attribs.Size;
if (Size <= 0)
{
UNEXPECTED("Size must be positive");
return;
}

CreateCubeGeometryInternal(Attribs.NumSubdivisions,
Attribs.VertexFlags,
ppVertices,
ppIndices,
pInfo,
[&](float3& Pos, float3& Normal, float2& UV) {
Pos *= Size;
});
}

void CreateSphereGeometry(const SphereGeometryPrimitiveAttributes& Attribs,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
GeometryPrimitiveInfo* pInfo)
{
const float Radius = Attribs.Radius;
if (Radius <= 0)
{
UNEXPECTED("Radius must be positive");
return;
}

CreateCubeGeometryInternal(Attribs.NumSubdivisions,
Attribs.VertexFlags,
ppVertices,
ppIndices,
pInfo,
[&](float3& Pos, float3& Normal, float2& UV) {
Normal = normalize(Pos);
Pos = Normal * Radius;

UV.x = 0.5f + atan2(Normal.z, Normal.x) / (2 * PI_F);
UV.y = 0.5f - asin(Normal.y) / PI_F;
});
}

void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
IDataBlob** ppVertices,
IDataBlob** ppIndices,
Expand All @@ -222,7 +265,7 @@ void CreateGeometryPrimitive(const GeometryPrimitiveAttributes& Attribs,
DEV_CHECK_ERR(ppVertices == nullptr || *ppVertices == nullptr, "*ppVertices is not null which may cause memory leaks");
DEV_CHECK_ERR(ppIndices == nullptr || *ppIndices == nullptr, "*ppIndices is not null which may cause memory leaks");

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

case GEOMETRY_PRIMITIVE_TYPE_SPHERE:
CreateSphereGeometry(static_cast<const SphereGeometryPrimitiveAttributes&>(Attribs), ppVertices, ppIndices, pInfo);
break;

default:
UNEXPECTED("Unknown geometry primitive type");
}
Expand Down
3 changes: 2 additions & 1 deletion Graphics/GraphicsTools/src/GraphicsUtilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -667,7 +667,7 @@ void CreateGeometryPrimitiveBuffers(IRenderDevice* pD
IBuffer** ppIndices,
GeometryPrimitiveInfo* pInfo)
{
static_assert(GEOMETRY_PRIMITIVE_TYPE_LAST == 1, "Please handle the new primitive type");
static_assert(GEOMETRY_PRIMITIVE_TYPE_COUNT == 3, "Please handle the new primitive type");

RefCntAutoPtr<IDataBlob> pVertexData;
RefCntAutoPtr<IDataBlob> pIndexData;
Expand All @@ -684,6 +684,7 @@ void CreateGeometryPrimitiveBuffers(IRenderDevice* pD
switch (Attribs.Type)
{
case GEOMETRY_PRIMITIVE_TYPE_CUBE: PrimTypeStr = "Cube"; break;
case GEOMETRY_PRIMITIVE_TYPE_SPHERE: PrimTypeStr = "Sphere"; break;
default: UNEXPECTED("Unexpected primitive type");
}

Expand Down

0 comments on commit afbed3d

Please sign in to comment.