Program Listing for File ObjectDescription.ixx

Program Listing for File ObjectDescription.ixx#

Return to documentation for file (Src/GraphicsEngineVulkan/scene/ObjectDescription.ixx)

module;

#include "ObjectDescription.hpp"
#include <algorithm>
#include <cstdint>
#include <span>
#include <vector>

export module kataglyphis.vulkan.object_description;

export using ::ObjectDescription;

export namespace Kataglyphis {

inline void assignTextureOffsets(std::span<ObjectDescription> descriptions,
  std::span<const uint32_t> meshCountPerModel,
  std::span<const uint32_t> textureCountPerModel)
{
    const std::size_t modelCount = std::min(meshCountPerModel.size(), textureCountPerModel.size());
    std::size_t descIndex = 0;
    uint64_t offset = 0;
    for (std::size_t m = 0; m < modelCount; ++m) {
        for (uint32_t k = 0; k < meshCountPerModel[m]; ++k) {
            if (descIndex >= descriptions.size()) { return; }
            descriptions[descIndex].texture_offset = offset;
            ++descIndex;
        }
        offset += textureCountPerModel[m];
    }
}

inline std::vector<uint32_t> meshBaseOffsets(std::span<const uint32_t> meshCountPerModel)
{
    std::vector<uint32_t> offsets;
    offsets.reserve(meshCountPerModel.size());
    uint32_t offset = 0;
    for (const uint32_t meshCount : meshCountPerModel) {
        offsets.push_back(offset);
        offset += meshCount;
    }
    return offsets;
}

struct FlattenedTextureSlot
{
    uint32_t model;
    uint32_t indexInModel;

    bool operator==(const FlattenedTextureSlot &) const = default;
};

struct FlattenedTexturePlan
{
    std::vector<FlattenedTextureSlot> slots;
    uint32_t requestedCount;
    bool exhausted;
};

inline FlattenedTexturePlan planFlattenedTextureSlots(std::span<const uint32_t> textureCountPerModel, uint32_t maxSlots)
{
    FlattenedTexturePlan plan{ .slots = {}, .requestedCount = 0, .exhausted = false };

    for (uint32_t model = 0; model < textureCountPerModel.size(); ++model) {
        plan.requestedCount += textureCountPerModel[model];
    }

    for (uint32_t model = 0; model < textureCountPerModel.size(); ++model) {
        const uint32_t modelTextureCount = textureCountPerModel[model];
        for (uint32_t t = 0; t < modelTextureCount; ++t) {
            if (plan.slots.size() >= maxSlots) {
                plan.exhausted = true;
                break;
            }
            plan.slots.push_back(FlattenedTextureSlot{ .model = model, .indexInModel = t });
        }
        if (plan.exhausted) { break; }
    }

    if (plan.slots.empty()) { return plan; }

    const FlattenedTextureSlot firstSlot = plan.slots.front();
    while (plan.slots.size() < maxSlots) {
        plan.slots.push_back(firstSlot);
    }

    return plan;
}

}// namespace Kataglyphis