Skip to content

Instantly share code, notes, and snippets.

@deccer
Created January 31, 2025 23:31
Show Gist options
  • Save deccer/c5a751d80db2b238a30e6cb580ff858d to your computer and use it in GitHub Desktop.
Save deccer/c5a751d80db2b238a30e6cb580ff858d to your computer and use it in GitHub Desktop.
how to use mikktspace.md
FetchContent_Declare(
    mikktspace
    GIT_REPOSITORY  https://github.com/mmikk/MikkTSpace/
    GIT_TAG         master
    GIT_SHALLOW     TRUE
    GIT_PROGRESS    TRUE
)
FetchContent_GetProperties(mikktspace)
if(NOT mikktspace_POPULATED)
    FetchContent_MakeAvailable(mikktspace)
    message("Fetching mikktspace")

    add_library(mikktspace
        ${mikktspace_SOURCE_DIR}/mikktspace.c
    )
    target_include_directories(mikktspace
        PUBLIC ${mikktspace_SOURCE_DIR}
    )

endif()
#include <mikktspace.h>

auto CalculateTangents(TAssetMeshData& assetMeshData) -> void {

    auto getNumFaces = [](const SMikkTSpaceContext* context) -> int32_t {

        auto* meshData = static_cast<TAssetMeshData*>(context->m_pUserData);
        return meshData->Indices.size() / 3;
    };

    auto getNumVerticesOfFace = [](
        const SMikkTSpaceContext* context,
        const int32_t iFace) -> int32_t {

        return 3;
    };

    auto getPosition = [](
        const SMikkTSpaceContext* context,
        float posOut[],
        const int32_t faceIndex,
        const int32_t vertIndex) -> void {

        auto* meshData = static_cast<TAssetMeshData*>(context->m_pUserData);
        auto index = meshData->Indices[faceIndex * 3 + vertIndex];
        const glm::vec3& pos = meshData->Positions[index];
        posOut[0] = pos.x;
        posOut[1] = pos.y;
        posOut[2] = pos.z;
    };

    auto getNormal = [](
        const SMikkTSpaceContext* context,
        float normOut[],
        const int32_t faceIndex,
        const int32_t vertIndex) -> void {

        auto* meshData = static_cast<TAssetMeshData*>(context->m_pUserData);
        auto index = meshData->Indices[faceIndex * 3 + vertIndex];
        const glm::vec3& normal = meshData->Normals[index];
        normOut[0] = normal.x;
        normOut[1] = normal.y;
        normOut[2] = normal.z;
    };

    auto getUv = [](
        const SMikkTSpaceContext* context,
        float uvOut[],
        const int32_t faceIndex,
        const int32_t vertIndex) -> void {

        auto* meshData = static_cast<TAssetMeshData*>(context->m_pUserData);
        auto index = meshData->Indices[faceIndex * 3 + vertIndex];
        const glm::vec2& uv = meshData->Uvs[index];
        uvOut[0] = uv.x;
        uvOut[1] = uv.y;
    };

    auto setTSpaceBasic = [](
        const SMikkTSpaceContext* context,
        const float tangent[],
        const float sign,
        const int32_t faceIndex,
        const int32_t vertIndex) {

        auto* meshData = static_cast<TAssetMeshData*>(context->m_pUserData);
        auto index = meshData->Indices[faceIndex * 3 + vertIndex];

        glm::vec3 t(tangent[0], tangent[1], tangent[2]);
        meshData->Tangents[index] = glm::vec4(glm::normalize(t), sign);
    };

    SMikkTSpaceInterface interface = {
        .m_getNumFaces = getNumFaces,
        .m_getNumVerticesOfFace = getNumVerticesOfFace,
        .m_getPosition = getPosition,
        .m_getNormal = getNormal,
        .m_getTexCoord = getUv,
        .m_setTSpaceBasic = setTSpaceBasic,
    };

    SMikkTSpaceContext context = {
        .m_pInterface = &interface,
        .m_pUserData = &assetMeshData
    };

    genTangSpaceDefault(&context);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment