~redstrate/libxiv

071aed659612cc36d4657cd15761cb0894dbf094 — Joshua Goins 2 years ago 89ea054
Export bone weights & bone ids for vertices

This currently pulls in glm as a dependency, will be added to the build
system soon.
4 files changed, 47 insertions(+), 7 deletions(-)

M include/havokxmlparser.h
M include/mdlparser.h
M include/memorybuffer.h
M src/mdlparser.cpp
M include/havokxmlparser.h => include/havokxmlparser.h +2 -1
@@ 3,13 3,14 @@
#include <string>
#include <vector>
#include <array>
#include <glm/glm.hpp>

struct Bone {
    std::string name;

    Bone* parent = nullptr;

    std::array<float, 16> localTransform, finalTransform;
    glm::mat4 localTransform, finalTransform, inversePose;

    std::array<float, 3> position;
    std::array<float, 4> rotation;

M include/mdlparser.h => include/mdlparser.h +13 -0
@@ 8,12 8,23 @@

struct Vertex {
    std::array<float, 3> position;
    std::array<float, 2> uv;
    std::array<float, 3> normal;

    std::array<float, 4> boneWeights;
    std::array<uint8_t, 4> boneIds;
};

struct PartSubmesh {
    uint32_t indexOffset, indexCount;
    uint32_t boneStartIndex, boneCount;
};

struct Part {
    std::vector<Vertex> vertices;
    std::vector<uint16_t> indices;

    std::vector<PartSubmesh> submeshes;
};

struct Lod {


@@ 22,6 33,8 @@ struct Lod {

struct Model {
    std::vector<Lod> lods;

    std::vector<std::string> affectedBoneNames;
};

Model parseMDL(MemorySpan data);
\ No newline at end of file

M include/memorybuffer.h => include/memorybuffer.h +1 -1
@@ 58,7 58,7 @@ private:
};

template<>
void MemoryBuffer::write<std::vector<uint8_t>>(const std::vector<uint8_t>& t) {
inline void MemoryBuffer::write<std::vector<uint8_t>>(const std::vector<uint8_t>& t) {
    size_t end = position + (sizeof(uint8_t) * t.size());
    if(end > data.size())
        data.resize(end);

M src/mdlparser.cpp => src/mdlparser.cpp +31 -5
@@ 159,8 159,8 @@ struct Mesh {
};

struct Submesh {
    unsigned int indexOffset;
    unsigned int indexCount;
    int32_t indexOffset;
    int32_t indexCount;
    unsigned int attributeIndexMask;
    unsigned short boneStartIndex;
    unsigned short boneCount;


@@ 292,6 292,18 @@ Model parseMDL(MemorySpan data) {

    Model model;

    for(auto offset : boneNameOffsets) {
        std::string name;
        char nextChar = strings[offset];
        while(nextChar != '\0') {
            name += nextChar;
            offset++;
            nextChar = strings[offset];
        }

        model.affectedBoneNames.push_back(name);
    }

    for(int i = 0; i < modelHeader.lodCount; i++) {
        Lod lod;



@@ 303,11 315,22 @@ Model parseMDL(MemorySpan data) {
            int vertexCount = meshes[j].vertexCount;
            std::vector<Vertex> vertices(vertexCount);

            for(int k = meshes[j].subMeshIndex; k < (meshes[j].subMeshIndex + meshes[j].subMeshCount); k++) {
                PartSubmesh submesh;
                submesh.indexCount = submeshes[k].indexCount;
                submesh.indexOffset = submeshes[k].indexOffset;
                submesh.boneCount = submeshes[k].boneCount;
                submesh.boneStartIndex = submeshes[k].boneStartIndex;

                part.submeshes.push_back(submesh);
            }

            for(int k = 0; k < vertexCount; k++) {
                for(auto& element : decl.elements) {
                    data.seek(lods[i].vertexDataOffset + meshes[j].vertexBufferOffset[element.stream] + element.offset + meshes[i].vertexBufferStride[element.stream] * k, Seek::Set);

                    std::array<float, 4> floatData = {};
                    std::array<uint8_t, 4> intData = {};
                    switch(element.type) {
                        case VertexType::Single3:
                            data.read_array(floatData.data(), 3);


@@ 316,7 339,7 @@ Model parseMDL(MemorySpan data) {
                            data.read_array(floatData.data(), 4);
                            break;
                        case VertexType::UInt:
                            data.seek(sizeof(uint8_t) * 4, Seek::Current);
                            data.read_array(intData.data(), 4);
                            break;
                        case VertexType::ByteFloat4: {
                            uint8_t values[4];


@@ 329,7 352,7 @@ Model parseMDL(MemorySpan data) {
                        }
                            break;
                        case VertexType::Half2: {
                            uint16_t values[2];
                            uint16_t values[2] = {};
                            data.read_array(values, 2);

                            floatData[0] = half_to_float(values[0]);


@@ 337,7 360,7 @@ Model parseMDL(MemorySpan data) {
                        }
                            break;
                        case VertexType::Half4: {
                            uint16_t values[4];
                            uint16_t values[4] = {};
                            data.read_array(values, 4);

                            floatData[0] = half_to_float(values[0]);


@@ 356,10 379,13 @@ Model parseMDL(MemorySpan data) {
                            memcpy(vertices[k].normal.data(), floatData.data(), sizeof(float) * 3);
                            break;
                        case BlendWeights:
                            memcpy(vertices[k].boneWeights.data(), floatData.data(), sizeof(float) * 4);
                            break;
                        case BlendIndices:
                            memcpy(vertices[k].boneIds.data(), intData.data(), sizeof(uint8_t) * 4);
                            break;
                        case UV:
                            memcpy(vertices[k].uv.data(), floatData.data(), sizeof(float) * 2);
                            break;
                        case Tangent2:
                            break;