From 92accb352e244282acc572ec5329a46f74c87e0c Mon Sep 17 00:00:00 2001 From: Benau Date: Mon, 23 May 2022 13:46:03 +0800 Subject: [PATCH] Convert spm to GE spm --- src/graphics/sp_mesh_loader.cpp | 170 +++++++++++++++++++++++++++++--- src/graphics/sp_mesh_loader.hpp | 8 +- 2 files changed, 161 insertions(+), 17 deletions(-) diff --git a/src/graphics/sp_mesh_loader.cpp b/src/graphics/sp_mesh_loader.cpp index 084b627a9..3e0f4b9c2 100644 --- a/src/graphics/sp_mesh_loader.cpp +++ b/src/graphics/sp_mesh_loader.cpp @@ -37,6 +37,9 @@ const uint8_t VERSION_NOW = 1; #include #include #ifndef SERVER_ONLY +#include +#include +#include #include #endif @@ -67,7 +70,19 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f) m_joint_count = 0; m_frame_count = 0; m_mesh = NULL; - m_mesh = real_spm ? new SP::SPMesh() : m_scene_manager->createSkinnedMesh(); + bool ge_spm = false; +#ifndef SERVER_ONLY + if (GE::getVKDriver()) + { + ge_spm = true; + m_mesh = new GE::GESPM(); + } +#endif + if (!m_mesh) + { + m_mesh = real_spm ? + new SP::SPMesh() : m_scene_manager->createSkinnedMesh(); + } io::IFileSystem* fs = m_scene_manager->getFileSystem(); std::string base_path = fs->getFileDir(f->getFileName()).c_str(); std::string header; @@ -257,6 +272,14 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f) std::get<2>(sp_mat_map[mat_id]), vt, std::get<0>(sp_mat_map[mat_id])); } + else if (ge_spm) + { + assert(mat_id < mat_map.size()); + decompressGESPM(f, vertices_count, indices_count, read_normal, + read_vcolor, read_tangent, std::get<1>(mat_map[mat_id]), + std::get<2>(mat_map[mat_id]), vt, + std::get<0>(mat_map[mat_id])); + } else { assert(mat_id < mat_map.size()); @@ -313,11 +336,11 @@ scene::IAnimatedMesh* SPMeshLoader::createMesh(io::IReadFile* f) spm->m_all_armatures = std::move(m_all_armatures); } m_mesh->finalize(); - if (!real_spm && has_armature) + scene::CSkinnedMesh* cmesh = dynamic_cast(m_mesh); + if (cmesh && !real_spm && has_armature) { // Because the last frame in spm is usable - static_cast(m_mesh)->AnimationFrames = - (float)m_frame_count + 1.0f; + cmesh->AnimationFrames = (float)m_frame_count + 1.0f; } m_all_armatures.clear(); m_to_bind_pose_matrices.clear(); @@ -431,6 +454,118 @@ void SPMeshLoader::decompressSPM(irr::io::IReadFile* spm, } // decompressSPM +// ---------------------------------------------------------------------------- +void SPMeshLoader::decompressGESPM(irr::io::IReadFile* spm, + unsigned vertices_count, + unsigned indices_count, bool read_normal, + bool read_vcolor, bool read_tangent, + bool uv_one, bool uv_two, SPVertexType vt, + const video::SMaterial& m) +{ +#ifndef SERVER_ONLY + assert(vertices_count != 0); + assert(indices_count != 0); + + GE::GESPMBuffer* mb = new GE::GESPMBuffer(); + static_cast(m_mesh)->m_buffer.push_back(mb); + std::vector vertices; + const unsigned idx_size = vertices_count > 255 ? 2 : 1; + for (unsigned i = 0; i < vertices_count; i++) + { + video::S3DVertexSkinnedMesh vertex = {}; + // 3 * float position + spm->read(&vertex.m_position, 12); + if (read_normal) + { + spm->read(&vertex.m_normal, 4); + } + else + { + // 0, 1, 0 + vertex.m_normal = 0x1FF << 10; + } + if (read_vcolor) + { + // Color identifier + uint8_t ci; + spm->read(&ci, 1); + if (ci == 128) + { + // All white + vertex.m_color = video::SColor(255, 255, 255, 255); + } + else + { + uint8_t r, g, b; + spm->read(&r, 1); + spm->read(&g, 1); + spm->read(&b, 1); + vertex.m_color = video::SColor(255, r, g, b); + } + } + else + { + vertex.m_color = video::SColor(255, 255, 255, 255); + } + if (uv_one) + { + spm->read(&vertex.m_all_uvs[0], 4); + if (uv_two) + { + spm->read(&vertex.m_all_uvs[2], 4); + } + if (read_tangent) + { + spm->read(&vertex.m_tangent, 4); + } + else + { + vertex.m_tangent = MiniGLM::quickTangent(vertex.m_normal); + } + } + if (vt == SPVT_SKINNED) + { + spm->read(&vertex.m_joint_idx[0], 16); + if (vertex.m_joint_idx[0] == -1 || + vertex.m_weight[0] == 0 || + // -0.0 in half float (16bit) + vertex.m_weight[0] == -32768) + { + // For the skinned mesh shader + vertex.m_joint_idx[0] = -32767; + // 1.0 in half float (16bit) + vertex.m_weight[0] = 15360; + } + } + vertices.push_back(vertex); + } + + std::vector indices; + indices.resize(indices_count); + if (idx_size == 2) + { + spm->read(indices.data(), indices_count * 2); + } + else + { + std::vector tmp_idx; + tmp_idx.resize(indices_count); + spm->read(tmp_idx.data(), indices_count); + for (unsigned i = 0; i < indices_count; i++) + { + indices[i] = tmp_idx[i]; + } + } + std::swap(mb->m_vertices, vertices); + std::swap(mb->m_indices, indices); + if (m.TextureLayer[0].Texture != NULL) + { + mb->m_material = m; + } + mb->recalculateBoundingBox(); +#endif +} // decompressGESPM + // ---------------------------------------------------------------------------- void SPMeshLoader::decompress(irr::io::IReadFile* spm, unsigned vertices_count, unsigned indices_count, bool read_normal, @@ -440,7 +575,8 @@ void SPMeshLoader::decompress(irr::io::IReadFile* spm, unsigned vertices_count, { assert(vertices_count != 0); assert(indices_count != 0); - scene::SSkinMeshBuffer* mb = m_mesh->addMeshBuffer(); + scene::SSkinMeshBuffer* mb = + static_cast(m_mesh)->addMeshBuffer(); if (uv_two) { mb->convertTo2TCoords(); @@ -603,17 +739,18 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm) accumulated_joints += m_all_armatures[i].m_joint_used; } + scene::ISkinnedMesh* smesh = dynamic_cast(m_mesh); // Only for legacy device - if (m_joints.empty()) + if (!smesh || m_joints.empty()) { return; } - assert(m_joints.size() == m_mesh->getMeshBufferCount()); + assert(m_joints.size() == smesh->getMeshBufferCount()); for (unsigned i = 0; i < m_to_bind_pose_matrices.size(); i++) { m_to_bind_pose_matrices[i].makeInverse(); } - for (unsigned i = 0; i < m_mesh->getMeshBufferCount(); i++) + for (unsigned i = 0; i < smesh->getMeshBufferCount(); i++) { for (unsigned j = 0; j < m_joints[i].size(); j++) { @@ -630,15 +767,15 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm) core::vector3df cur_pos, cur_nor; m_to_bind_pose_matrices[m_joints[i][j].first[k]] .transformVect(cur_pos, - m_mesh->getMeshBuffers()[i]->getVertex(j)->Pos); + smesh->getMeshBuffers()[i]->getVertex(j)->Pos); bind_pos += cur_pos * m_joints[i][j].second[k]; m_to_bind_pose_matrices[m_joints[i][j].first[k]] .rotateVect(cur_nor, - m_mesh->getMeshBuffers()[i]->getVertex(j)->Normal); + smesh->getMeshBuffers()[i]->getVertex(j)->Normal); bind_nor += cur_nor * m_joints[i][j].second[k]; } - m_mesh->getMeshBuffers()[i]->getVertex(j)->Pos = bind_pos; - m_mesh->getMeshBuffers()[i]->getVertex(j)->Normal = bind_nor; + smesh->getMeshBuffers()[i]->getVertex(j)->Pos = bind_pos; + smesh->getMeshBuffers()[i]->getVertex(j)->Normal = bind_nor; } } } @@ -647,8 +784,9 @@ void SPMeshLoader::createAnimationData(irr::io::IReadFile* spm) // ---------------------------------------------------------------------------- void SPMeshLoader::convertIrrlicht() { + scene::ISkinnedMesh* smesh = dynamic_cast(m_mesh); // Only for legacy device - if (m_joints.empty()) + if (!smesh || m_joints.empty()) { return; } @@ -659,9 +797,9 @@ void SPMeshLoader::convertIrrlicht() } for (unsigned i = 0; i < total_joints; i++) { - m_mesh->addJoint(NULL); + smesh->addJoint(NULL); } - core::array& joints = m_mesh->getAllJoints(); + core::array& joints = smesh->getAllJoints(); std::vector used_joints_map; used_joints_map.resize(m_joint_count); total_joints = 0; @@ -723,7 +861,7 @@ void SPMeshLoader::convertIrrlicht() { break; } - scene::ISkinnedMesh::SWeight* w = m_mesh->addWeight + scene::ISkinnedMesh::SWeight* w = smesh->addWeight (joints[used_joints_map[m_joints[i][j].first[k]]]); w->buffer_id = (uint16_t)i; w->vertex_id = j; diff --git a/src/graphics/sp_mesh_loader.hpp b/src/graphics/sp_mesh_loader.hpp index 5d59b3048..7b681ce43 100644 --- a/src/graphics/sp_mesh_loader.hpp +++ b/src/graphics/sp_mesh_loader.hpp @@ -53,6 +53,12 @@ private: bool read_tangent, bool uv_one, bool uv_two, SPVertexType vt, const video::SMaterial& m); // ------------------------------------------------------------------------ + void decompressGESPM(irr::io::IReadFile* spm, unsigned vertices_count, + unsigned indices_count, bool read_normal, + bool read_vcolor, bool read_tangent, bool uv_one, + bool uv_two, SPVertexType vt, + const video::SMaterial& m); + // ------------------------------------------------------------------------ void decompressSPM(irr::io::IReadFile* spm, unsigned vertices_count, unsigned indices_count, bool read_normal, bool read_vcolor, bool read_tangent, bool uv_one, @@ -63,7 +69,7 @@ private: // ------------------------------------------------------------------------ void convertIrrlicht(); - scene::ISkinnedMesh* m_mesh; + scene::IAnimatedMesh* m_mesh; scene::ISceneManager* m_scene_manager;