From 1a5606a45cd6cd4f21b5afe3a75432a3e2c302ac Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 13 Oct 2023 23:33:03 +0200 Subject: [PATCH] Improve collision data cooking usability #1687 --- Source/Engine/Graphics/Models/Mesh.cpp | 2 +- Source/Engine/Physics/CollisionCooking.cpp | 6 ++++++ Source/Engine/Physics/CollisionData.cpp | 14 ++++++-------- 3 files changed, 13 insertions(+), 9 deletions(-) diff --git a/Source/Engine/Graphics/Models/Mesh.cpp b/Source/Engine/Graphics/Models/Mesh.cpp index f03c013c6..1e531d0e0 100644 --- a/Source/Engine/Graphics/Models/Mesh.cpp +++ b/Source/Engine/Graphics/Models/Mesh.cpp @@ -609,7 +609,7 @@ bool Mesh::DownloadDataCPU(MeshBufferType type, BytesContainer& result, int32& c ScopeLock lock(model->Locker); if (model->IsVirtual()) { - LOG(Error, "Cannot access CPU data of virtual models. Use GPU data download"); + LOG(Error, "Cannot access CPU data of virtual models. Use GPU data download."); return true; } diff --git a/Source/Engine/Physics/CollisionCooking.cpp b/Source/Engine/Physics/CollisionCooking.cpp index dc2c42584..4c8cffdcc 100644 --- a/Source/Engine/Physics/CollisionCooking.cpp +++ b/Source/Engine/Physics/CollisionCooking.cpp @@ -127,6 +127,8 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali const auto& mesh = *meshes[i]; if ((arg.MaterialSlotsMask & (1 << mesh.GetMaterialSlotIndex())) == 0) continue; + if (mesh.GetVertexCount() == 0) + continue; int32 count; if (mesh.DownloadDataCPU(MeshBufferType::Vertex0, vertexBuffers[i], count)) @@ -159,6 +161,8 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali const auto& mesh = *meshes[i]; if ((arg.MaterialSlotsMask & (1 << mesh.GetMaterialSlotIndex())) == 0) continue; + if (mesh.GetVertexCount() == 0) + continue; auto task = mesh.DownloadDataGPUAsync(MeshBufferType::Vertex0, vertexBuffers[i]); if (task == nullptr) @@ -208,6 +212,8 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali const int32 firstVertexIndex = vertexCounter; const int32 vertexCount = vertexCounts[i]; + if (vertexCount == 0) + continue; Platform::MemoryCopy(finalVertexData.Get() + firstVertexIndex, vData.Get(), vertexCount * sizeof(Float3)); vertexCounter += vertexCount; diff --git a/Source/Engine/Physics/CollisionData.cpp b/Source/Engine/Physics/CollisionData.cpp index 36f28c111..54a49671d 100644 --- a/Source/Engine/Physics/CollisionData.cpp +++ b/Source/Engine/Physics/CollisionData.cpp @@ -23,12 +23,16 @@ CollisionData::CollisionData(const SpawnParams& params, const AssetInfo* info) bool CollisionData::CookCollision(CollisionDataType type, ModelBase* modelObj, int32 modelLodIndex, uint32 materialSlotsMask, ConvexMeshGenerationFlags convexFlags, int32 convexVertexLimit) { - // Validate state if (!IsVirtual()) { LOG(Warning, "Only virtual assets can be modified at runtime."); return true; } + if (IsInMainThread() && modelObj && modelObj->IsVirtual()) + { + LOG(Error, "Cannot cook collision data for virtual models on a main thread (virtual models data is stored on GPU only). Use thread pool or async task."); + return true; + } // Prepare CollisionCooking::Argument arg; @@ -43,18 +47,12 @@ bool CollisionData::CookCollision(CollisionDataType type, ModelBase* modelObj, i SerializedOptions options; BytesContainer outputData; if (CollisionCooking::CookCollision(arg, options, outputData)) - { return true; - } - - // Clear state - unload(true); // Load data + unload(true); if (load(&options, outputData.Get(), outputData.Length()) != LoadResult::Ok) - { return true; - } // Mark as loaded (eg. Mesh Colliders using this asset will update shape for physics simulation) onLoaded();