in UVAtlas/isochart/UVAtlas.cpp [1239:1367]
HRESULT __cdecl DirectX::UVAtlasComputeIMTFromTexture(
const XMFLOAT3* positions,
const XMFLOAT2* texcoords,
size_t nVerts,
const void* indices,
DXGI_FORMAT indexFormat,
size_t nFaces,
const float* pTexture,
size_t width,
size_t height,
UVATLAS_IMT options,
std::function<HRESULT __cdecl(float percentComplete)> statusCallBack,
float* pIMTArray)
{
if (!positions || !texcoords || !nVerts || !indices || !nFaces || !pTexture || !pIMTArray)
return E_INVALIDARG;
if (!width || !height)
return E_INVALIDARG;
if ((width > UINT32_MAX) || (height > UINT32_MAX))
return E_INVALIDARG;
switch (indexFormat)
{
case DXGI_FORMAT_R16_UINT:
if (nVerts >= UINT16_MAX)
return E_INVALIDARG;
break;
case DXGI_FORMAT_R32_UINT:
if (nVerts >= UINT32_MAX)
return E_INVALIDARG;
break;
default:
return E_INVALIDARG;
}
if ((uint64_t(nFaces) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;
LPIMTSIGNALCALLBACK pSignalCallback = nullptr;
if ((options & UVATLAS_IMT_WRAP_UV) == UVATLAS_IMT_WRAP_UV)
{
pSignalCallback = IMTTextureCbWrapUV;
}
else if (options & UVATLAS_IMT_WRAP_U)
{
pSignalCallback = IMTTextureCbWrapU;
}
else if (options & UVATLAS_IMT_WRAP_V)
{
pSignalCallback = IMTTextureCbWrapV;
}
else
{
pSignalCallback = IMTTextureCbWrapNone;
}
auto pdwIndexData = reinterpret_cast<const uint32_t*>(indices);
auto pwIndexData = reinterpret_cast<const uint16_t*>(indices);
IMTTextureDesc TextureDesc;
TextureDesc.pTexture = reinterpret_cast<const XMFLOAT4*>(pTexture);
TextureDesc.uWidth = width;
TextureDesc.uHeight = height;
float* pfIMTData = pIMTArray;
HRESULT hr;
for (size_t i = 0; i < nFaces; i++)
{
if (statusCallBack && ((i % 64) == 0))
{
float fPct = float(i) / float(nFaces);
hr = statusCallBack(fPct);
if (FAILED(hr))
return E_ABORT;
}
XMFLOAT3 pos[3] = {};
XMFLOAT2 uv[3] = {};
for (size_t j = 0; j < 3; j++)
{
uint32_t dwId;
if (indexFormat == DXGI_FORMAT_R16_UINT)
{
dwId = pwIndexData[3 * i + j];
}
else
{
dwId = pdwIndexData[3 * i + j];
}
if (dwId >= nVerts)
{
DPF(0, "UVAtlasComputeIMT: Vertex ID out of range.");
return E_FAIL;
}
pos[j] = positions[dwId];
uv[j] = texcoords[dwId];
}
hr = IMTFromTextureMapEx(pos,
uv,
i,
4, // dimension 4, rgba, can be zeroes if less than 4
pSignalCallback,
&TextureDesc,
reinterpret_cast<FLOAT3*>(pfIMTData + 3 * i));
if (FAILED(hr))
{
DPF(0, "UVAtlasComputeIMT: IMT data calculation failed.");
return hr;
}
}
if (statusCallBack)
{
hr = statusCallBack(1.0f);
if (FAILED(hr))
return E_ABORT;
}
return S_OK;
}