mirror of
https://github.com/dolphin-emu/dolphin.git
synced 2025-09-05 00:56:13 +00:00
mesh asset
This commit is contained in:
parent
e362140773
commit
ec5f7bbe93
2 changed files with 134 additions and 70 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue