1
Fork 0
mirror of https://github.com/redstrate/Novus.git synced 2025-04-23 12:37:45 +00:00

Import more vertex data, correct bone ids

This commit is contained in:
Joshua Goins 2023-12-10 12:38:28 -05:00
parent 9b135d9597
commit ae96efcc5e

View file

@ -47,16 +47,26 @@ void importModel(physis_MDL &existingModel, const QString &filename)
auto &mesh = model.meshes[node.mesh]; auto &mesh = model.meshes[node.mesh];
auto &primitive = mesh.primitives[0]; auto &primitive = mesh.primitives[0];
const auto getAccessor = [&model, &primitive](const std::string &name, const int index) -> unsigned char const * {
const auto &positionAccessor = model.accessors[primitive.attributes[name]];
const auto &positionView = model.bufferViews[positionAccessor.bufferView];
const auto &positionBuffer = model.buffers[positionView.buffer];
int elementCount = tinygltf::GetNumComponentsInType(positionAccessor.type);
int elementSize = tinygltf::GetComponentSizeInBytes(positionAccessor.componentType);
return (positionBuffer.data.data() + (std::max(positionView.byteStride, (size_t)elementCount * elementSize) * index) + positionView.byteOffset
+ positionAccessor.byteOffset);
};
// All of the accessors are mapped to the same buffer vertex view // All of the accessors are mapped to the same buffer vertex view
const auto &vertexAccessor = model.accessors[primitive.attributes["POSITION"]]; const auto &positionAccessor = model.accessors[primitive.attributes["POSITION"]];
const auto &vertexView = model.bufferViews[vertexAccessor.bufferView];
const auto &vertexBuffer = model.buffers[vertexView.buffer];
const auto &indexAccessor = model.accessors[primitive.indices]; const auto &indexAccessor = model.accessors[primitive.indices];
const auto &indexView = model.bufferViews[indexAccessor.bufferView]; const auto &indexView = model.bufferViews[indexAccessor.bufferView];
const auto &indexBuffer = model.buffers[indexView.buffer]; const auto &indexBuffer = model.buffers[indexView.buffer];
const int newVertexCount = vertexAccessor.count; const int newVertexCount = positionAccessor.count;
const int oldVertexCount = existingModel.lods[lodNumber].parts[partNumber].num_vertices; const int oldVertexCount = existingModel.lods[lodNumber].parts[partNumber].num_vertices;
if (newVertexCount != oldVertexCount) { if (newVertexCount != oldVertexCount) {
@ -70,12 +80,16 @@ void importModel(physis_MDL &existingModel, const QString &filename)
qInfo() << "- Difference in index count!" << newIndexCount << "old:" << oldIndexCount; qInfo() << "- Difference in index count!" << newIndexCount << "old:" << oldIndexCount;
} }
qInfo() << "- Importing mesh of" << vertexAccessor.count << "vertices and" << indexAccessor.count << "indices."; qInfo() << "- Importing mesh of" << positionAccessor.count << "vertices and" << indexAccessor.count << "indices.";
std::vector<Vertex> newVertices; std::vector<Vertex> newVertices;
for (uint32_t i = 0; i < vertexAccessor.count; i++) { for (uint32_t i = 0; i < positionAccessor.count; i++) {
auto vertexData = (glm::vec3 *)(vertexBuffer.data.data() + (std::max(vertexView.byteStride, sizeof(float) * 3) * i) + vertexView.byteOffset glm::vec3 const *positionData = reinterpret_cast<glm::vec3 const *>(getAccessor("POSITION", i));
+ vertexAccessor.byteOffset); glm::vec3 const *normalData = reinterpret_cast<glm::vec3 const *>(getAccessor("NORMAL", i));
glm::vec2 const *uv0Data = reinterpret_cast<glm::vec2 const *>(getAccessor("TEXCOORD_0", i));
glm::vec2 const *uv1Data = reinterpret_cast<glm::vec2 const *>(getAccessor("TEXCOORD_1", i));
glm::vec4 const *weightsData = reinterpret_cast<glm::vec4 const *>(getAccessor("WEIGHTS_0", i));
uint8_t const *jointsData = reinterpret_cast<uint8_t const *>(getAccessor("JOINTS_0", i));
// Replace position data // Replace position data
Vertex vertex{}; Vertex vertex{};
@ -83,9 +97,42 @@ void importModel(physis_MDL &existingModel, const QString &filename)
vertex = existingModel.lods[lodNumber].parts[partNumber].vertices[i]; vertex = existingModel.lods[lodNumber].parts[partNumber].vertices[i];
} }
vertex.position[0] = vertexData->x; vertex.position[0] = positionData->x;
vertex.position[1] = vertexData->y; vertex.position[1] = positionData->y;
vertex.position[2] = vertexData->z; vertex.position[2] = positionData->z;
vertex.normal[0] = normalData->x;
vertex.normal[1] = normalData->y;
vertex.normal[2] = normalData->z;
vertex.uv0[0] = uv0Data->x;
vertex.uv0[1] = uv0Data->y;
vertex.uv1[0] = uv1Data->x;
vertex.uv1[1] = uv1Data->y;
vertex.bone_weight[0] = weightsData->x;
vertex.bone_weight[1] = weightsData->y;
vertex.bone_weight[2] = weightsData->z;
vertex.bone_weight[3] = weightsData->w;
// We need to ensure the bones are mapped correctly
// When exporting from modeling software, it's possible it sorted the nodes (Blender does this)
for (int i = 0; i < 4; i++) {
int originalBoneId = *(jointsData + i);
auto joints = model.skins[0].joints;
int realBoneId = 0;
for (int j = 0; j < existingModel.num_affected_bones; j++) {
if (strcmp(existingModel.affected_bone_names[j], model.nodes[joints[originalBoneId]].name.c_str()) == 0) {
realBoneId = j;
break;
}
}
vertex.bone_id[i] = realBoneId;
}
newVertices.push_back(vertex); newVertices.push_back(vertex);
} }