LOD and subset management fixes

This commit is contained in:
Turánszki János
2025-03-29 10:30:51 +01:00
parent d1578b0179
commit 60d82edb7f
5 changed files with 97 additions and 56 deletions
+5 -20
View File
@@ -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<MeshComponent::MeshSubset> 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));
}
}
});
+5 -26
View File
@@ -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
{
+77 -9
View File
@@ -1937,6 +1937,7 @@ namespace wi::scene
}
size_t MeshComponent::CreateSubset()
{
wi::vector<MeshSubset> 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<MeshSubset> 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()
{
+9
View File
@@ -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();
+1 -1
View File
@@ -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);