in UVAtlas/isochart/UVAtlas.cpp [728:843]
HRESULT __cdecl DirectX::UVAtlasComputeIMTFromPerVertexSignal(
const XMFLOAT3* positions,
size_t nVerts,
const void* indices,
DXGI_FORMAT indexFormat,
size_t nFaces,
const float* pVertexSignal,
size_t signalDimension,
size_t signalStride,
std::function<HRESULT __cdecl(float percentComplete)> statusCallBack,
float* pIMTArray)
{
if (!positions || !nVerts || !indices || !nFaces || !pVertexSignal || !pIMTArray)
return E_INVALIDARG;
if (!signalStride || (signalStride % sizeof(float)))
{
DPF(0, "UVAtlasComputeIMT: signalStride (%zu) must be a multiple of %zu.", signalStride, sizeof(float));
return E_INVALIDARG;
}
if ((signalStride / sizeof(float)) < signalDimension)
{
DPF(0, "UVAtlasComputeIMT: signalStride (%zu) must accommodate signal dimension float values (%zu)\n", signalStride, signalDimension);
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(signalDimension) * 3) >= UINT32_MAX)
return HRESULT_E_ARITHMETIC_OVERFLOW;
std::unique_ptr<float[]> signalData(new (std::nothrow) float[3 * signalDimension]);
if (!signalData)
return E_OUTOFMEMORY;
float* pfSignalData = signalData.get();
auto pdwIndexData = reinterpret_cast<const uint32_t*>(indices);
auto pwIndexData = reinterpret_cast<const uint16_t*>(indices);
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] = {};
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];
for (size_t k = 0; k < signalDimension; k++)
{
pfSignalData[j * signalDimension + k] = pVertexSignal[dwId * (signalStride / sizeof(float)) + k];
}
}
hr = IMTFromPerVertexSignal(pos,
pfSignalData,
signalDimension,
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;
}