Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Баг конвертации билдовских ogf в object #1

Open
PavelBlend opened this issue Feb 4, 2018 · 3 comments
Open

Comments

@PavelBlend
Copy link
Contributor

Данный конвертер не правильно конвертирует ogf модели из некоторых билдов. Я прикрепил пример ogf модели, которая конвертируется с багами (худ модель ак74 из билда 1472). В некоторых местах меш покорёжен (видно при проигрывании анимаций, что пальцы не такие, как в самом билде).
ak74_build_1472.zip

@abramcumner
Copy link
Owner

А можешь дать ссылку на 1472?

@PavelBlend
Copy link
Contributor Author

Я давно качал с рутрекера. Сейчас он не доступен. Но скорее всего билд ещё здесь скачать можно:
https://stalker-ru.gamepedia.com/Build_1472
Или здесь:
https://www.gameru.net/forum/index.php?showtopic=18951

@PavelBlend
Copy link
Contributor Author

Кое-что удалось выяснить. Конвертер не правильно обрабатывает вершины с мягкой привязкой (когда две кости влияют на вершину). В 1472 билде формат вершин другой. В конвертере формат описывается так:

кость 1
кость 2
позиция
нормаль
тангенс
бинормаль
вес
юви

На самом деле вместо тангенса и бинормали идут позиция2 и нормаль2. В итоге вершина имеет две позиции и две нормали. Я смотрел код за 2003 год:
https://github.com/SkyLoaderr/xray-engine-repo/blob/554467cd181b73b80b5f5c7f0de2014264cf3342/xr_3da/xrCPU_Pipe/xrSkin2W.cpp#L40

Итоговая позиция вершины интерполируется от двух позиций.

Я пробовал внести правки в код конвертера, результат стал лучше, но не идеален.
02

Вот как было до моих правок:
01

Вот мой правленый код из файла xr_geom_buf.cxx

void xr_vbuf::load_ogf3(xr_reader& r, size_t n, ogf_vertex_format vf)
{
    if (vf == OGF3_VERTEXFORMAT_FVF_1L) {
        clear();
        m_influences = new finfluence[n];
        m_points = new fvector3[n];
        m_normals = new fvector3[n];
        m_texcoords = new fvector2[n];
        set_size(n);
        for (size_t i = 0; i != n; ++i) {
            r.r_fvector3(m_points[i]);
            r.r_fvector3(m_normals[i]);
            r.r_fvector2(m_texcoords[i]);
            m_influences[i].set(r.r_u32());
        }
        make_signature();
    } else if (vf == OGF3_VERTEXFORMAT_FVF_2L) {
        clear();
        m_influences = new finfluence[n];
        m_points = new fvector3[n];
        m_normals = new fvector3[n];
        m_points1 = new fvector3[n];
        m_normals1 = new fvector3[n];
        m_points2 = new fvector3[n];
        m_normals2 = new fvector3[n];
        m_texcoords = new fvector2[n];
        set_size(n);
        for (size_t i = 0; i != n; ++i) {
            uint16_t bone0 = r.r_u16();
            uint16_t bone1 = r.r_u16();
            r.r_fvector3(m_points1[i]);
            r.r_fvector3(m_normals1[i]);
            r.r_fvector3(m_points2[i]);
            r.r_fvector3(m_normals2[i]);
            float weight = r.r_float();
            float weight_inv = 1.0f - weight;

            // здесь я изменил
            m_points[i].x = (1.0f - weight) * m_points1[i].x + weight * m_points2[i].x;
            m_points[i].y = (1.0f - weight) * m_points1[i].y + weight * m_points2[i].y;
            m_points[i].z = (1.0f - weight) * m_points1[i].z + weight * m_points2[i].z;
            m_normals[i].x = (1.0f - weight) * m_normals1[i].x + weight * m_normals2[i].x;
            m_normals[i].y = (1.0f - weight) * m_normals1[i].y + weight * m_normals2[i].y;
            m_normals[i].z = (1.0f - weight) * m_normals1[i].z + weight * m_normals2[i].z;
            float length = std::sqrt(
                m_normals[i].x * m_normals[i].x +
                m_normals[i].y * m_normals[i].y +
                m_normals[i].z * m_normals[i].z
            );
            if (length > 0.0f) {
                m_normals[i].x /= length;
                m_normals[i].y /= length;
                m_normals[i].z /= length;
            }
            // конец изменений

            m_influences[i].set_wo_reorder(bone0, bone1, weight);//set_wo_reorder нужно для восстановления модели
            r.r_fvector2(m_texcoords[i]);
        }
        make_signature();
    } else {
        load_d3d7(r, n, vf);
    }
}

Может я что-то не правильно сделал. Почему вершины не много смещены?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants