diff --git a/Editor/ModelImporter_GLTF.cpp b/Editor/ModelImporter_GLTF.cpp index a733a84fb..afc8a192c 100644 --- a/Editor/ModelImporter_GLTF.cpp +++ b/Editor/ModelImporter_GLTF.cpp @@ -1415,9 +1415,8 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene) const tinygltf::Buffer& sparse_values_buffer = state.gltfModel.buffers[sparse_values_view.buffer]; const uint8_t* sparse_indices_data = sparse_indices_buffer.data.data() + sparse.indices.byteOffset + sparse_indices_view.byteOffset; const uint8_t* sparse_values_data = sparse_values_buffer.data.data() + sparse.values.byteOffset + sparse_values_view.byteOffset; - const size_t sparseOffset = morph_target.sparse_indices.size(); - morph_target.vertex_positions.resize(sparseOffset + sparse.count); - morph_target.sparse_indices.resize(sparseOffset + sparse.count); + morph_target.vertex_positions.resize(sparse.count); + morph_target.sparse_indices_positions.resize(sparse.count); switch (sparse.indices.componentType) { @@ -1425,22 +1424,22 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene) case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + sparse_indices_data[s]; - morph_target.vertex_positions[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_positions[s] = vertexOffset + sparse_indices_data[s]; + morph_target.vertex_positions[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + ((const uint16_t*)sparse_indices_data)[s]; - morph_target.vertex_positions[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_positions[s] = vertexOffset + ((const uint16_t*)sparse_indices_data)[s]; + morph_target.vertex_positions[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + ((const uint32_t*)sparse_indices_data)[s]; - morph_target.vertex_positions[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_positions[s] = vertexOffset + ((const uint32_t*)sparse_indices_data)[s]; + morph_target.vertex_positions[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; } @@ -1473,9 +1472,8 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene) const tinygltf::Buffer& sparse_values_buffer = state.gltfModel.buffers[sparse_values_view.buffer]; const uint8_t* sparse_indices_data = sparse_indices_buffer.data.data() + sparse.indices.byteOffset + sparse_indices_view.byteOffset; const uint8_t* sparse_values_data = sparse_values_buffer.data.data() + sparse.values.byteOffset + sparse_values_view.byteOffset; - const size_t sparseOffset = morph_target.sparse_indices.size(); - morph_target.vertex_normals.resize(sparseOffset + sparse.count); - morph_target.sparse_indices.resize(sparseOffset + sparse.count); + morph_target.vertex_normals.resize(sparse.count); + morph_target.sparse_indices_normals.resize(sparse.count); switch (sparse.indices.componentType) { @@ -1483,22 +1481,22 @@ void ImportModel_GLTF(const std::string& fileName, Scene& scene) case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + sparse_indices_data[s]; - morph_target.vertex_normals[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_normals[s] = vertexOffset + sparse_indices_data[s]; + morph_target.vertex_normals[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + ((const uint16_t*)sparse_indices_data)[s]; - morph_target.vertex_normals[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_normals[s] = vertexOffset + ((const uint16_t*)sparse_indices_data)[s]; + morph_target.vertex_normals[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT: for (int s = 0; s < sparse.count; ++s) { - morph_target.sparse_indices[sparseOffset + s] = vertexOffset + ((const uint32_t*)sparse_indices_data)[s]; - morph_target.vertex_normals[sparseOffset + s] = ((const XMFLOAT3*)sparse_values_data)[s]; + morph_target.sparse_indices_normals[s] = vertexOffset + ((const uint32_t*)sparse_indices_data)[s]; + morph_target.vertex_normals[s] = ((const XMFLOAT3*)sparse_values_data)[s]; } break; } @@ -3939,16 +3937,24 @@ void ExportModel_GLTF(const std::string& filename, Scene& scene) wi::vector> morphs_norm_accessors; for(auto& m_morph : mesh.morph_targets) { - size_t buf_d_morph_idc_offset, buf_d_morph_idc_size, + size_t buf_d_morph_idc_pos_offset, buf_d_morph_idc_pos_size, + buf_d_morph_idc_nor_offset, buf_d_morph_idc_nor_size, buf_d_morph_pos_size, buf_d_morph_pos_offset, buf_d_morph_norm_size, buf_d_morph_norm_offset; - buf_d_morph_idc_offset = buf_i; - for(auto& m_morph_idc : m_morph.sparse_indices) + buf_d_morph_idc_pos_offset = buf_i; + for(auto& m_morph_idc : m_morph.sparse_indices_positions) { _ExportHelper_valuetobuf(m_morph_idc, buffer_builder, buf_i); } - buf_d_morph_idc_size = buf_i - buf_d_morph_idc_offset; + buf_d_morph_idc_pos_size = buf_i - buf_d_morph_idc_pos_offset; + + buf_d_morph_idc_nor_offset = buf_i; + for (auto& m_morph_idc : m_morph.sparse_indices_normals) + { + _ExportHelper_valuetobuf(m_morph_idc, buffer_builder, buf_i); + } + buf_d_morph_idc_nor_size = buf_i - buf_d_morph_idc_nor_offset; buf_d_morph_pos_offset = buf_i; for(auto& m_morph_pos : m_morph.vertex_positions) @@ -3966,23 +3972,23 @@ void ExportModel_GLTF(const std::string& filename, Scene& scene) // Build accessors - // Sparse accessor indices - auto is_sparse = (m_morph.sparse_indices.size() > 0); - int morph_sparse_bufferView_index = 0; - if(is_sparse) - { - tinygltf::BufferView morph_sparse_bufferView_builder; - morph_sparse_bufferView_index = (int)state.gltfModel.bufferViews.size(); - morph_sparse_bufferView_builder.buffer = buffer_index; - morph_sparse_bufferView_builder.byteOffset = buf_d_morph_idc_offset; - morph_sparse_bufferView_builder.byteLength = buf_d_morph_idc_size; - morph_sparse_bufferView_builder.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; - state.gltfModel.bufferViews.push_back(morph_sparse_bufferView_builder); - } - size_t morph_pos_accessor_index; if(buf_d_morph_pos_size > 0) { + // Sparse accessor indices + auto is_sparse = (m_morph.sparse_indices_positions.size() > 0); + int morph_sparse_bufferView_index = 0; + if (is_sparse) + { + tinygltf::BufferView morph_sparse_bufferView_builder; + morph_sparse_bufferView_index = (int)state.gltfModel.bufferViews.size(); + morph_sparse_bufferView_builder.buffer = buffer_index; + morph_sparse_bufferView_builder.byteOffset = buf_d_morph_idc_pos_offset; + morph_sparse_bufferView_builder.byteLength = buf_d_morph_idc_pos_size; + morph_sparse_bufferView_builder.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; + state.gltfModel.bufferViews.push_back(morph_sparse_bufferView_builder); + } + tinygltf::BufferView morph_pos_bufferView_builder; int morph_pos_bufferView_index = (int)state.gltfModel.bufferViews.size(); morph_pos_bufferView_builder.buffer = buffer_index; @@ -4001,7 +4007,7 @@ void ExportModel_GLTF(const std::string& filename, Scene& scene) { auto& sparse = morph_pos_accessor_builder.sparse; sparse.isSparse = true; - sparse.count = (int)m_morph.sparse_indices.size(); + sparse.count = (int)m_morph.sparse_indices_positions.size(); sparse.indices.bufferView = morph_sparse_bufferView_index; sparse.indices.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT; @@ -4014,6 +4020,20 @@ void ExportModel_GLTF(const std::string& filename, Scene& scene) size_t morph_norm_accessor_index; if(buf_d_morph_norm_size > 0) { + // Sparse accessor indices + auto is_sparse = (m_morph.sparse_indices_normals.size() > 0); + int morph_sparse_bufferView_index = 0; + if (is_sparse) + { + tinygltf::BufferView morph_sparse_bufferView_builder; + morph_sparse_bufferView_index = (int)state.gltfModel.bufferViews.size(); + morph_sparse_bufferView_builder.buffer = buffer_index; + morph_sparse_bufferView_builder.byteOffset = buf_d_morph_idc_nor_offset; + morph_sparse_bufferView_builder.byteLength = buf_d_morph_idc_nor_size; + morph_sparse_bufferView_builder.target = TINYGLTF_TARGET_ELEMENT_ARRAY_BUFFER; + state.gltfModel.bufferViews.push_back(morph_sparse_bufferView_builder); + } + tinygltf::BufferView morph_norm_bufferView_builder; int morph_norm_bufferView_index = (int)state.gltfModel.bufferViews.size(); morph_norm_bufferView_builder.buffer = buffer_index; @@ -4034,7 +4054,7 @@ void ExportModel_GLTF(const std::string& filename, Scene& scene) { auto& sparse = morph_norm_accessor_builder.sparse; sparse.isSparse = true; - sparse.count = (int)m_morph.sparse_indices.size(); + sparse.count = (int)m_morph.sparse_indices_normals.size(); sparse.indices.bufferView = morph_sparse_bufferView_index; sparse.indices.componentType = TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT; diff --git a/WickedEngine/wiScene.cpp b/WickedEngine/wiScene.cpp index 8dbc9a184..92f1a4720 100644 --- a/WickedEngine/wiScene.cpp +++ b/WickedEngine/wiScene.cpp @@ -2836,37 +2836,47 @@ namespace wi::scene { if (morph.weight <= 0) continue; - if (morph.sparse_indices.empty()) + if (morph.sparse_indices_positions.empty()) { + // Flat update: for (size_t i = 0; i < morph.vertex_positions.size(); ++i) { mesh.morph_temp_pos[i].x += morph.weight * morph.vertex_positions[i].x; mesh.morph_temp_pos[i].y += morph.weight * morph.vertex_positions[i].y; mesh.morph_temp_pos[i].z += morph.weight * morph.vertex_positions[i].z; - - if (!morph.vertex_normals.empty()) - { - mesh.morph_temp_nor[i].x += morph.weight * morph.vertex_normals[i].x; - mesh.morph_temp_nor[i].y += morph.weight * morph.vertex_normals[i].y; - mesh.morph_temp_nor[i].z += morph.weight * morph.vertex_normals[i].z; - } } } else { - for (size_t i = 0; i < morph.sparse_indices.size(); ++i) + // Sparse update: + for (size_t i = 0; i < morph.sparse_indices_positions.size(); ++i) { - const uint32_t ind = morph.sparse_indices[i]; + const uint32_t ind = morph.sparse_indices_positions[i]; mesh.morph_temp_pos[ind].x += morph.weight * morph.vertex_positions[i].x; mesh.morph_temp_pos[ind].y += morph.weight * morph.vertex_positions[i].y; mesh.morph_temp_pos[ind].z += morph.weight * morph.vertex_positions[i].z; + } + } - if (!morph.vertex_normals.empty()) - { - mesh.morph_temp_nor[ind].x += morph.weight * morph.vertex_normals[i].x; - mesh.morph_temp_nor[ind].y += morph.weight * morph.vertex_normals[i].y; - mesh.morph_temp_nor[ind].z += morph.weight * morph.vertex_normals[i].z; - } + if (morph.sparse_indices_normals.empty()) + { + // Flat update: + for (size_t i = 0; i < morph.vertex_normals.size(); ++i) + { + mesh.morph_temp_nor[i].x += morph.weight * morph.vertex_normals[i].x; + mesh.morph_temp_nor[i].y += morph.weight * morph.vertex_normals[i].y; + mesh.morph_temp_nor[i].z += morph.weight * morph.vertex_normals[i].z; + } + } + else + { + // Sparse update: + for (size_t i = 0; i < morph.sparse_indices_normals.size(); ++i) + { + const uint32_t ind = morph.sparse_indices_normals[i]; + mesh.morph_temp_nor[ind].x += morph.weight * morph.vertex_normals[i].x; + mesh.morph_temp_nor[ind].y += morph.weight * morph.vertex_normals[i].y; + mesh.morph_temp_nor[ind].z += morph.weight * morph.vertex_normals[i].z; } } } diff --git a/WickedEngine/wiScene.h b/WickedEngine/wiScene.h index 1945687c2..a8b7ddeb1 100644 --- a/WickedEngine/wiScene.h +++ b/WickedEngine/wiScene.h @@ -29,7 +29,7 @@ namespace wi::scene wi::ecs::ComponentManager& transforms = componentLibrary.Register("wi::scene::Scene::transforms"); wi::ecs::ComponentManager& hierarchy = componentLibrary.Register("wi::scene::Scene::hierarchy"); wi::ecs::ComponentManager& materials = componentLibrary.Register("wi::scene::Scene::materials", 1); // version = 1 - wi::ecs::ComponentManager& meshes = componentLibrary.Register("wi::scene::Scene::meshes", 1); // version = 1 + wi::ecs::ComponentManager& meshes = componentLibrary.Register("wi::scene::Scene::meshes", 2); // version = 2 wi::ecs::ComponentManager& impostors = componentLibrary.Register("wi::scene::Scene::impostors"); wi::ecs::ComponentManager& objects = componentLibrary.Register("wi::scene::Scene::objects", 1); // version = 1 wi::ecs::ComponentManager& rigidbodies = componentLibrary.Register("wi::scene::Scene::rigidbodies", 1); // version = 1 diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index 4b2f48941..f0cc50ae8 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -360,7 +360,8 @@ namespace wi::scene { wi::vector vertex_positions; wi::vector vertex_normals; - wi::vector sparse_indices; // optional, these can be used to target vertices indirectly + wi::vector sparse_indices_positions; // optional, these can be used to target vertices indirectly + wi::vector sparse_indices_normals; // optional, these can be used to target vertices indirectly float weight = 0; }; wi::vector morph_targets; diff --git a/WickedEngine/wiScene_Serializers.cpp b/WickedEngine/wiScene_Serializers.cpp index 7ebbc81cf..b4efa2eb1 100644 --- a/WickedEngine/wiScene_Serializers.cpp +++ b/WickedEngine/wiScene_Serializers.cpp @@ -417,7 +417,11 @@ namespace wi::scene archive >> morph_targets[i].weight; if (seri.GetVersion() >= 1) { - archive >> morph_targets[i].sparse_indices; + archive >> morph_targets[i].sparse_indices_positions; + } + if (seri.GetVersion() >= 2) + { + archive >> morph_targets[i].sparse_indices_normals; } } } @@ -490,7 +494,11 @@ namespace wi::scene archive << morph_targets[i].weight; if (seri.GetVersion() >= 1) { - archive << morph_targets[i].sparse_indices; + archive << morph_targets[i].sparse_indices_positions; + } + if (seri.GetVersion() >= 2) + { + archive << morph_targets[i].sparse_indices_normals; } } } diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index 867b515fc..4155e4efa 100644 --- a/WickedEngine/wiVersion.cpp +++ b/WickedEngine/wiVersion.cpp @@ -9,7 +9,7 @@ namespace wi::version // minor features, major updates, breaking compatibility changes const int minor = 71; // minor bug fixes, alterations, refactors, updates - const int revision = 105; + const int revision = 106; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);