From 21047ac8ac6ae7905ecf43dbe6d5887148f026fc Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 24 Feb 2025 23:46:44 +0100 Subject: [PATCH] Upgrade `CollisionCooking` to use new `MeshAccessor` --- Source/Engine/Graphics/Models/MeshAccessor.h | 10 +++ Source/Engine/Graphics/Models/MeshBase.cpp | 90 ++++++++++++++++++++ Source/Engine/Physics/CollisionCooking.cpp | 26 ++---- 3 files changed, 107 insertions(+), 19 deletions(-) diff --git a/Source/Engine/Graphics/Models/MeshAccessor.h b/Source/Engine/Graphics/Models/MeshAccessor.h index 3fc7f689f..29ec406f2 100644 --- a/Source/Engine/Graphics/Models/MeshAccessor.h +++ b/Source/Engine/Graphics/Models/MeshAccessor.h @@ -89,6 +89,16 @@ public: // Check input data and stream type with IsLinear before calling. void SetLinear(const void* data); + + // Copies the contents of the input data span into the elements of this stream. + void Set(Span src); + void Set(Span src); + void Set(Span src); + + // Copies the contents of this stream into a destination data span. + void CopyTo(Span dst) const; + void CopyTo(Span dst) const; + void CopyTo(Span dst) const; }; private: diff --git a/Source/Engine/Graphics/Models/MeshBase.cpp b/Source/Engine/Graphics/Models/MeshBase.cpp index 229edde7c..5c38dd24b 100644 --- a/Source/Engine/Graphics/Models/MeshBase.cpp +++ b/Source/Engine/Graphics/Models/MeshBase.cpp @@ -89,6 +89,96 @@ void MeshAccessor::Stream::SetLinear(const void* data) Platform::MemoryCopy(_data.Get(), data, _data.Length()); } +void MeshAccessor::Stream::Set(Span src) +{ + const int32 count = GetCount(); + ASSERT(src.Length() >= count); + if (IsLinear(PixelFormat::R32G32_Float)) + { + Platform::MemoryCopy(_data.Get(), src.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + _sampler.Write(_data.Get() + i * _stride, Float4(src.Get()[i], 0, 0)); + } +} + +void MeshAccessor::Stream::Set(Span src) +{ + const int32 count = GetCount(); + ASSERT(src.Length() >= count); + if (IsLinear(PixelFormat::R32G32B32_Float)) + { + Platform::MemoryCopy(_data.Get(), src.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + _sampler.Write(_data.Get() + i * _stride, Float4(src.Get()[i], 0)); + } +} + +inline void MeshAccessor::Stream::Set(Span<::Color> src) +{ + const int32 count = GetCount(); + ASSERT(src.Length() >= count); + if (IsLinear(PixelFormat::R32G32B32A32_Float)) + { + Platform::MemoryCopy(_data.Get(), src.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + _sampler.Write(_data.Get() + i * _stride, Float4(src.Get()[i])); + } +} + +void MeshAccessor::Stream::CopyTo(Span dst) const +{ + const int32 count = GetCount(); + ASSERT(dst.Length() >= count); + if (IsLinear(PixelFormat::R32G32_Float)) + { + Platform::MemoryCopy(dst.Get(), _data.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + dst.Get()[i] = Float2(_sampler.Read(_data.Get() + i * _stride)); + } +} + +void MeshAccessor::Stream::CopyTo(Span dst) const +{ + const int32 count = GetCount(); + ASSERT(dst.Length() >= count); + if (IsLinear(PixelFormat::R32G32B32_Float)) + { + Platform::MemoryCopy(dst.Get(), _data.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + dst.Get()[i] = Float3(_sampler.Read(_data.Get() + i * _stride)); + } +} + +void MeshAccessor::Stream::CopyTo(Span<::Color> dst) const +{ + const int32 count = GetCount(); + ASSERT(dst.Length() >= count); + if (IsLinear(PixelFormat::R32G32B32A32_Float)) + { + Platform::MemoryCopy(dst.Get(), _data.Get(), _data.Length()); + } + else + { + for (int32 i = 0; i < count; i++) + dst.Get()[i] = ::Color(_sampler.Read(_data.Get() + i * _stride)); + } +} + bool MeshAccessor::LoadMesh(const MeshBase* mesh, bool forceGpu, Span buffers) { CHECK_RETURN(mesh, true); diff --git a/Source/Engine/Physics/CollisionCooking.cpp b/Source/Engine/Physics/CollisionCooking.cpp index 97b01c70f..cbfb91e5a 100644 --- a/Source/Engine/Physics/CollisionCooking.cpp +++ b/Source/Engine/Physics/CollisionCooking.cpp @@ -4,8 +4,10 @@ #include "CollisionCooking.h" #include "Engine/Threading/Task.h" +#include "Engine/Graphics/GPUBuffer.h" #include "Engine/Graphics/Async/GPUTask.h" #include "Engine/Graphics/Models/MeshBase.h" +#include "Engine/Graphics/Models/MeshAccessor.h" #include "Engine/Threading/Threading.h" #include "Engine/Profiler/ProfilerCPU.h" #include "Engine/Core/Log.h" @@ -216,21 +218,11 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali const int32 vertexCount = vertexCounts[i]; if (vertexCount == 0) continue; - const int32 vStride = vData.Length() / vertexCount; - if (vStride == sizeof(Float3)) - Platform::MemoryCopy(finalVertexData.Get() + firstVertexIndex, vData.Get(), vertexCount * sizeof(Float3)); - else - { - // This assumes that each vertex structure contains position as Float3 in the beginning - auto dst = finalVertexData.Get() + firstVertexIndex; - auto src = vData.Get(); - for (int32 j = 0; j < vertexCount; j++) - { - *dst++ = *(Float3*)src; - src += vStride; - - } - } + MeshAccessor accessor; + if (accessor.LoadBuffer(MeshBufferType::Vertex0, Span(vData), mesh.GetVertexBuffer(0)->GetVertexLayout())) + continue; + auto positionStream = accessor.Position(); + positionStream.CopyTo(Span(finalVertexData.Get() + firstVertexIndex, vertexCount)); vertexCounter += vertexCount; if (needIndexBuffer) @@ -242,9 +234,7 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali auto dst = finalIndexData.Get() + indexCounter; auto src = iData.Get(); for (int32 j = 0; j < indexCount; j++) - { *dst++ = firstVertexIndex + *src++; - } indexCounter += indexCount; } else @@ -252,9 +242,7 @@ bool CollisionCooking::CookCollision(const Argument& arg, CollisionData::Seriali auto dst = finalIndexData.Get() + indexCounter; auto src = iData.Get(); for (int32 j = 0; j < indexCount; j++) - { *dst++ = firstVertexIndex + *src++; - } indexCounter += indexCount; } }