diff --git a/Editor/MeshWindow.cpp b/Editor/MeshWindow.cpp index 0e38d434e..d833772b3 100644 --- a/Editor/MeshWindow.cpp +++ b/Editor/MeshWindow.cpp @@ -48,7 +48,7 @@ void MeshWindow::Create(EditorComponent* _editor) float step = hei + 2; float wid = 170; - float infolabel_height = 280; + float infolabel_height = 360; meshInfoLabel.Create("Mesh Info"); meshInfoLabel.SetPos(XMFLOAT2(20, y)); meshInfoLabel.SetSize(XMFLOAT2(260, infolabel_height)); @@ -100,21 +100,8 @@ void MeshWindow::Create(EditorComponent* _editor) int selected = subsetComboBox.GetSelected(); - uint32_t first_subset = 0; - uint32_t last_subset = 0; - mesh->GetLODSubsetRange(0, first_subset, last_subset); - wi::vector newSubsets; - int s = 0; - for (uint32_t i = first_subset; i < last_subset; ++i) - { - if (s != selected) - { - newSubsets.push_back(mesh->subsets[i]); - } - s++; - } - mesh->subsets = newSubsets; - mesh->subsets_per_lod = 0; + mesh->DeleteSubset(uint32_t(selected)); + SetEntity(entity, selected - 1); editor->RecordEntity(archive, entity); @@ -831,15 +818,13 @@ void MeshWindow::Create(EditorComponent* _editor) MeshComponent* mesh = scene.meshes.GetComponent(entity); if (mesh != nullptr && subset >= 0 && subset < mesh->subsets.size()) { - MeshComponent::MeshSubset& meshsubset = mesh->subsets[subset]; if (args.iValue == 0) { - meshsubset.materialID = INVALID_ENTITY; + mesh->SetSubsetMaterial(uint32_t(subset), INVALID_ENTITY); } else { - MeshComponent::MeshSubset& meshsubset = mesh->subsets[subset]; - meshsubset.materialID = scene.materials.GetEntity(args.iValue - 1); + mesh->SetSubsetMaterial(uint32_t(subset), scene.materials.GetEntity(args.iValue - 1)); } } }); diff --git a/WickedEngine/wiScene_BindLua.cpp b/WickedEngine/wiScene_BindLua.cpp index e2e7c4542..9ffbdb76a 100644 --- a/WickedEngine/wiScene_BindLua.cpp +++ b/WickedEngine/wiScene_BindLua.cpp @@ -4802,21 +4802,9 @@ int MeshComponent_BindLua::SetMeshSubsetMaterialID(lua_State* L) int argc = wi::lua::SGetArgCount(L); if (argc >= 2) { - size_t subsetindex = (uint32_t)wi::lua::SGetLongLong(L, 1); + uint32_t subsetindex = (uint32_t)wi::lua::SGetLongLong(L, 1); Entity entity = (Entity)wi::lua::SGetLongLong(L, 2); - - const uint32_t lod_count = component->GetLODCount(); - for (uint32_t lod = 0; lod < lod_count; ++lod) - { - uint32_t first_subset = 0; - uint32_t last_subset = 0; - component->GetLODSubsetRange(lod, first_subset, last_subset); - size_t subset_offset = first_subset + subsetindex; - if (subset_offset < last_subset) - { - component->subsets[subset_offset].materialID = entity; - } - } + component->SetSubsetMaterial(subsetindex, entity); } else { @@ -4830,18 +4818,9 @@ int MeshComponent_BindLua::GetMeshSubsetMaterialID(lua_State* L) int argc = wi::lua::SGetArgCount(L); if (argc > 0) { - size_t subsetindex = wi::lua::SGetLongLong(L, 1); - - if(subsetindex < component->subsets.size()) - { - auto& subsetdata = component->subsets[subsetindex]; - wi::lua::SSetLongLong(L, subsetdata.materialID); - return 1; - } - else - { - wi::lua::SError(L, "GetMeshSubsetMaterialID(int subsetindex) index out of range!"); - } + uint32_t subsetindex = (uint32_t)wi::lua::SGetLongLong(L, 1); + wi::lua::SSetLongLong(L, component->GetSubsetMaterial(subsetindex)); + return 1; } else { diff --git a/WickedEngine/wiScene_Components.cpp b/WickedEngine/wiScene_Components.cpp index 872373d27..b1bccb3d4 100644 --- a/WickedEngine/wiScene_Components.cpp +++ b/WickedEngine/wiScene_Components.cpp @@ -1937,6 +1937,7 @@ namespace wi::scene } size_t MeshComponent::CreateSubset() { + wi::vector new_subsets; int ret = 0; const uint32_t lod_count = GetLODCount(); for (uint32_t lod = 0; lod < lod_count; ++lod) @@ -1944,27 +1945,94 @@ namespace wi::scene uint32_t first_subset = 0; uint32_t last_subset = 0; GetLODSubsetRange(lod, first_subset, last_subset); - MeshComponent::MeshSubset subset; - subset.indexOffset = ~0u; - subset.indexCount = 0; + uint32_t firstIndex = ~0u; + uint32_t lastIndex = 0u; for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex) { - subset.indexOffset = std::min(subset.indexOffset, subsets[subsetIndex].indexOffset); - subset.indexCount = std::max(subset.indexCount, subsets[subsetIndex].indexOffset + subsets[subsetIndex].indexCount); + const MeshComponent::MeshSubset& subset = subsets[subsetIndex]; + firstIndex = std::min(firstIndex, subset.indexOffset); + lastIndex = std::max(lastIndex, subset.indexOffset + subset.indexCount); + new_subsets.push_back(subset); } - subsets.insert(subsets.begin() + last_subset, subset); - if (lod == 0) + if (lastIndex > firstIndex) { - ret = last_subset; + MeshComponent::MeshSubset& subset = new_subsets.emplace_back(); + subset.indexOffset = firstIndex; + subset.indexCount = lastIndex - firstIndex; + if (lod == 0) + { + ret = last_subset; + } } } if (subsets_per_lod > 0) { subsets_per_lod++; } - CreateRenderData(); // mesh shader needs to rebuild clusters, otherwise wouldn't be needed + std::swap(subsets, new_subsets); + if (wi::renderer::IsMeshShaderAllowed() || !cluster_ranges.empty()) + { + // mesh shader needs to rebuild clusters, otherwise not be needed + CreateRenderData(); + } return ret; } + void MeshComponent::DeleteSubset(uint32_t subsetIndexToDelete) + { + wi::vector new_subsets; + const uint32_t lod_count = GetLODCount(); + for (uint32_t lod = 0; lod < lod_count; ++lod) + { + uint32_t first_subset = 0; + uint32_t last_subset = 0; + GetLODSubsetRange(lod, first_subset, last_subset); + uint32_t firstIndex = ~0u; + uint32_t lastIndex = 0u; + for (uint32_t subsetIndex = first_subset; subsetIndex < last_subset; ++subsetIndex) + { + if (subsetIndexToDelete != (subsetIndex - first_subset)) + { + new_subsets.push_back(subsets[subsetIndex]); + } + } + } + if (subsets_per_lod > 0) + { + subsets_per_lod--; + } + std::swap(subsets, new_subsets); + if (wi::renderer::IsMeshShaderAllowed() || !cluster_ranges.empty()) + { + // mesh shader needs to rebuild clusters, otherwise not be needed + CreateRenderData(); + } + } + void MeshComponent::SetSubsetMaterial(uint32_t subsetIndex, Entity entity) + { + const uint32_t lod_count = GetLODCount(); + for (uint32_t lod = 0; lod < lod_count; ++lod) + { + uint32_t first_subset = 0; + uint32_t last_subset = 0; + GetLODSubsetRange(lod, first_subset, last_subset); + size_t subset_offset = first_subset + subsetIndex; + if (subset_offset < last_subset) + { + subsets[subset_offset].materialID = entity; + } + } + } + Entity MeshComponent::GetSubsetMaterial(uint32_t subsetIndex) + { + uint32_t first_subset = 0; + uint32_t last_subset = 0; + GetLODSubsetRange(0, first_subset, last_subset); + if (subsetIndex >= first_subset && subsetIndex < last_subset) + { + return subsets[subsetIndex].materialID; + } + return INVALID_ENTITY; + } void ObjectComponent::ClearLightmap() { diff --git a/WickedEngine/wiScene_Components.h b/WickedEngine/wiScene_Components.h index 7f67d7169..f6cd875c8 100644 --- a/WickedEngine/wiScene_Components.h +++ b/WickedEngine/wiScene_Components.h @@ -702,6 +702,15 @@ namespace wi::scene // Creates a new subset as a combination of the subsets of the first LOD, returns its index. This works if there are multiple LODs which are also contained in subsets array size_t CreateSubset(); + // Deletes a subset from all LODs + void DeleteSubset(uint32_t subsetIndex); + + // Set a material to a subset in all LODs + void SetSubsetMaterial(uint32_t subsetIndex, wi::ecs::Entity entity); + + // Get the material from the subsetIndex in the first LOD + wi::ecs::Entity GetSubsetMaterial(uint32_t subsetIndex); + // Deletes all GPU resources void DeleteRenderData(); diff --git a/WickedEngine/wiVersion.cpp b/WickedEngine/wiVersion.cpp index b4155eb4c..7726503ba 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 = 725; + const int revision = 726; const std::string version_string = std::to_string(major) + "." + std::to_string(minor) + "." + std::to_string(revision);