mesh asset

This commit is contained in:
iwubcode 2025-06-04 22:29:32 -05:00
commit ec5f7bbe93
2 changed files with 134 additions and 70 deletions

View file

@ -33,12 +33,11 @@ Common::Matrix44 BuildMatrixFromNode(const tinygltf::Node& node)
Common::Matrix44 matrix = Common::Matrix44::Identity();
// Check individual components
if (!node.scale.empty())
if (!node.translation.empty())
{
matrix *= Common::Matrix44::FromMatrix33(Common::Matrix33::Scale(
Common::Vec3{static_cast<float>(node.scale[0]), static_cast<float>(node.scale[1]),
static_cast<float>(node.scale[2])}));
matrix *= Common::Matrix44::Translate(Common::Vec3{static_cast<float>(node.translation[0]),
static_cast<float>(node.translation[1]),
static_cast<float>(node.translation[2])});
}
if (!node.rotation.empty())
@ -48,11 +47,11 @@ Common::Matrix44 BuildMatrixFromNode(const tinygltf::Node& node)
static_cast<float>(node.rotation[1]), static_cast<float>(node.rotation[2])));
}
if (!node.translation.empty())
if (!node.scale.empty())
{
matrix *= Common::Matrix44::Translate(Common::Vec3{static_cast<float>(node.translation[0]),
static_cast<float>(node.translation[1]),
static_cast<float>(node.translation[2])});
matrix *= Common::Matrix44::FromMatrix33(Common::Matrix33::Scale(
Common::Vec3{static_cast<float>(node.scale[0]), static_cast<float>(node.scale[1]),
static_cast<float>(node.scale[2])}));
}
return matrix;
@ -291,12 +290,12 @@ bool ReadGLTFMesh(std::string_view mesh_file, const tinygltf::Model& model,
chunk.num_vertices = static_cast<u32>(pos_accessor.count);
// TODO C++23: use make_unique_overwrite
chunk.vertex_data = std::unique_ptr<u8[]>(new u8[chunk.num_vertices * chunk.vertex_stride]);
chunk.vertex_declaration.position.offset = static_cast<int>(outbound_offset);
if (!CopyBufferDataFromPrimitive(model, position_it->second, &outbound_offset, &chunk))
return false;
chunk.components_available = 0;
chunk.vertex_declaration.position.enable = true;
chunk.vertex_declaration.position.components = 3;
chunk.vertex_declaration.position.offset = 0;
if (!GLTFComponentTypeToAttributeFormat(pos_accessor.componentType,
&chunk.vertex_declaration.position))
{
@ -454,18 +453,27 @@ bool ReadGLTFMaterials(std::string_view mesh_file, const tinygltf::Model& model,
bool ReadGLTF(std::string_view mesh_file, const tinygltf::Model& model, MeshData* data)
{
int scene_index = model.defaultScene;
if (scene_index == -1)
scene_index = 0;
const auto& scene = model.scenes[scene_index];
const auto scene_node_indices = scene.nodes;
for (std::size_t i = 0; i < scene_node_indices.size(); i++)
const int scene_index = model.defaultScene;
if (scene_index != -1)
{
const tinygltf::Node& node = model.nodes[scene_node_indices[i]];
const auto mat = BuildMatrixFromNode(node);
if (!ReadGLTFNodes(mesh_file, model, node, mat, data))
return false;
const auto& scene = model.scenes[scene_index];
const auto scene_node_indices = scene.nodes;
for (std::size_t i = 0; i < scene_node_indices.size(); i++)
{
const tinygltf::Node& node = model.nodes[scene_node_indices[i]];
const auto mat = BuildMatrixFromNode(node);
if (!ReadGLTFNodes(mesh_file, model, node, mat, data))
return false;
}
}
else
{
for (const auto& node : model.nodes)
{
const auto mat = BuildMatrixFromNode(node);
if (!ReadGLTFNodes(mesh_file, model, node, mat, data))
return false;
}
}
return ReadGLTFMaterials(mesh_file, model, data);
@ -514,6 +522,57 @@ void MeshData::ToJson(picojson::object& obj, const MeshData& data)
bool MeshData::FromDolphinMesh(std::span<const u8> raw_data, MeshData* data)
{
const auto read_chunk = [](std::span<const u8> raw_data, MeshDataChunk* mesh_data_chunk,
std::size_t* offset) {
auto& chunk = *mesh_data_chunk;
std::memcpy(&chunk.num_vertices, raw_data.data() + *offset, sizeof(u32));
*offset += sizeof(u32);
std::memcpy(&chunk.vertex_stride, raw_data.data() + *offset, sizeof(u32));
*offset += sizeof(u32);
// TODO C++23: use make_unique_overwrite
chunk.vertex_data = std::unique_ptr<u8[]>(new u8[chunk.num_vertices * chunk.vertex_stride]);
std::memcpy(chunk.vertex_data.get(), raw_data.data() + *offset,
chunk.num_vertices * chunk.vertex_stride);
*offset += chunk.num_vertices * chunk.vertex_stride;
std::memcpy(&chunk.num_indices, raw_data.data() + *offset, sizeof(u32));
*offset += sizeof(u32);
// TODO C++23: use make_unique_overwrite
chunk.indices = std::unique_ptr<u16[]>(new u16[chunk.num_indices]);
std::memcpy(chunk.indices.get(), raw_data.data() + *offset, chunk.num_indices * sizeof(u16));
*offset += chunk.num_indices * sizeof(u16);
std::memcpy(&chunk.vertex_declaration, raw_data.data() + *offset,
sizeof(PortableVertexDeclaration));
*offset += sizeof(PortableVertexDeclaration);
std::memcpy(&chunk.primitive_type, raw_data.data() + *offset, sizeof(PrimitiveType));
*offset += sizeof(PrimitiveType);
std::memcpy(&chunk.components_available, raw_data.data() + *offset, sizeof(u32));
*offset += sizeof(u32);
std::memcpy(&chunk.minimum_position, raw_data.data() + *offset, sizeof(Common::Vec3));
*offset += sizeof(Common::Vec3);
std::memcpy(&chunk.maximum_position, raw_data.data() + *offset, sizeof(Common::Vec3));
*offset += sizeof(Common::Vec3);
std::memcpy(&chunk.transform.data[0], raw_data.data() + *offset,
chunk.transform.data.size() * sizeof(float));
*offset += chunk.transform.data.size() * sizeof(float);
std::size_t material_name_size = 0;
std::memcpy(&material_name_size, raw_data.data() + *offset, sizeof(std::size_t));
*offset += sizeof(std::size_t);
chunk.material_name.assign(raw_data.data() + *offset,
raw_data.data() + *offset + material_name_size);
*offset += material_name_size * sizeof(char);
};
std::size_t offset = 0;
std::size_t chunk_size = 0;
@ -524,56 +583,32 @@ bool MeshData::FromDolphinMesh(std::span<const u8> raw_data, MeshData* data)
for (std::size_t i = 0; i < chunk_size; i++)
{
MeshDataChunk chunk;
read_chunk(raw_data, &chunk, &offset);
data->m_mesh_chunks.push_back(std::move(chunk));
}
std::memcpy(&chunk.num_vertices, raw_data.data() + offset, sizeof(u32));
offset += sizeof(u32);
std::size_t gpu_skinning_size = 0;
std::memcpy(&gpu_skinning_size, raw_data.data() + offset, sizeof(std::size_t));
offset += sizeof(std::size_t);
for (std::size_t i = 0; i < gpu_skinning_size; i++)
{
GraphicsModSystem::DrawCallID draw_call_id;
std::memcpy(&draw_call_id, raw_data.data() + offset, sizeof(GraphicsModSystem::DrawCallID));
offset += sizeof(GraphicsModSystem::DrawCallID);
std::memcpy(&chunk.vertex_stride, raw_data.data() + offset, sizeof(u32));
offset += sizeof(u32);
// TODO C++23: use make_unique_overwrite
chunk.vertex_data = std::unique_ptr<u8[]>(new u8[chunk.num_vertices * chunk.vertex_stride]);
std::memcpy(chunk.vertex_data.get(), raw_data.data() + offset,
chunk.num_vertices * chunk.vertex_stride);
offset += chunk.num_vertices * chunk.vertex_stride;
std::memcpy(&chunk.num_indices, raw_data.data() + offset, sizeof(u32));
offset += sizeof(u32);
// TODO C++23: use make_unique_overwrite
chunk.indices = std::unique_ptr<u16[]>(new u16[chunk.num_indices]);
std::memcpy(chunk.indices.get(), raw_data.data() + offset, chunk.num_indices * sizeof(u16));
offset += chunk.num_indices * sizeof(u16);
std::memcpy(&chunk.vertex_declaration, raw_data.data() + offset,
sizeof(PortableVertexDeclaration));
offset += sizeof(PortableVertexDeclaration);
std::memcpy(&chunk.primitive_type, raw_data.data() + offset, sizeof(PrimitiveType));
offset += sizeof(PrimitiveType);
std::memcpy(&chunk.components_available, raw_data.data() + offset, sizeof(u32));
offset += sizeof(u32);
std::memcpy(&chunk.minimum_position, raw_data.data() + offset, sizeof(Common::Vec3));
offset += sizeof(Common::Vec3);
std::memcpy(&chunk.maximum_position, raw_data.data() + offset, sizeof(Common::Vec3));
offset += sizeof(Common::Vec3);
std::memcpy(&chunk.transform.data[0], raw_data.data() + offset,
chunk.transform.data.size() * sizeof(float));
offset += chunk.transform.data.size() * sizeof(float);
std::size_t material_name_size = 0;
std::memcpy(&material_name_size, raw_data.data() + offset, sizeof(std::size_t));
std::size_t gpu_skinning_chunk_size = 0;
std::memcpy(&gpu_skinning_chunk_size, raw_data.data() + offset, sizeof(std::size_t));
offset += sizeof(std::size_t);
chunk.material_name.assign(raw_data.data() + offset,
raw_data.data() + offset + material_name_size);
offset += material_name_size * sizeof(char);
std::vector<MeshDataChunk> gpu_skinning_chunks;
for (std::size_t chunk_index = 0; chunk_index < gpu_skinning_chunk_size; chunk_index++)
{
MeshDataChunk chunk;
read_chunk(raw_data, &chunk, &offset);
gpu_skinning_chunks.push_back(std::move(chunk));
}
data->m_mesh_chunks.push_back(std::move(chunk));
data->m_gpu_skinning_chunks.try_emplace(draw_call_id, std::move(gpu_skinning_chunks));
}
return true;
@ -581,10 +616,7 @@ bool MeshData::FromDolphinMesh(std::span<const u8> raw_data, MeshData* data)
bool MeshData::ToDolphinMesh(File::IOFile* file_data, const MeshData& data)
{
const std::size_t chunk_size = data.m_mesh_chunks.size();
file_data->WriteBytes(&chunk_size, sizeof(std::size_t));
for (const auto& chunk : data.m_mesh_chunks)
{
const auto write_chunk = [](File::IOFile* file_data, const VideoCommon::MeshDataChunk& chunk) {
if (!file_data->WriteBytes(&chunk.num_vertices, sizeof(u32)))
return false;
if (!file_data->WriteBytes(&chunk.vertex_stride, sizeof(u32)))
@ -616,7 +648,37 @@ bool MeshData::ToDolphinMesh(File::IOFile* file_data, const MeshData& data)
return false;
if (!file_data->WriteBytes(&chunk.material_name[0], chunk.material_name.size() * sizeof(char)))
return false;
return true;
};
const std::size_t chunk_size = data.m_mesh_chunks.size();
file_data->WriteBytes(&chunk_size, sizeof(std::size_t));
for (const auto& chunk : data.m_mesh_chunks)
{
if (!write_chunk(file_data, chunk))
return false;
}
const std::size_t gpu_skinning_map_size = data.m_gpu_skinning_chunks.size();
if (!file_data->WriteBytes(&gpu_skinning_map_size, sizeof(std::size_t)))
return false;
for (const auto& [draw_call, gpu_skinning_chunks] : data.m_gpu_skinning_chunks)
{
if (!file_data->WriteBytes(&draw_call, sizeof(GraphicsModSystem::DrawCallID)))
return false;
const std::size_t gpu_skinning_chunk_size = gpu_skinning_chunks.size();
if (!file_data->WriteBytes(&gpu_skinning_chunk_size, sizeof(std::size_t)))
return false;
for (const auto& gpu_skinning_chunk : gpu_skinning_chunks)
{
if (!write_chunk(file_data, gpu_skinning_chunk))
return false;
}
}
return true;
}

View file

@ -15,6 +15,7 @@
#include "Common/Matrix.h"
#include "VideoCommon/Assets/CustomAsset.h"
#include "VideoCommon/GraphicsModSystem/Types.h"
#include "VideoCommon/NativeVertexFormat.h"
#include "VideoCommon/RenderState.h"
@ -54,6 +55,7 @@ struct MeshData
static bool FromGLTF(std::string_view gltf_file, MeshData* data);
std::vector<MeshDataChunk> m_mesh_chunks;
std::map<GraphicsModSystem::DrawCallID, std::vector<MeshDataChunk>> m_gpu_skinning_chunks;
std::map<std::string, CustomAssetLibrary::AssetID, std::less<>>
m_mesh_material_to_material_asset_id;
};