Идея состоит в том, чтобы представить нарисованный трехмерный объект "по центру" на экране. После загрузки объекта с помощью WaveFrontReader я получил массив вершин:
float bmin[3], bmax[3];
bmin[0] = bmin[1] = bmin[2] = std::numeric_limits<float>::max();
bmax[0] = bmax[1] = bmax[2] = -std::numeric_limits<float>::max();
for (int k = 0; k < 3; k++)
{
for (auto& v : objx->wfr.vertices)
{
if (k == 0)
{
bmin[k] = std::min(v.position.x, bmin[k]);
bmax[k] = std::max(v.position.x, bmax[k]);
}
if (k == 1)
{
bmin[k] = std::min(v.position.y, bmin[k]);
bmax[k] = std::max(v.position.y, bmax[k]);
}
if (k == 2)
{
bmin[k] = std::min(v.position.z, bmin[k]);
bmax[k] = std::max(v.position.z, bmax[k]);
}
}
}
Я получил представление от средства просмотра в TinyObjLoader (хотя использует OpenGL), и затем:
float maxExtent = 0.5f * (bmax[0] - bmin[0]);
if (maxExtent < 0.5f * (bmax[1] - bmin[1])) {
maxExtent = 0.5f * (bmax[1] - bmin[1]);
}
if (maxExtent < 0.5f * (bmax[2] - bmin[2])) {
maxExtent = 0.5f * (bmax[2] - bmin[2]);
}
_3dp.scale[0] = maxExtent;
_3dp.scale[1] = maxExtent;
_3dp.scale[2] = maxExtent;
_3dp.translation[0] = -0.5 * (bmax[0] + bmin[0]);
_3dp.translation[1] = -0.5 * (bmax[1] + bmin[1]);
_3dp.translation[2] = -0.5 * (bmax[2] + bmin[2]);
Однако это не работает. С таким объектом, как этот паук , который имеет вершины, координаты которых не расширяются +/- 100, масштаб достигает примерно 100x по приведенной выше формуле и, тем не менее, с текущим видом, установленным на 0,0,0 объект находится слишком близко, и мне нужно вручную поместить перевод Z в что-то вроде 50000, чтобы просмотреть его в полный прямоугольник с D3D11_VIEWPORT viewport = { 0.0f, 0.0f, w, h, 0.0f, 1.0f };
, не говоря уже о том, что Y также не центрирован.
Is есть правильный алгоритм для центрирования объекта в поле зрения?
Большое спасибо