From c19ff9eb2f72c04c93f3a82aa76769cece96aa29 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Sat, 12 Jul 2025 16:56:17 +0200 Subject: [PATCH 01/32] enable STL loader and writer in CMake --- src/nbl/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nbl/CMakeLists.txt b/src/nbl/CMakeLists.txt index cd9572daa5..1d35f415f3 100755 --- a/src/nbl/CMakeLists.txt +++ b/src/nbl/CMakeLists.txt @@ -52,8 +52,8 @@ include(common) option(_NBL_COMPILE_WITH_MTL_LOADER_ "Compile with MTL Loader" OFF) #default off until Material Compiler 2 option(_NBL_COMPILE_WITH_OBJ_LOADER_ "Compile with OBJ Loader" OFF) #default off until Material Compiler 2 #option(_NBL_COMPILE_WITH_OBJ_WRITER_ "Compile with OBJ Writer" ON) uncomment when writer exists -option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" OFF) #default off until reimplemented -option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" OFF) #default off until reimplemented +option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" ON) +option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" ON) option(_NBL_COMPILE_WITH_PLY_LOADER_ "Compile with PLY Loader" ON) option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" OFF) #default off until reimplemented option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON) From 549ada6b2a5a011e3a1b3502a723c97cfed6a59b Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Sat, 12 Jul 2025 17:05:51 +0200 Subject: [PATCH 02/32] enable PLY writer too --- src/nbl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nbl/CMakeLists.txt b/src/nbl/CMakeLists.txt index 1d35f415f3..d3810ecee2 100755 --- a/src/nbl/CMakeLists.txt +++ b/src/nbl/CMakeLists.txt @@ -55,7 +55,7 @@ option(_NBL_COMPILE_WITH_OBJ_LOADER_ "Compile with OBJ Loader" OFF) #default off option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" ON) option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" ON) option(_NBL_COMPILE_WITH_PLY_LOADER_ "Compile with PLY Loader" ON) -option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" OFF) #default off until reimplemented +option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" ON) #default off until reimplemented option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON) option(_NBL_COMPILE_WITH_JPG_WRITER_ "Compile with JPG Writer" ON) option(_NBL_COMPILE_WITH_PNG_LOADER_ "Compile with PNG Loader" ON) From 5e6316d975ca502dfe3ba4758d45c43199112ddc Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Mon, 14 Jul 2025 23:44:19 +0200 Subject: [PATCH 03/32] comment out initialize function for further inspection, implement missing performActionBasedOnOrientationSystem --- .../asset/interchange/CSTLMeshFileLoader.cpp | 197 +++++++++--------- .../asset/interchange/CSTLMeshFileLoader.h | 62 +++--- 2 files changed, 127 insertions(+), 132 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index d00c37cf10..515e61f73c 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -22,108 +22,101 @@ constexpr auto COLOR_ATTRIBUTE = 1; constexpr auto UV_ATTRIBUTE = 2; constexpr auto NORMAL_ATTRIBUTE = 3; -CSTLMeshFileLoader::CSTLMeshFileLoader(asset::IAssetManager* _m_assetMgr) - : IRenderpassIndependentPipelineLoader(_m_assetMgr), m_assetMgr(_m_assetMgr) -{ - -} - -void CSTLMeshFileLoader::initialize() -{ - IRenderpassIndependentPipelineLoader::initialize(); - - auto precomputeAndCachePipeline = [&](bool withColorAttribute) - { - auto getShaderDefaultPaths = [&]() -> std::pair - { - if (withColorAttribute) - return std::make_pair("nbl/builtin/material/debug/vertex_color/specialized_shader.vert", "nbl/builtin/material/debug/vertex_color/specialized_shader.frag"); - else - return std::make_pair("nbl/builtin/material/debug/vertex_normal/specialized_shader.vert", "nbl/builtin/material/debug/vertex_normal/specialized_shader.frag"); - }; - - auto defaultOverride = IAssetLoaderOverride(m_assetMgr); - const std::string pipelineCacheHash = getPipelineCacheKey(withColorAttribute).data(); - const uint32_t _hierarchyLevel = 0; - const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); - - const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u }; - auto pipelineBundle = defaultOverride.findCachedAsset(pipelineCacheHash, types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); - if (pipelineBundle.getContents().empty()) - { - auto mbVertexShader = core::smart_refctd_ptr(); - auto mbFragmentShader = core::smart_refctd_ptr(); - { - const IAsset::E_TYPE types[]{ IAsset::E_TYPE::ET_SPECIALIZED_SHADER, static_cast(0u) }; - const auto shaderPaths = getShaderDefaultPaths(); - - auto vertexShaderBundle = m_assetMgr->findAssets(shaderPaths.first.data(), types); - auto fragmentShaderBundle = m_assetMgr->findAssets(shaderPaths.second.data(), types); - - mbVertexShader = core::smart_refctd_ptr_static_cast(vertexShaderBundle->begin()->getContents().begin()[0]); - mbFragmentShader = core::smart_refctd_ptr_static_cast(fragmentShaderBundle->begin()->getContents().begin()[0]); - } - - auto defaultOverride = IAssetLoaderOverride(m_assetMgr); - - const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); - auto mbBundlePipelineLayout = defaultOverride.findDefaultAsset("nbl/builtin/pipeline_layout/loader/STL", fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::PIPELINE_LAYOUT_HIERARCHYLEVELS_BELOW); - auto mbPipelineLayout = mbBundlePipelineLayout.first; - - auto const positionFormatByteSize = getTexelOrBlockBytesize(EF_R32G32B32_SFLOAT); - auto const colorFormatByteSize = withColorAttribute ? getTexelOrBlockBytesize(EF_B8G8R8A8_UNORM) : 0; - auto const normalFormatByteSize = getTexelOrBlockBytesize(EF_A2B10G10R10_SNORM_PACK32); - - SVertexInputParams mbInputParams; - const auto stride = positionFormatByteSize + colorFormatByteSize + normalFormatByteSize; - mbInputParams.enabledBindingFlags |= core::createBitmask({ 0 }); - mbInputParams.enabledAttribFlags |= core::createBitmask({ POSITION_ATTRIBUTE, NORMAL_ATTRIBUTE, withColorAttribute ? COLOR_ATTRIBUTE : 0 }); - mbInputParams.bindings[0] = { stride, EVIR_PER_VERTEX }; - - mbInputParams.attributes[POSITION_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; - mbInputParams.attributes[POSITION_ATTRIBUTE].relativeOffset = 0; - mbInputParams.attributes[POSITION_ATTRIBUTE].binding = 0; - - if (withColorAttribute) - { - mbInputParams.attributes[COLOR_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; - mbInputParams.attributes[COLOR_ATTRIBUTE].relativeOffset = positionFormatByteSize; - mbInputParams.attributes[COLOR_ATTRIBUTE].binding = 0; - } - - mbInputParams.attributes[NORMAL_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; - mbInputParams.attributes[NORMAL_ATTRIBUTE].relativeOffset = positionFormatByteSize + colorFormatByteSize; - mbInputParams.attributes[NORMAL_ATTRIBUTE].binding = 0; - - SBlendParams blendParams; - SPrimitiveAssemblyParams primitiveAssemblyParams; - primitiveAssemblyParams.primitiveType = E_PRIMITIVE_TOPOLOGY::EPT_TRIANGLE_LIST; - - SRasterizationParams rastarizationParmas; - - auto mbPipeline = core::make_smart_refctd_ptr(std::move(mbPipelineLayout), nullptr, nullptr, mbInputParams, blendParams, primitiveAssemblyParams, rastarizationParmas); - { - mbPipeline->setShaderAtStage(asset::IShader::ESS_VERTEX, mbVertexShader.get()); - mbPipeline->setShaderAtStage(asset::IShader::ESS_FRAGMENT, mbFragmentShader.get()); - } - - asset::SAssetBundle newPipelineBundle(nullptr, {core::smart_refctd_ptr(mbPipeline)}); - defaultOverride.insertAssetIntoCache(newPipelineBundle, pipelineCacheHash, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); - } - else - return; - }; - - /* - Pipeline permutations are cached - */ - - precomputeAndCachePipeline(true); - precomputeAndCachePipeline(false); -} +//void CSTLMeshFileLoader::initialize() +//{ +// auto precomputeAndCachePipeline = [&](bool withColorAttribute) +// { +// auto getShaderDefaultPaths = [&]() -> std::pair +// { +// if (withColorAttribute) +// return std::make_pair("nbl/builtin/material/debug/vertex_color/specialized_shader.vert", "nbl/builtin/material/debug/vertex_color/specialized_shader.frag"); +// else +// return std::make_pair("nbl/builtin/material/debug/vertex_normal/specialized_shader.vert", "nbl/builtin/material/debug/vertex_normal/specialized_shader.frag"); +// }; +// +// auto defaultOverride = IAssetLoaderOverride(m_assetMgr); +// const std::string pipelineCacheHash = getPipelineCacheKey(withColorAttribute).data(); +// const uint32_t _hierarchyLevel = 0; +// const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); +// +// const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u }; +// auto pipelineBundle = defaultOverride.findCachedAsset(pipelineCacheHash, types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); +// if (pipelineBundle.getContents().empty()) +// { +// auto mbVertexShader = core::smart_refctd_ptr(); +// auto mbFragmentShader = core::smart_refctd_ptr(); +// { +// const IAsset::E_TYPE types[]{ IAsset::E_TYPE::ET_SPECIALIZED_SHADER, static_cast(0u) }; +// const auto shaderPaths = getShaderDefaultPaths(); +// +// auto vertexShaderBundle = m_assetMgr->findAssets(shaderPaths.first.data(), types); +// auto fragmentShaderBundle = m_assetMgr->findAssets(shaderPaths.second.data(), types); +// +// mbVertexShader = core::smart_refctd_ptr_static_cast(vertexShaderBundle->begin()->getContents().begin()[0]); +// mbFragmentShader = core::smart_refctd_ptr_static_cast(fragmentShaderBundle->begin()->getContents().begin()[0]); +// } +// +// auto defaultOverride = IAssetLoaderOverride(m_assetMgr); +// +// const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); +// auto mbBundlePipelineLayout = defaultOverride.findDefaultAsset("nbl/builtin/pipeline_layout/loader/STL", fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::PIPELINE_LAYOUT_HIERARCHYLEVELS_BELOW); +// auto mbPipelineLayout = mbBundlePipelineLayout.first; +// +// auto const positionFormatByteSize = getTexelOrBlockBytesize(EF_R32G32B32_SFLOAT); +// auto const colorFormatByteSize = withColorAttribute ? getTexelOrBlockBytesize(EF_B8G8R8A8_UNORM) : 0; +// auto const normalFormatByteSize = getTexelOrBlockBytesize(EF_A2B10G10R10_SNORM_PACK32); +// +// SVertexInputParams mbInputParams; +// const auto stride = positionFormatByteSize + colorFormatByteSize + normalFormatByteSize; +// mbInputParams.enabledBindingFlags |= core::createBitmask({ 0 }); +// mbInputParams.enabledAttribFlags |= core::createBitmask({ POSITION_ATTRIBUTE, NORMAL_ATTRIBUTE, withColorAttribute ? COLOR_ATTRIBUTE : 0 }); +// mbInputParams.bindings[0] = { stride, EVIR_PER_VERTEX }; +// +// mbInputParams.attributes[POSITION_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; +// mbInputParams.attributes[POSITION_ATTRIBUTE].relativeOffset = 0; +// mbInputParams.attributes[POSITION_ATTRIBUTE].binding = 0; +// +// if (withColorAttribute) +// { +// mbInputParams.attributes[COLOR_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; +// mbInputParams.attributes[COLOR_ATTRIBUTE].relativeOffset = positionFormatByteSize; +// mbInputParams.attributes[COLOR_ATTRIBUTE].binding = 0; +// } +// +// mbInputParams.attributes[NORMAL_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; +// mbInputParams.attributes[NORMAL_ATTRIBUTE].relativeOffset = positionFormatByteSize + colorFormatByteSize; +// mbInputParams.attributes[NORMAL_ATTRIBUTE].binding = 0; +// +// SBlendParams blendParams; +// SPrimitiveAssemblyParams primitiveAssemblyParams; +// primitiveAssemblyParams.primitiveType = E_PRIMITIVE_TOPOLOGY::EPT_TRIANGLE_LIST; +// +// SRasterizationParams rastarizationParmas; +// +// auto mbPipeline = core::make_smart_refctd_ptr(std::move(mbPipelineLayout), nullptr, nullptr, mbInputParams, blendParams, primitiveAssemblyParams, rastarizationParmas); +// { +// mbPipeline->setShaderAtStage(asset::IShader::ESS_VERTEX, mbVertexShader.get()); +// mbPipeline->setShaderAtStage(asset::IShader::ESS_FRAGMENT, mbFragmentShader.get()); +// } +// +// asset::SAssetBundle newPipelineBundle(nullptr, {core::smart_refctd_ptr(mbPipeline)}); +// defaultOverride.insertAssetIntoCache(newPipelineBundle, pipelineCacheHash, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); +// } +// else +// return; +// }; +// +// /* +// Pipeline permutations are cached +// */ +// +// precomputeAndCachePipeline(true); +// precomputeAndCachePipeline(false); +//} SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override, uint32_t _hierarchyLevel) { + using namespace nbl::core; if (!_file) return {}; @@ -136,6 +129,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa _override }; + auto geometry = make_smart_refctd_ptr(); const size_t filesize = context.inner.mainFile->getSize(); if (filesize < 6ull) // we need a header @@ -143,11 +137,6 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa bool hasColor = false; - auto mesh = core::make_smart_refctd_ptr(); - auto meshbuffer = core::make_smart_refctd_ptr(); - meshbuffer->setPositionAttributeIx(POSITION_ATTRIBUTE); - meshbuffer->setNormalAttributeIx(NORMAL_ATTRIBUTE); - bool binary = false; std::string token; if (getNextToken(&context, token) != "solid") diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.h b/src/nbl/asset/interchange/CSTLMeshFileLoader.h index f7020ab292..41805365f5 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.h +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.h @@ -18,45 +18,51 @@ namespace nbl::asset //! Meshloader capable of loading STL meshes. class CSTLMeshFileLoader final : public IGeometryLoader { - public: + public: - CSTLMeshFileLoader(asset::IAssetManager* _m_assetMgr); + inline CSTLMeshFileLoader() = default; - asset::SAssetBundle loadAsset(system::IFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override = nullptr, uint32_t _hierarchyLevel = 0u) override; + asset::SAssetBundle loadAsset(system::IFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override = nullptr, uint32_t _hierarchyLevel = 0u) override; - bool isALoadableFileFormat(system::IFile* _file, const system::logger_opt_ptr logger) const override; + bool isALoadableFileFormat(system::IFile* _file, const system::logger_opt_ptr logger) const override; - const char** getAssociatedFileExtensions() const override - { - static const char* ext[]{ "stl", nullptr }; - return ext; - } + const char** getAssociatedFileExtensions() const override + { + static const char* ext[]{ "stl", nullptr }; + return ext; + } - private: - struct SContext - { - IAssetLoader::SAssetLoadContext inner; - uint32_t topHierarchyLevel; - IAssetLoader::IAssetLoaderOverride* loaderOverride; + private: + struct SContext + { + IAssetLoader::SAssetLoadContext inner; + uint32_t topHierarchyLevel; + IAssetLoader::IAssetLoaderOverride* loaderOverride; - size_t fileOffset = {}; - }; + size_t fileOffset = {}; + }; - virtual void initialize() override; + virtual void initialize() override; - const std::string_view getPipelineCacheKey(bool withColorAttribute) { return withColorAttribute ? "nbl/builtin/pipeline/loader/STL/color_attribute" : "nbl/builtin/pipeline/loader/STL/no_color_attribute"; } + const std::string_view getPipelineCacheKey(bool withColorAttribute) { return withColorAttribute ? "nbl/builtin/pipeline/loader/STL/color_attribute" : "nbl/builtin/pipeline/loader/STL/no_color_attribute"; } - // skips to the first non-space character available - void goNextWord(SContext* context) const; - // returns the next word + // skips to the first non-space character available + void goNextWord(SContext* context) const; + // returns the next word - const std::string& getNextToken(SContext* context, std::string& token) const; - // skip to next printable character after the first line break - void goNextLine(SContext* context) const; - //! Read 3d vector of floats - void getNextVector(SContext* context, core::vectorSIMDf& vec, bool binary) const; + const std::string& getNextToken(SContext* context, std::string& token) const; + // skip to next printable character after the first line break + void goNextLine(SContext* context) const; + //! Read 3d vector of floats + void getNextVector(SContext* context, core::vectorSIMDf& vec, bool binary) const; - asset::IAssetManager* m_assetMgr; + asset::IAssetManager* m_assetMgr; + + template + static inline void performActionBasedOnOrientationSystem(aType& varToHandle, void (*performOnCertainOrientation)(aType& varToHandle)) + { + performOnCertainOrientation(varToHandle); + } }; } // end namespace nbl::scene From f522af5ebd8504bcaa9c0ec4b16b7d18cc6486ae Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Tue, 15 Jul 2025 01:33:44 +0200 Subject: [PATCH 04/32] move SContext to .cpp and implement utility functions that used it inside, comment out some legacy code --- .../asset/interchange/CSTLMeshFileLoader.cpp | 316 +++++++----------- .../asset/interchange/CSTLMeshFileLoader.h | 21 -- 2 files changed, 118 insertions(+), 219 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index 515e61f73c..b2803b72e5 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -22,97 +22,109 @@ constexpr auto COLOR_ATTRIBUTE = 1; constexpr auto UV_ATTRIBUTE = 2; constexpr auto NORMAL_ATTRIBUTE = 3; -//void CSTLMeshFileLoader::initialize() -//{ -// auto precomputeAndCachePipeline = [&](bool withColorAttribute) -// { -// auto getShaderDefaultPaths = [&]() -> std::pair -// { -// if (withColorAttribute) -// return std::make_pair("nbl/builtin/material/debug/vertex_color/specialized_shader.vert", "nbl/builtin/material/debug/vertex_color/specialized_shader.frag"); -// else -// return std::make_pair("nbl/builtin/material/debug/vertex_normal/specialized_shader.vert", "nbl/builtin/material/debug/vertex_normal/specialized_shader.frag"); -// }; -// -// auto defaultOverride = IAssetLoaderOverride(m_assetMgr); -// const std::string pipelineCacheHash = getPipelineCacheKey(withColorAttribute).data(); -// const uint32_t _hierarchyLevel = 0; -// const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); -// -// const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u }; -// auto pipelineBundle = defaultOverride.findCachedAsset(pipelineCacheHash, types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); -// if (pipelineBundle.getContents().empty()) -// { -// auto mbVertexShader = core::smart_refctd_ptr(); -// auto mbFragmentShader = core::smart_refctd_ptr(); -// { -// const IAsset::E_TYPE types[]{ IAsset::E_TYPE::ET_SPECIALIZED_SHADER, static_cast(0u) }; -// const auto shaderPaths = getShaderDefaultPaths(); -// -// auto vertexShaderBundle = m_assetMgr->findAssets(shaderPaths.first.data(), types); -// auto fragmentShaderBundle = m_assetMgr->findAssets(shaderPaths.second.data(), types); -// -// mbVertexShader = core::smart_refctd_ptr_static_cast(vertexShaderBundle->begin()->getContents().begin()[0]); -// mbFragmentShader = core::smart_refctd_ptr_static_cast(fragmentShaderBundle->begin()->getContents().begin()[0]); -// } -// -// auto defaultOverride = IAssetLoaderOverride(m_assetMgr); -// -// const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); -// auto mbBundlePipelineLayout = defaultOverride.findDefaultAsset("nbl/builtin/pipeline_layout/loader/STL", fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::PIPELINE_LAYOUT_HIERARCHYLEVELS_BELOW); -// auto mbPipelineLayout = mbBundlePipelineLayout.first; -// -// auto const positionFormatByteSize = getTexelOrBlockBytesize(EF_R32G32B32_SFLOAT); -// auto const colorFormatByteSize = withColorAttribute ? getTexelOrBlockBytesize(EF_B8G8R8A8_UNORM) : 0; -// auto const normalFormatByteSize = getTexelOrBlockBytesize(EF_A2B10G10R10_SNORM_PACK32); -// -// SVertexInputParams mbInputParams; -// const auto stride = positionFormatByteSize + colorFormatByteSize + normalFormatByteSize; -// mbInputParams.enabledBindingFlags |= core::createBitmask({ 0 }); -// mbInputParams.enabledAttribFlags |= core::createBitmask({ POSITION_ATTRIBUTE, NORMAL_ATTRIBUTE, withColorAttribute ? COLOR_ATTRIBUTE : 0 }); -// mbInputParams.bindings[0] = { stride, EVIR_PER_VERTEX }; -// -// mbInputParams.attributes[POSITION_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; -// mbInputParams.attributes[POSITION_ATTRIBUTE].relativeOffset = 0; -// mbInputParams.attributes[POSITION_ATTRIBUTE].binding = 0; -// -// if (withColorAttribute) -// { -// mbInputParams.attributes[COLOR_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; -// mbInputParams.attributes[COLOR_ATTRIBUTE].relativeOffset = positionFormatByteSize; -// mbInputParams.attributes[COLOR_ATTRIBUTE].binding = 0; -// } -// -// mbInputParams.attributes[NORMAL_ATTRIBUTE].format = EF_R32G32B32_SFLOAT; -// mbInputParams.attributes[NORMAL_ATTRIBUTE].relativeOffset = positionFormatByteSize + colorFormatByteSize; -// mbInputParams.attributes[NORMAL_ATTRIBUTE].binding = 0; -// -// SBlendParams blendParams; -// SPrimitiveAssemblyParams primitiveAssemblyParams; -// primitiveAssemblyParams.primitiveType = E_PRIMITIVE_TOPOLOGY::EPT_TRIANGLE_LIST; -// -// SRasterizationParams rastarizationParmas; -// -// auto mbPipeline = core::make_smart_refctd_ptr(std::move(mbPipelineLayout), nullptr, nullptr, mbInputParams, blendParams, primitiveAssemblyParams, rastarizationParmas); -// { -// mbPipeline->setShaderAtStage(asset::IShader::ESS_VERTEX, mbVertexShader.get()); -// mbPipeline->setShaderAtStage(asset::IShader::ESS_FRAGMENT, mbFragmentShader.get()); -// } -// -// asset::SAssetBundle newPipelineBundle(nullptr, {core::smart_refctd_ptr(mbPipeline)}); -// defaultOverride.insertAssetIntoCache(newPipelineBundle, pipelineCacheHash, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); -// } -// else -// return; -// }; -// -// /* -// Pipeline permutations are cached -// */ -// -// precomputeAndCachePipeline(true); -// precomputeAndCachePipeline(false); -//} +struct SContext +{ + IAssetLoader::SAssetLoadContext inner; + uint32_t topHierarchyLevel; + IAssetLoader::IAssetLoaderOverride* loaderOverride; + + size_t fileOffset = {}; + + // skips to the first non-space character available + void goNextWord() + { + uint8_t c; + while (fileOffset != inner.mainFile->getSize()) // TODO: check it + { + system::IFile::success_t success; + inner.mainFile->read(success, &c, fileOffset, sizeof(c)); + fileOffset += success.getBytesProcessed(); + + // found it, so leave + if (!core::isspace(c)) + { + fileOffset -= success.getBytesProcessed(); + break; + } + } + } + + // returns the next word + const std::string& getNextToken(std::string& token) + { + goNextWord(); + char c; + token = ""; + + while (fileOffset != inner.mainFile->getSize()) + { + system::IFile::success_t success; + inner.mainFile->read(success, &c, fileOffset, sizeof(c)); + fileOffset += success.getBytesProcessed(); + + // found it, so leave + if (core::isspace(c)) + break; + token += c; + } + return token; + } + + // skip to next printable character after the first line break + void goNextLine() + { + uint8_t c; + // look for newline characters + while (fileOffset != inner.mainFile->getSize()) // TODO: check it + { + system::IFile::success_t success; + inner.mainFile->read(success, &c, fileOffset, sizeof(c)); + fileOffset += success.getBytesProcessed(); + + // found it, so leave + if (c == '\n' || c == '\r') + break; + } + } + + //! Read 3d vector of floats + void getNextVector(core::vectorSIMDf& vec, bool binary) + { + if (binary) + { + { + system::IFile::success_t success; + inner.mainFile->read(success, &vec.X, fileOffset, 4); + fileOffset += success.getBytesProcessed(); + } + + { + system::IFile::success_t success; + inner.mainFile->read(success, &vec.Y, fileOffset, 4); + fileOffset += success.getBytesProcessed(); + } + + { + system::IFile::success_t success; + inner.mainFile->read(success, &vec.Z, fileOffset, 4); + fileOffset += success.getBytesProcessed(); + } + } + else + { + goNextWord(); + std::string tmp; + + getNextToken(tmp); + sscanf(tmp.c_str(), "%f", &vec.X); + getNextToken(tmp); + sscanf(tmp.c_str(), "%f", &vec.Y); + getNextToken(tmp); + sscanf(tmp.c_str(), "%f", &vec.Z); + } + vec.X = -vec.X; + } +}; SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override, uint32_t _hierarchyLevel) { @@ -139,7 +151,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa bool binary = false; std::string token; - if (getNextToken(&context, token) != "solid") + if (context.getNextToken(token) != "solid") binary = hasColor = true; core::vector positions, normals; @@ -165,7 +177,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa colors.reserve(vertexCount); } else - goNextLine(&context); // skip header + context.goNextLine(); // skip header uint16_t attrib = 0u; token.reserve(32); @@ -173,13 +185,13 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa { if (!binary) { - if (getNextToken(&context, token) != "facet") + if (context.getNextToken(token) != "facet") { if (token == "endsolid") break; return {}; } - if (getNextToken(&context, token) != "normal") + if (context.getNextToken(token) != "normal") { return {}; } @@ -187,7 +199,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa { core::vectorSIMDf n; - getNextVector(&context, n, binary); + context.getNextVector(n, binary); if(_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES) performActionBasedOnOrientationSystem(n.x, [](float& varToFlip) {varToFlip = -varToFlip;}); normals.push_back(core::normalize(n)); @@ -195,7 +207,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (!binary) { - if (getNextToken(&context, token) != "outer" || getNextToken(&context, token) != "loop") + if (context.getNextToken(token) != "outer" || context.getNextToken(token) != "loop") return {}; } @@ -205,10 +217,10 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa { if (!binary) { - if (getNextToken(&context, token) != "vertex") + if (context.getNextToken(token) != "vertex") return {}; } - getNextVector(&context, p[i], binary); + context.getNextVector(p[i], binary); if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES) performActionBasedOnOrientationSystem(p[i].x, [](float& varToFlip){varToFlip = -varToFlip; }); } @@ -218,7 +230,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (!binary) { - if (getNextToken(&context, token) != "endloop" || getNextToken(&context, token) != "endfacet") + if (context.getNextToken(token) != "endloop" || context.getNextToken(token) != "endfacet") return {}; } else @@ -257,6 +269,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa const size_t vtxSize = hasColor ? (3 * sizeof(float) + 4 + 4) : (3 * sizeof(float) + 4); auto vertexBuf = asset::ICPUBuffer::create({ vtxSize * positions.size() }); +#if 0 quant_normal_t normal; for (size_t i = 0u; i < positions.size(); ++i) { @@ -290,8 +303,11 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa meshbuffer->setVertexBufferBinding({ 0ul, vertexBuf }, 0); mesh->getMeshBufferVector().emplace_back(std::move(meshbuffer)); - - return SAssetBundle(std::move(meta), { std::move(mesh) }); +#endif + + auto meta = make_smart_refctd_ptr(); + + return SAssetBundle(std::move(meta), { std::move(geometry) }); } bool CSTLMeshFileLoader::isALoadableFileFormat(system::IFile* _file, const system::logger_opt_ptr logger) const @@ -327,100 +343,4 @@ bool CSTLMeshFileLoader::isALoadableFileFormat(system::IFile* _file, const syste } } -//! Read 3d vector of floats -void CSTLMeshFileLoader::getNextVector(SContext* context, core::vectorSIMDf& vec, bool binary) const -{ - if (binary) - { - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &vec.X, context->fileOffset, 4); - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &vec.Y, context->fileOffset, 4); - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &vec.Z, context->fileOffset, 4); - context->fileOffset += success.getBytesProcessed(); - } - } - else - { - goNextWord(context); - std::string tmp; - - getNextToken(context, tmp); - sscanf(tmp.c_str(), "%f", &vec.X); - getNextToken(context, tmp); - sscanf(tmp.c_str(), "%f", &vec.Y); - getNextToken(context, tmp); - sscanf(tmp.c_str(), "%f", &vec.Z); - } - vec.X = -vec.X; -} - -//! Read next word -const std::string& CSTLMeshFileLoader::getNextToken(SContext* context, std::string& token) const -{ - goNextWord(context); - char c; - token = ""; - - while (context->fileOffset != context->inner.mainFile->getSize()) - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &c, context->fileOffset, sizeof(c)); - context->fileOffset += success.getBytesProcessed(); - - // found it, so leave - if (core::isspace(c)) - break; - token += c; - } - return token; -} - -//! skip to next word -void CSTLMeshFileLoader::goNextWord(SContext* context) const -{ - uint8_t c; - while (context->fileOffset != context->inner.mainFile->getSize()) // TODO: check it - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &c, context->fileOffset, sizeof(c)); - context->fileOffset += success.getBytesProcessed(); - - // found it, so leave - if (!core::isspace(c)) - { - context->fileOffset -= success.getBytesProcessed(); - break; - } - } -} - -//! Read until line break is reached and stop at the next non-space character -void CSTLMeshFileLoader::goNextLine(SContext* context) const -{ - uint8_t c; - // look for newline characters - while (context->fileOffset != context->inner.mainFile->getSize()) // TODO: check it - { - system::IFile::success_t success; - context->inner.mainFile->read(success, &c, context->fileOffset, sizeof(c)); - context->fileOffset += success.getBytesProcessed(); - - // found it, so leave - if (c == '\n' || c == '\r') - break; - } -} - - #endif // _NBL_COMPILE_WITH_STL_LOADER_ diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.h b/src/nbl/asset/interchange/CSTLMeshFileLoader.h index 41805365f5..7c831f0e3d 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.h +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.h @@ -33,29 +33,8 @@ class CSTLMeshFileLoader final : public IGeometryLoader } private: - struct SContext - { - IAssetLoader::SAssetLoadContext inner; - uint32_t topHierarchyLevel; - IAssetLoader::IAssetLoaderOverride* loaderOverride; - - size_t fileOffset = {}; - }; - - virtual void initialize() override; - const std::string_view getPipelineCacheKey(bool withColorAttribute) { return withColorAttribute ? "nbl/builtin/pipeline/loader/STL/color_attribute" : "nbl/builtin/pipeline/loader/STL/no_color_attribute"; } - // skips to the first non-space character available - void goNextWord(SContext* context) const; - // returns the next word - - const std::string& getNextToken(SContext* context, std::string& token) const; - // skip to next printable character after the first line break - void goNextLine(SContext* context) const; - //! Read 3d vector of floats - void getNextVector(SContext* context, core::vectorSIMDf& vec, bool binary) const; - asset::IAssetManager* m_assetMgr; template From 80ad67f20edfdd8b4d07818f3091760d0b3d36f4 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Sun, 20 Jul 2025 21:02:55 +0200 Subject: [PATCH 05/32] default off PLY and STL writers for now, fix CSTLMeshLoader initialization in IAssetManager --- src/nbl/CMakeLists.txt | 4 ++-- src/nbl/asset/IAssetManager.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/nbl/CMakeLists.txt b/src/nbl/CMakeLists.txt index c444fe6e8c..39c7c753d3 100755 --- a/src/nbl/CMakeLists.txt +++ b/src/nbl/CMakeLists.txt @@ -53,9 +53,9 @@ option(_NBL_COMPILE_WITH_MTL_LOADER_ "Compile with MTL Loader" OFF) #default off option(_NBL_COMPILE_WITH_OBJ_LOADER_ "Compile with OBJ Loader" OFF) #default off until Material Compiler 2 #option(_NBL_COMPILE_WITH_OBJ_WRITER_ "Compile with OBJ Writer" ON) uncomment when writer exists option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" ON) -option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" ON) +option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" OFF) option(_NBL_COMPILE_WITH_PLY_LOADER_ "Compile with PLY Loader" ON) -option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" ON) #default off until reimplemented +option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" OFF) #default off until reimplemented option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON) option(_NBL_COMPILE_WITH_JPG_WRITER_ "Compile with JPG Writer" ON) option(_NBL_COMPILE_WITH_PNG_LOADER_ "Compile with PNG Loader" ON) diff --git a/src/nbl/asset/IAssetManager.cpp b/src/nbl/asset/IAssetManager.cpp index 344429f227..0c1b4493a1 100644 --- a/src/nbl/asset/IAssetManager.cpp +++ b/src/nbl/asset/IAssetManager.cpp @@ -121,7 +121,7 @@ void IAssetManager::initializeMeshTools() void IAssetManager::addLoadersAndWriters() { #ifdef _NBL_COMPILE_WITH_STL_LOADER_ - addAssetLoader(core::make_smart_refctd_ptr(this)); + addAssetLoader(core::make_smart_refctd_ptr()); #endif #ifdef _NBL_COMPILE_WITH_PLY_LOADER_ addAssetLoader(core::make_smart_refctd_ptr()); From 554897d9f1de2341f17b970c23a15a03a45442c8 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Tue, 29 Jul 2025 17:01:47 +0200 Subject: [PATCH 06/32] use types from hlsl namespace --- .../asset/interchange/CSTLMeshFileLoader.cpp | 42 ++++++++++--------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index b2803b72e5..eb679b874c 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -88,25 +88,25 @@ struct SContext } //! Read 3d vector of floats - void getNextVector(core::vectorSIMDf& vec, bool binary) + void getNextVector(hlsl::float32_t3& vec, bool binary) { if (binary) { { system::IFile::success_t success; - inner.mainFile->read(success, &vec.X, fileOffset, 4); + inner.mainFile->read(success, &vec.x, fileOffset, 4); fileOffset += success.getBytesProcessed(); } { system::IFile::success_t success; - inner.mainFile->read(success, &vec.Y, fileOffset, 4); + inner.mainFile->read(success, &vec.y, fileOffset, 4); fileOffset += success.getBytesProcessed(); } { system::IFile::success_t success; - inner.mainFile->read(success, &vec.Z, fileOffset, 4); + inner.mainFile->read(success, &vec.z, fileOffset, 4); fileOffset += success.getBytesProcessed(); } } @@ -116,13 +116,13 @@ struct SContext std::string tmp; getNextToken(tmp); - sscanf(tmp.c_str(), "%f", &vec.X); + sscanf(tmp.c_str(), "%f", &vec.x); getNextToken(tmp); - sscanf(tmp.c_str(), "%f", &vec.Y); + sscanf(tmp.c_str(), "%f", &vec.y); getNextToken(tmp); - sscanf(tmp.c_str(), "%f", &vec.Z); + sscanf(tmp.c_str(), "%f", &vec.z); } - vec.X = -vec.X; + vec.x = -vec.x; } }; @@ -154,7 +154,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (context.getNextToken(token) != "solid") binary = hasColor = true; - core::vector positions, normals; + core::vector positions, normals; core::vector colors; if (binary) { @@ -198,11 +198,11 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa } { - core::vectorSIMDf n; + hlsl::float32_t3 n; context.getNextVector(n, binary); if(_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES) performActionBasedOnOrientationSystem(n.x, [](float& varToFlip) {varToFlip = -varToFlip;}); - normals.push_back(core::normalize(n)); + normals.push_back(hlsl::normalize(n)); } if (!binary) @@ -212,7 +212,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa } { - core::vectorSIMDf p[3]; + hlsl::float32_t3 p[3]; for (uint32_t i = 0u; i < 3u; ++i) { if (!binary) @@ -255,21 +255,23 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa colors.clear(); } - if ((normals.back() == core::vectorSIMDf()).all()) + if (normals.back() == hlsl::float32_t3{}) { - normals.back().set( - core::plane3dSIMDf( - *(positions.rbegin() + 2), - *(positions.rbegin() + 1), - *(positions.rbegin() + 0)).getNormal() - ); + // TODO: calculate normals + assert(false); + //normals.back().set( + // core::plane3dSIMDf( + // *(positions.rbegin() + 2), + // *(positions.rbegin() + 1), + // *(positions.rbegin() + 0)).getNormal() + //); } } // end while (_file->getPos() < filesize) +#if 0 const size_t vtxSize = hasColor ? (3 * sizeof(float) + 4 + 4) : (3 * sizeof(float) + 4); auto vertexBuf = asset::ICPUBuffer::create({ vtxSize * positions.size() }); -#if 0 quant_normal_t normal; for (size_t i = 0u; i < positions.size(); ++i) { From a8728a8a6f0735aba65e41fbc1c6d1217d6a9063 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 30 Jul 2025 15:52:05 +0200 Subject: [PATCH 07/32] position and normal views --- .../asset/interchange/CSTLMeshFileLoader.cpp | 60 ++++++------------- 1 file changed, 18 insertions(+), 42 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index eb679b874c..a80d837a56 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -226,6 +226,8 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa } for (uint32_t i = 0u; i < 3u; ++i) // seems like in STL format vertices are ordered in clockwise manner... positions.push_back(p[2u - i]); + + } if (!binary) @@ -257,58 +259,32 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (normals.back() == hlsl::float32_t3{}) { - // TODO: calculate normals assert(false); - //normals.back().set( - // core::plane3dSIMDf( - // *(positions.rbegin() + 2), - // *(positions.rbegin() + 1), - // *(positions.rbegin() + 0)).getNormal() - //); + static auto computeNormal = [](const hlsl::float32_t3& v1, const hlsl::float32_t3& v2, const hlsl::float32_t3& v3) + { + return hlsl::normalize(hlsl::cross(v2 - v1, v3 - v1)); + }; + + auto& pos1 = *(positions.rbegin() + 2); + auto& pos2 = *(positions.rbegin() + 1); + auto& pos3 = *(positions.rbegin() + 0); + normals.back() = computeNormal(pos1, pos2, pos3); } } // end while (_file->getPos() < filesize) -#if 0 - const size_t vtxSize = hasColor ? (3 * sizeof(float) + 4 + 4) : (3 * sizeof(float) + 4); - auto vertexBuf = asset::ICPUBuffer::create({ vtxSize * positions.size() }); + geometry->setPositionView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, positions.size(), positions.data())); + geometry->setNormalView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, normals.size(), normals.data())); - quant_normal_t normal; - for (size_t i = 0u; i < positions.size(); ++i) - { - if (i % 3 == 0) - normal = quantNormalCache->quantize(normals[i / 3]); - uint8_t* ptr = (reinterpret_cast(vertexBuf->getPointer())) + i * vtxSize; - memcpy(ptr, positions[i].pointer, 3 * 4); + // TODO: Vertex colors - *reinterpret_cast(ptr + 12) = normal; + CPolygonGeometryManipulator::recomputeContentHashes(geometry.get()); + CPolygonGeometryManipulator::recomputeRanges(geometry.get()); - if (hasColor) - memcpy(ptr + 16, colors.data() + i / 3, 4); - } + geometry->setIndexing(IPolygonGeometryBase::TriangleList()); - const IAssetLoader::SAssetLoadContext fakeContext(IAssetLoader::SAssetLoadParams{}, nullptr); - const asset::IAsset::E_TYPE types[]{ asset::IAsset::ET_RENDERPASS_INDEPENDENT_PIPELINE, (asset::IAsset::E_TYPE)0u }; - auto pipelineBundle = _override->findCachedAsset(getPipelineCacheKey(hasColor).data(), types, fakeContext, _hierarchyLevel + ICPURenderpassIndependentPipeline::DESC_SET_HIERARCHYLEVELS_BELOW); - { - bool status = !pipelineBundle.getContents().empty(); - assert(status); - } - - auto mbPipeline = core::smart_refctd_ptr_static_cast(pipelineBundle.getContents().begin()[0]); - - auto meta = core::make_smart_refctd_ptr(1u, std::move(m_basicViewParamsSemantics)); - meta->placeMeta(0u, mbPipeline.get()); - - meshbuffer->setPipeline(std::move(mbPipeline)); - meshbuffer->setIndexCount(positions.size()); - meshbuffer->setIndexType(asset::EIT_UNKNOWN); - - meshbuffer->setVertexBufferBinding({ 0ul, vertexBuf }, 0); - mesh->getMeshBufferVector().emplace_back(std::move(meshbuffer)); -#endif + CPolygonGeometryManipulator::recomputeAABB(geometry.get()); auto meta = make_smart_refctd_ptr(); - return SAssetBundle(std::move(meta), { std::move(geometry) }); } From 75576af72ff618488cddb81e855bb4a953df6bff Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 30 Jul 2025 15:54:49 +0200 Subject: [PATCH 08/32] put missing TODO --- src/nbl/asset/interchange/CSTLMeshFileLoader.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index a80d837a56..00ad606d3a 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -259,6 +259,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (normals.back() == hlsl::float32_t3{}) { + // TODO: validate this assert(false); static auto computeNormal = [](const hlsl::float32_t3& v1, const hlsl::float32_t3& v2, const hlsl::float32_t3& v3) { From d4e674519f0001ff4ec2d187c5459ed2095de039 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 30 Jul 2025 22:04:09 +0200 Subject: [PATCH 09/32] make STL loader work --- ...amework,Version=v4.0.AssemblyAttributes.cs | 4 ++ .../LzmaAlone.csproj.AssemblyReference.cache | Bin 0 -> 5519 bytes ...amework,Version=v4.0.AssemblyAttributes.cs | 4 ++ .../LzmaAlone.csproj.AssemblyReference.cache | Bin 0 -> 5519 bytes .../asset/interchange/CSTLMeshFileLoader.cpp | 61 +++++++++++------- 5 files changed, 46 insertions(+), 23 deletions(-) create mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs create mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache create mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs create mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs new file mode 100644 index 0000000000..5d01041163 --- /dev/null +++ b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..e4d691834147411578407ee9e8a8dbf9517ea3af GIT binary patch literal 5519 zcmeHLOHb5L6z)|pBao<|1QHh{Zd{NS=E2Ai;$wIQL1YM+*ksZvcc7sUY&#f?37WXj zL{~1|_!Dqt;?liFO-u}dgoRsU`~${&+TNLVrZdwzU9g~pdG+?3@7!~~ujlj(>S7oM zjb$_Z>g>YAoz)yaFNwNlXhoAtktK)@qT1bhhk>Sxq5)WM)wLPJZ3K|B@xOPx546GF79e(;|Hb0-6 zz0K!#3==DS-1eByS6g%zl(+NmhZ|r2JU@g8h#R;pHI$C08Fb&}#F7daHTSRc178RyB_#X{k;KrqH~gVO6=RFOBtn^R4Q-?h^49-0i)5=T9Qh z6NN1lK`z53C9_45I!VyBZSIA4=0s2PwguP|p(W{IS2=zFdwX6%OA&5Y9qbBWPfYJKNYC3MoQ1l{n z&WUxQq+neVTZ^;TF}74vO-aFQRuDHNbv;zb)hgNV*ql^NtZ(U(fpb{jmP8y5s@E(e z&nub%Wu;2f{zF#2{N4{NE4BSrNLfk5Phf+Y=L z^Ja`JD)(Yc_piR!cMobOjDRXu?L3%_xe?5y_8(tfvYMktcU^1J0Il^*8zDsu&{7#A z7y>p&6m9d~Xx_QQkSn5UjjVp~IJHLIPK;K|n0p|TSXs2h>m8}gE?&-Y9*?&5`p zichd97|rXC$FQoxou4Dme7S>N4jT*>HSU9v$AjU@QP0~q{ni7QhOMDLeUxycg_}Nr zA|QXtfSVJD4i|7qR19hd)i_QJY9w<|y>J8>QX;)GQe!zRmUPM73B~DVEpf)55cQrb z(r0uPrXBOgigwDZyg{{fshX}xYpTGi@>VB&QH!GM^BR1%7OBNe>jeE`one@Nd~9v4 literal 0 HcmV?d00001 diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs new file mode 100644 index 0000000000..5d01041163 --- /dev/null +++ b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs @@ -0,0 +1,4 @@ +// +using System; +using System.Reflection; +[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache new file mode 100644 index 0000000000000000000000000000000000000000..e4d691834147411578407ee9e8a8dbf9517ea3af GIT binary patch literal 5519 zcmeHLOHb5L6z)|pBao<|1QHh{Zd{NS=E2Ai;$wIQL1YM+*ksZvcc7sUY&#f?37WXj zL{~1|_!Dqt;?liFO-u}dgoRsU`~${&+TNLVrZdwzU9g~pdG+?3@7!~~ujlj(>S7oM zjb$_Z>g>YAoz)yaFNwNlXhoAtktK)@qT1bhhk>Sxq5)WM)wLPJZ3K|B@xOPx546GF79e(;|Hb0-6 zz0K!#3==DS-1eByS6g%zl(+NmhZ|r2JU@g8h#R;pHI$C08Fb&}#F7daHTSRc178RyB_#X{k;KrqH~gVO6=RFOBtn^R4Q-?h^49-0i)5=T9Qh z6NN1lK`z53C9_45I!VyBZSIA4=0s2PwguP|p(W{IS2=zFdwX6%OA&5Y9qbBWPfYJKNYC3MoQ1l{n z&WUxQq+neVTZ^;TF}74vO-aFQRuDHNbv;zb)hgNV*ql^NtZ(U(fpb{jmP8y5s@E(e z&nub%Wu;2f{zF#2{N4{NE4BSrNLfk5Phf+Y=L z^Ja`JD)(Yc_piR!cMobOjDRXu?L3%_xe?5y_8(tfvYMktcU^1J0Il^*8zDsu&{7#A z7y>p&6m9d~Xx_QQkSn5UjjVp~IJHLIPK;K|n0p|TSXs2h>m8}gE?&-Y9*?&5`p zichd97|rXC$FQoxou4Dme7S>N4jT*>HSU9v$AjU@QP0~q{ni7QhOMDLeUxycg_}Nr zA|QXtfSVJD4i|7qR19hd)i_QJY9w<|y>J8>QX;)GQe!zRmUPM73B~DVEpf)55cQrb z(r0uPrXBOgigwDZyg{{fshX}xYpTGi@>VB&QH!GM^BR1%7OBNe>jeE`one@Nd~9v4 literal 0 HcmV?d00001 diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index 00ad606d3a..d3b6570f05 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -22,6 +22,14 @@ constexpr auto COLOR_ATTRIBUTE = 1; constexpr auto UV_ATTRIBUTE = 2; constexpr auto NORMAL_ATTRIBUTE = 3; +struct Vec3Hasher +{ + size_t operator()(const hlsl::float32_t3& v) const + { + return std::hash()(v.x) ^ (std::hash()(v.y) << 1) ^ (std::hash()(v.z) << 2); + } +}; + struct SContext { IAssetLoader::SAssetLoadContext inner; @@ -124,6 +132,10 @@ struct SContext } vec.x = -vec.x; } + + core::vector vertices; + core::vector normals; + core::vector indices; }; SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoader::SAssetLoadParams& _params, IAssetLoader::IAssetLoaderOverride* _override, uint32_t _hierarchyLevel) @@ -154,7 +166,6 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (context.getNextToken(token) != "solid") binary = hasColor = true; - core::vector positions, normals; core::vector colors; if (binary) { @@ -172,8 +183,6 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa return {}; context.fileOffset += sizeof(vertexCount); - positions.reserve(3 * vertexCount); - normals.reserve(vertexCount); colors.reserve(vertexCount); } else @@ -181,6 +190,9 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa uint16_t attrib = 0u; token.reserve(32); + + core::unordered_map vertexMap; + while (context.fileOffset < filesize) // TODO: check it { if (!binary) @@ -202,7 +214,8 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa context.getNextVector(n, binary); if(_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES) performActionBasedOnOrientationSystem(n.x, [](float& varToFlip) {varToFlip = -varToFlip;}); - normals.push_back(hlsl::normalize(n)); + + context.normals.emplace_back(std::move(n)); } if (!binary) @@ -212,22 +225,31 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa } { - hlsl::float32_t3 p[3]; for (uint32_t i = 0u; i < 3u; ++i) { + hlsl::float32_t3 p; if (!binary) { if (context.getNextToken(token) != "vertex") return {}; } - context.getNextVector(p[i], binary); + context.getNextVector(p, binary); if (_params.loaderFlags & E_LOADER_PARAMETER_FLAGS::ELPF_RIGHT_HANDED_MESHES) - performActionBasedOnOrientationSystem(p[i].x, [](float& varToFlip){varToFlip = -varToFlip; }); - } - for (uint32_t i = 0u; i < 3u; ++i) // seems like in STL format vertices are ordered in clockwise manner... - positions.push_back(p[2u - i]); - + performActionBasedOnOrientationSystem(p.x, [](float& varToFlip){varToFlip = -varToFlip; }); + auto it = vertexMap.find(p); + if (it == vertexMap.end()) + { + uint32_t newIdx = static_cast(context.vertices.size()); + vertexMap[p] = newIdx; + context.indices.push_back(newIdx); + context.vertices.push_back(p); + } + else + { + context.indices.push_back(it->second); + } + } } if (!binary) @@ -257,24 +279,16 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa colors.clear(); } - if (normals.back() == hlsl::float32_t3{}) + if (context.normals.back() == hlsl::float32_t3{}) { - // TODO: validate this + // TODO: calculate normals assert(false); - static auto computeNormal = [](const hlsl::float32_t3& v1, const hlsl::float32_t3& v2, const hlsl::float32_t3& v3) - { - return hlsl::normalize(hlsl::cross(v2 - v1, v3 - v1)); - }; - auto& pos1 = *(positions.rbegin() + 2); - auto& pos2 = *(positions.rbegin() + 1); - auto& pos3 = *(positions.rbegin() + 0); - normals.back() = computeNormal(pos1, pos2, pos3); } } // end while (_file->getPos() < filesize) - geometry->setPositionView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, positions.size(), positions.data())); - geometry->setNormalView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, normals.size(), normals.data())); + geometry->setPositionView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, context.vertices.size(), context.vertices.data())); + geometry->setNormalView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, context.normals.size(), context.normals.data())); // TODO: Vertex colors @@ -282,6 +296,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa CPolygonGeometryManipulator::recomputeRanges(geometry.get()); geometry->setIndexing(IPolygonGeometryBase::TriangleList()); + geometry->setIndexView(createView(E_FORMAT::EF_R32_UINT, context.indices.size(), context.indices.data())); CPolygonGeometryManipulator::recomputeAABB(geometry.get()); From c227b7052b3fb3f208fd8fc02725aa6c43a08a86 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 15:48:13 +0200 Subject: [PATCH 10/32] get colors working? --- src/nbl/asset/interchange/CSTLMeshFileLoader.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index d3b6570f05..052ae53531 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -135,6 +135,7 @@ struct SContext core::vector vertices; core::vector normals; + core::vector colors; core::vector indices; }; @@ -243,7 +244,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa uint32_t newIdx = static_cast(context.vertices.size()); vertexMap[p] = newIdx; context.indices.push_back(newIdx); - context.vertices.push_back(p); + context.vertices.emplace_back(std::move(p)); } else { @@ -271,7 +272,7 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa const void* srcColor[1]{ &attrib }; uint32_t color{}; convertColor(srcColor, &color, 0u, 0u); - colors.push_back(color); + context.colors.push_back(color); } else { @@ -290,7 +291,12 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa geometry->setPositionView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, context.vertices.size(), context.vertices.data())); geometry->setNormalView(createView(E_FORMAT::EF_R32G32B32_SFLOAT, context.normals.size(), context.normals.data())); - // TODO: Vertex colors + if (!context.colors.empty()) + { + // I'm still not sure if this works, probably not + auto colorsView = createView(EF_A1R5G5B5_UNORM_PACK16, context.colors.size(), context.colors.data()); + geometry->getAuxAttributeViews()->push_back(colorsView); + } CPolygonGeometryManipulator::recomputeContentHashes(geometry.get()); CPolygonGeometryManipulator::recomputeRanges(geometry.get()); From 5eef9a99b0fc937f458ecebd399b0b167562855e Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 16:46:28 +0200 Subject: [PATCH 11/32] calculate normal if not present --- src/nbl/asset/interchange/CSTLMeshFileLoader.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp index 052ae53531..444c26bad7 100644 --- a/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CSTLMeshFileLoader.cpp @@ -282,9 +282,13 @@ SAssetBundle CSTLMeshFileLoader::loadAsset(system::IFile* _file, const IAssetLoa if (context.normals.back() == hlsl::float32_t3{}) { - // TODO: calculate normals - assert(false); + auto& p1 = *(context.vertices.rbegin() + 2); + auto& p2 = *(context.vertices.rbegin() + 1); + auto& p3 = *(context.vertices.rbegin() + 0); + auto u = p2 - p1; + auto v = p3 - p1; + context.normals.emplace_back(hlsl::normalize(hlsl::cross(u, v))); } } // end while (_file->getPos() < filesize) From 45ed81da4fa1647ce09bc084522ef429b179df47 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 16:53:54 +0200 Subject: [PATCH 12/32] remove lzma files pushed by accident --- ...TFramework,Version=v4.0.AssemblyAttributes.cs | 4 ---- .../LzmaAlone.csproj.AssemblyReference.cache | Bin 5519 -> 0 bytes ...TFramework,Version=v4.0.AssemblyAttributes.cs | 4 ---- .../LzmaAlone.csproj.AssemblyReference.cache | Bin 5519 -> 0 bytes 4 files changed, 8 deletions(-) delete mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs delete mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache delete mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs delete mode 100644 3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs deleted file mode 100644 index 5d01041163..0000000000 --- a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/.NETFramework,Version=v4.0.AssemblyAttributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -// -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Debug/LzmaAlone.csproj.AssemblyReference.cache deleted file mode 100644 index e4d691834147411578407ee9e8a8dbf9517ea3af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5519 zcmeHLOHb5L6z)|pBao<|1QHh{Zd{NS=E2Ai;$wIQL1YM+*ksZvcc7sUY&#f?37WXj zL{~1|_!Dqt;?liFO-u}dgoRsU`~${&+TNLVrZdwzU9g~pdG+?3@7!~~ujlj(>S7oM zjb$_Z>g>YAoz)yaFNwNlXhoAtktK)@qT1bhhk>Sxq5)WM)wLPJZ3K|B@xOPx546GF79e(;|Hb0-6 zz0K!#3==DS-1eByS6g%zl(+NmhZ|r2JU@g8h#R;pHI$C08Fb&}#F7daHTSRc178RyB_#X{k;KrqH~gVO6=RFOBtn^R4Q-?h^49-0i)5=T9Qh z6NN1lK`z53C9_45I!VyBZSIA4=0s2PwguP|p(W{IS2=zFdwX6%OA&5Y9qbBWPfYJKNYC3MoQ1l{n z&WUxQq+neVTZ^;TF}74vO-aFQRuDHNbv;zb)hgNV*ql^NtZ(U(fpb{jmP8y5s@E(e z&nub%Wu;2f{zF#2{N4{NE4BSrNLfk5Phf+Y=L z^Ja`JD)(Yc_piR!cMobOjDRXu?L3%_xe?5y_8(tfvYMktcU^1J0Il^*8zDsu&{7#A z7y>p&6m9d~Xx_QQkSn5UjjVp~IJHLIPK;K|n0p|TSXs2h>m8}gE?&-Y9*?&5`p zichd97|rXC$FQoxou4Dme7S>N4jT*>HSU9v$AjU@QP0~q{ni7QhOMDLeUxycg_}Nr zA|QXtfSVJD4i|7qR19hd)i_QJY9w<|y>J8>QX;)GQe!zRmUPM73B~DVEpf)55cQrb z(r0uPrXBOgigwDZyg{{fshX}xYpTGi@>VB&QH!GM^BR1%7OBNe>jeE`one@Nd~9v4 diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs deleted file mode 100644 index 5d01041163..0000000000 --- a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/.NETFramework,Version=v4.0.AssemblyAttributes.cs +++ /dev/null @@ -1,4 +0,0 @@ -// -using System; -using System.Reflection; -[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.0", FrameworkDisplayName = ".NET Framework 4")] diff --git a/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache b/3rdparty/lzma/CS/7zip/Compress/LzmaAlone/obj/Release/LzmaAlone.csproj.AssemblyReference.cache deleted file mode 100644 index e4d691834147411578407ee9e8a8dbf9517ea3af..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5519 zcmeHLOHb5L6z)|pBao<|1QHh{Zd{NS=E2Ai;$wIQL1YM+*ksZvcc7sUY&#f?37WXj zL{~1|_!Dqt;?liFO-u}dgoRsU`~${&+TNLVrZdwzU9g~pdG+?3@7!~~ujlj(>S7oM zjb$_Z>g>YAoz)yaFNwNlXhoAtktK)@qT1bhhk>Sxq5)WM)wLPJZ3K|B@xOPx546GF79e(;|Hb0-6 zz0K!#3==DS-1eByS6g%zl(+NmhZ|r2JU@g8h#R;pHI$C08Fb&}#F7daHTSRc178RyB_#X{k;KrqH~gVO6=RFOBtn^R4Q-?h^49-0i)5=T9Qh z6NN1lK`z53C9_45I!VyBZSIA4=0s2PwguP|p(W{IS2=zFdwX6%OA&5Y9qbBWPfYJKNYC3MoQ1l{n z&WUxQq+neVTZ^;TF}74vO-aFQRuDHNbv;zb)hgNV*ql^NtZ(U(fpb{jmP8y5s@E(e z&nub%Wu;2f{zF#2{N4{NE4BSrNLfk5Phf+Y=L z^Ja`JD)(Yc_piR!cMobOjDRXu?L3%_xe?5y_8(tfvYMktcU^1J0Il^*8zDsu&{7#A z7y>p&6m9d~Xx_QQkSn5UjjVp~IJHLIPK;K|n0p|TSXs2h>m8}gE?&-Y9*?&5`p zichd97|rXC$FQoxou4Dme7S>N4jT*>HSU9v$AjU@QP0~q{ni7QhOMDLeUxycg_}Nr zA|QXtfSVJD4i|7qR19hd)i_QJY9w<|y>J8>QX;)GQe!zRmUPM73B~DVEpf)55cQrb z(r0uPrXBOgigwDZyg{{fshX}xYpTGi@>VB&QH!GM^BR1%7OBNe>jeE`one@Nd~9v4 From b3bf45d07377e393882b0174b20da69a0d63e323 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 18:42:38 +0200 Subject: [PATCH 13/32] enable STL loader --- src/nbl/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nbl/CMakeLists.txt b/src/nbl/CMakeLists.txt index d46b8c9894..f4e48a1eab 100755 --- a/src/nbl/CMakeLists.txt +++ b/src/nbl/CMakeLists.txt @@ -53,7 +53,7 @@ option(_NBL_COMPILE_WITH_MTL_LOADER_ "Compile with MTL Loader" OFF) #default off option(_NBL_COMPILE_WITH_OBJ_LOADER_ "Compile with OBJ Loader" OFF) #default off until Material Compiler 2 #option(_NBL_COMPILE_WITH_OBJ_WRITER_ "Compile with OBJ Writer" ON) uncomment when writer exists option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" ON) -option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" OFF) +option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" ON) option(_NBL_COMPILE_WITH_PLY_LOADER_ "Compile with PLY Loader" ON) option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" OFF) #default off until reimplemented option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON) From c3140ea668ef354aebe199ebd800b2912a894b65 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 19:45:08 +0200 Subject: [PATCH 14/32] disable some old code to make STL writer compile --- .../nbl/asset/interchange/IGeometryWriter.h | 2 ++ src/nbl/asset/interchange/CSTLMeshWriter.cpp | 24 ++++++++++++------- src/nbl/asset/interchange/CSTLMeshWriter.h | 2 +- 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/nbl/asset/interchange/IGeometryWriter.h b/include/nbl/asset/interchange/IGeometryWriter.h index d7e7ab964a..3448a031f6 100644 --- a/include/nbl/asset/interchange/IGeometryWriter.h +++ b/include/nbl/asset/interchange/IGeometryWriter.h @@ -26,6 +26,8 @@ class IGeometryWriter : public IAssetWriter private: }; +inline IGeometryWriter::~IGeometryWriter() { } + } #endif diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index 45c7c1f939..40cd2cf0ac 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -24,9 +24,9 @@ CSTLMeshWriter::CSTLMeshWriter() #endif } - CSTLMeshWriter::~CSTLMeshWriter() { + } //! writes a mesh @@ -37,11 +37,11 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ SAssetWriteContext inCtx{_params, _file}; - const asset::ICPUMesh* mesh = + const asset::ICPUPolygonGeometry* mesh = # ifndef _NBL_DEBUG - static_cast(_params.rootAsset); + static_cast(_params.rootAsset); # else - dynamic_cast(_params.rootAsset); + dynamic_cast(_params.rootAsset); # endif assert(mesh); @@ -64,8 +64,9 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ namespace { template -inline void writeFacesBinary(const asset::ICPUMeshBuffer* buffer, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) +inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) { +#if 0 auto& inputParams = buffer->getPipeline()->getCachedCreationParams().vertexInput; bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); @@ -165,10 +166,11 @@ inline void writeFacesBinary(const asset::ICPUMeshBuffer* buffer, const bool& no *fileOffset += success.getBytesProcessed(); } } +#endif } } -bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUMesh* mesh, SContext* context) +bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SContext* context) { // write STL MESH header const char headerTxt[] = "Irrlicht-baw Engine"; @@ -209,7 +211,8 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUMesh* mesh, SContext* cont context->fileOffset += success.getBytesProcessed(); } } - + +#if 0 uint32_t facenum = 0; for (auto& mb : mesh->getMeshBuffers()) facenum += mb->getIndexCount()/3; @@ -220,7 +223,6 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUMesh* mesh, SContext* cont context->fileOffset += success.getBytesProcessed(); } // write mesh buffers - for (auto& buffer : mesh->getMeshBuffers()) if (buffer) { @@ -235,10 +237,11 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUMesh* mesh, SContext* cont else writeFacesBinary(buffer, true, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); //template param doesn't matter if there's no indices } +#endif return true; } -bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUMesh* mesh, SContext* context) +bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SContext* context) { // write STL MESH header const char headerTxt[] = "Irrlicht-baw Engine "; @@ -275,6 +278,7 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUMesh* mesh, SContext* conte context->fileOffset += success.getBytesProcessed(); } +#if 0 // write mesh buffers for (auto& buffer : mesh->getMeshBuffers()) if (buffer) @@ -331,6 +335,8 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUMesh* mesh, SContext* conte } } +#endif + { system::IFile::success_t success;; context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.h b/src/nbl/asset/interchange/CSTLMeshWriter.h index a25a84534c..771d9cb026 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.h +++ b/src/nbl/asset/interchange/CSTLMeshWriter.h @@ -17,7 +17,7 @@ namespace nbl::asset class CSTLMeshWriter : public IGeometryWriter { protected: - virtual ~CSTLMeshWriter(); + ~CSTLMeshWriter() override; public: CSTLMeshWriter(); From f670252e6aac13a7fc14fa021b987aa986dfe1d8 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 20:30:33 +0200 Subject: [PATCH 15/32] STL binary data writer --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 49 ++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index 40cd2cf0ac..c2a89b247e 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -66,6 +66,55 @@ namespace template inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) { + using normal_t = hlsl::float32_t3; + using vertex_t = hlsl::float32_t3; + using index_t = uint32_t; + + auto& posView = geom->getPositionView(); + auto& normalView = geom->getNormalView(); + auto& idxView = geom->getIndexView(); + + const auto vertexCount = posView.getElementCount(); + const auto idxCount = idxView.getElementCount(); + + // TODO: check if I can actually assume following types, if not, handle that + const uint32_t* idxBufPtr = reinterpret_cast(idxView.getPointer()); + const hlsl::float32_t3* vtxBufPtr = reinterpret_cast(posView.getPointer()); + + static auto calculateNormal = [](const hlsl::float32_t3& v1, const hlsl::float32_t3 v2, const hlsl::float32_t3 v3) + { + return hlsl::normalize(hlsl::cross(v2 - v1, v3 - v1)); + }; + + for (size_t i = 0; i < idxCount; i+=3) + { + index_t idx[3] = {}; + for (size_t j = 0; j < 3; j++) + idx[i] = *(idxBufPtr + j + i); + + vertex_t pos[3] = {}; + for (size_t j = 0; j < 3; j++) + pos[j] = *(vtxBufPtr + idx[j]); + + // TODO: vertex color + // TODO: I could get the normal from normalView, but I need to think how can I do that well + + normal_t n = calculateNormal(pos[1], pos[2], pos[3]); + + // success variable can be reused, no need to scope it + system::IFile::success_t success{}; + + // write normal + file->write(success, &normal, *fileOffset, 12); + *fileOffset += success.getBytesProcessed(); + + // write positions + for (size_t j = 0; j < 3; j++) + { + file->write(success, &pos[i], *fileOffset, 12); + *fileOffset += success.getBytesProcessed(); + } + } #if 0 auto& inputParams = buffer->getPipeline()->getCachedCreationParams().vertexInput; bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); From d3a01ae56b9131b46a1befa4dcd3e3294227d285 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 21:55:56 +0200 Subject: [PATCH 16/32] delete implemented stuff from disabled code, modify todos --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 71 ++------------------ 1 file changed, 5 insertions(+), 66 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index c2a89b247e..3833e0f66f 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -70,6 +70,9 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& using vertex_t = hlsl::float32_t3; using index_t = uint32_t; + bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); + const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); + auto& posView = geom->getPositionView(); auto& normalView = geom->getNormalView(); auto& idxView = geom->getIndexView(); @@ -97,7 +100,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& pos[j] = *(vtxBufPtr + idx[j]); // TODO: vertex color - // TODO: I could get the normal from normalView, but I need to think how can I do that well + // TODO: I think I could get the normal from normalView, but I need to think how can I do that well normal_t n = calculateNormal(pos[1], pos[2], pos[3]); @@ -116,26 +119,6 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& } } #if 0 - auto& inputParams = buffer->getPipeline()->getCachedCreationParams().vertexInput; - bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); - const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); - - const uint32_t indexCount = buffer->getIndexCount(); - for (uint32_t j = 0u; j < indexCount; j += 3u) - { - I idx[3]; - for (uint32_t i = 0u; i < 3u; ++i) - { - if (noIndices) - idx[i] = j + i; - else - idx[i] = ((I*)buffer->getIndices())[j + i]; - } - - core::vectorSIMDf v[3]; - for (uint32_t i = 0u; i < 3u; ++i) - v[i] = buffer->getPosition(idx[i]); - uint16_t color = 0u; if (hasColor) { @@ -164,57 +147,12 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& } } - core::vectorSIMDf normal = core::plane3dSIMDf(v[0], v[1], v[2]).getNormal(); - core::vectorSIMDf vertex1 = v[2]; - core::vectorSIMDf vertex2 = v[1]; - core::vectorSIMDf vertex3 = v[0]; - - auto flipVectors = [&]() - { - vertex1.X = -vertex1.X; - vertex2.X = -vertex2.X; - vertex3.X = -vertex3.X; - normal = core::plane3dSIMDf(vertex1, vertex2, vertex3).getNormal(); - }; - - if (!(context->params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) - flipVectors(); - - { - system::IFile::success_t success;; - file->write(success, &normal, *fileOffset, 12); - - *fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - file->write(success, &vertex1, *fileOffset, 12); - - *fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - file->write(success, &vertex2, *fileOffset, 12); - - *fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - file->write(success, &vertex3, *fileOffset, 12); - - *fileOffset += success.getBytesProcessed(); - } - { system::IFile::success_t success;; file->write(success, &color, *fileOffset, 2); // saving color using non-standard VisCAM/SolidView trick *fileOffset += success.getBytesProcessed(); } - } #endif } } @@ -261,6 +199,7 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SCo } } + // TODO: is this method (writeFacesBinary) even necessary with new ICPUPolygonGeometry? #if 0 uint32_t facenum = 0; for (auto& mb : mesh->getMeshBuffers()) From 11d315cc1fb66345849b4e1c344f94c05990c680 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 22:27:10 +0200 Subject: [PATCH 17/32] detect IndexType --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 39 ++++++++------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index 3833e0f66f..c80c0502bd 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -63,12 +63,11 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ namespace { -template +template inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) { using normal_t = hlsl::float32_t3; using vertex_t = hlsl::float32_t3; - using index_t = uint32_t; bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); @@ -91,7 +90,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& for (size_t i = 0; i < idxCount; i+=3) { - index_t idx[3] = {}; + IndexType idx[3] = {}; for (size_t j = 0; j < 3; j++) idx[i] = *(idxBufPtr + j + i); @@ -200,32 +199,24 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SCo } // TODO: is this method (writeFacesBinary) even necessary with new ICPUPolygonGeometry? -#if 0 - uint32_t facenum = 0; - for (auto& mb : mesh->getMeshBuffers()) - facenum += mb->getIndexCount()/3; - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, &facenum, context->fileOffset, sizeof(facenum)); + size_t idxCount = geom->getIndexCount(); + size_t facesCount = idxCount / 3; - context->fileOffset += success.getBytesProcessed(); - } - // write mesh buffers - for (auto& buffer : mesh->getMeshBuffers()) - if (buffer) + if (idxCount > 0) { - asset::E_INDEX_TYPE type = buffer->getIndexType(); - if (!buffer->getIndexBufferBinding().buffer) - type = asset::EIT_UNKNOWN; + auto& idxView = geom->getIndexView(); + size_t idxSize = idxView.src.size / idxCount; - if (type== asset::EIT_16BIT) - writeFacesBinary(buffer, false, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); - else if (type== asset::EIT_32BIT) - writeFacesBinary(buffer, false, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); + if (idxSize == sizeof(uint16_t)) + writeFacesBinary(geom, false, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); else - writeFacesBinary(buffer, true, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); //template param doesn't matter if there's no indices + writeFacesBinary(geom, false, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); } -#endif + else + { + writeFacesBinary(geom, true, context->writeContext.outputFile, COLOR_ATTRIBUTE, &context->writeContext, &context->fileOffset); + } + return true; } From 52a669dc92559c65fb9cb175509674f28d60294d Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 22:36:00 +0200 Subject: [PATCH 18/32] reuse success variable instead of creating a new one all the time --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 179 +++++-------------- 1 file changed, 49 insertions(+), 130 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index c80c0502bd..bdb2402d3f 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -159,43 +159,31 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SContext* context) { // write STL MESH header - const char headerTxt[] = "Irrlicht-baw Engine"; - constexpr size_t HEADER_SIZE = 80u; + const char headerTxt[] = "Irrlicht-baw Engine"; + constexpr size_t HEADER_SIZE = 80u; - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt)); + system::IFile::success_t success; - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt)); + context->fileOffset += success.getBytesProcessed(); const std::string name = context->writeContext.outputFile->getFileName().filename().replace_extension().string(); // TODO: check it const int32_t sizeleft = HEADER_SIZE - sizeof(headerTxt) - name.size(); if (sizeleft < 0) { - system::IFile::success_t success;; context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, HEADER_SIZE - sizeof(headerTxt)); - context->fileOffset += success.getBytesProcessed(); } else { const char buf[80] = {0}; - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, buf, context->fileOffset, sizeleft); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, buf, context->fileOffset, sizeleft); + context->fileOffset += success.getBytesProcessed(); } // TODO: is this method (writeFacesBinary) even necessary with new ICPUPolygonGeometry? @@ -223,39 +211,24 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SCo bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SContext* context) { // write STL MESH header - const char headerTxt[] = "Irrlicht-baw Engine "; - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "solid ", context->fileOffset, 6); - - context->fileOffset += success.getBytesProcessed(); - } + const char headerTxt[] = "Nabla Engine "; + system::IFile::success_t success; + + context->writeContext.outputFile->write(success, "solid ", context->fileOffset, 6); + context->fileOffset += success.getBytesProcessed(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); + context->fileOffset += success.getBytesProcessed(); const std::string name = context->writeContext.outputFile->getFileName().filename().replace_extension().string(); - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); + context->fileOffset += success.getBytesProcessed(); #if 0 // write mesh buffers @@ -316,26 +289,14 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon #endif - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); + context->fileOffset += success.getBytesProcessed(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); - - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); return true; } @@ -370,90 +331,48 @@ void CSTLMeshWriter::writeFaceText( if (!(context->writeContext.params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) flipVectors(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "facet normal ", context->fileOffset, 13); + system::IFile::success_t success; - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, "facet normal ", context->fileOffset, 13); + context->fileOffset += success.getBytesProcessed(); getVectorAsStringLine(normal, tmp); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, " outer loop\n", context->fileOffset, 13); + context->fileOffset += success.getBytesProcessed(); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, " outer loop\n", context->fileOffset, 13); - - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); getVectorAsStringLine(vertex1, tmp); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); getVectorAsStringLine(vertex2, tmp); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); getVectorAsStringLine(vertex3, tmp); - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, " endloop\n", context->fileOffset, 10); + context->writeContext.outputFile->write(success, " endloop\n", context->fileOffset, 10); + context->fileOffset += success.getBytesProcessed(); - context->fileOffset += success.getBytesProcessed(); - } - - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "endfacet\n", context->fileOffset, 9); - - context->fileOffset += success.getBytesProcessed(); - } + context->writeContext.outputFile->write(success, "endfacet\n", context->fileOffset, 9); + context->fileOffset += success.getBytesProcessed(); } #endif From 252c92cebdff6bc3c42b43d6077ffb5f0975e0c4 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Thu, 31 Jul 2025 23:14:10 +0200 Subject: [PATCH 19/32] rework ascii writer code, add type aliases to save some typing --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 128 ++++++++----------- src/nbl/asset/interchange/CSTLMeshWriter.h | 28 ++-- 2 files changed, 68 insertions(+), 88 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index bdb2402d3f..da00723f29 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -61,14 +61,16 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ return writeMeshASCII(mesh, &context); } +inline static hlsl::float32_t3 calculateNormal(const hlsl::float32_t3& p1, const hlsl::float32_t3& p2, const hlsl::float32_t3& p3) +{ + return hlsl::normalize(hlsl::cross(p2 - p1, p3 - p1)); +} + namespace { template inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) { - using normal_t = hlsl::float32_t3; - using vertex_t = hlsl::float32_t3; - bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); @@ -81,12 +83,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& // TODO: check if I can actually assume following types, if not, handle that const uint32_t* idxBufPtr = reinterpret_cast(idxView.getPointer()); - const hlsl::float32_t3* vtxBufPtr = reinterpret_cast(posView.getPointer()); - - static auto calculateNormal = [](const hlsl::float32_t3& v1, const hlsl::float32_t3 v2, const hlsl::float32_t3 v3) - { - return hlsl::normalize(hlsl::cross(v2 - v1, v3 - v1)); - }; + const pos_t* vtxBufPtr = reinterpret_cast(posView.getPointer()); for (size_t i = 0; i < idxCount; i+=3) { @@ -94,7 +91,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& for (size_t j = 0; j < 3; j++) idx[i] = *(idxBufPtr + j + i); - vertex_t pos[3] = {}; + pos_t pos[3] = {}; for (size_t j = 0; j < 3; j++) pos[j] = *(vtxBufPtr + idx[j]); @@ -210,15 +207,16 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SCo bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SContext* context) { + using pos_t = hlsl::float32_t3; + // write STL MESH header - const char headerTxt[] = "Nabla Engine "; + const char headerTxt[] = "Nabla Engine "; system::IFile::success_t success; context->writeContext.outputFile->write(success, "solid ", context->fileOffset, 6); context->fileOffset += success.getBytesProcessed(); - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); context->fileOffset += success.getBytesProcessed(); @@ -226,68 +224,48 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); context->fileOffset += success.getBytesProcessed(); - context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); context->fileOffset += success.getBytesProcessed(); -#if 0 - // write mesh buffers - for (auto& buffer : mesh->getMeshBuffers()) - if (buffer) + // TODO: what if index count is 0 + auto& idxView = geom->getIndexView(); + + const size_t idxCount = geom->getIndexCount(); + const size_t facesCount = idxCount / 3; + const size_t idxSize = idxView.src.buffer->getSize() / idxCount; + + auto& posView = geom->getPositionView(); + + for (size_t i = 0; i < facesCount; i++) { - asset::E_INDEX_TYPE type = buffer->getIndexType(); - if (!buffer->getIndexBufferBinding().buffer) - type = asset::EIT_UNKNOWN; - const uint32_t indexCount = buffer->getIndexCount(); - if (type==asset::EIT_16BIT) + pos_t positions[3] = {}; + if (idxSize == sizeof(uint16_t)) { - //os::Printer::log("Writing mesh with 16bit indices"); - for (uint32_t j=0; jgetPosition(((uint16_t*)buffer->getIndices())[j]), - buffer->getPosition(((uint16_t*)buffer->getIndices())[j+1]), - buffer->getPosition(((uint16_t*)buffer->getIndices())[j+2]), - context - ); - } + for (size_t j = 0; j < 3; j++) + { + uint16_t idx = *reinterpret_cast(idxView.getPointer(i + j)); + positions[j] = *reinterpret_cast(posView.getPointer(idx)); + } } - else if (type==asset::EIT_32BIT) + else if (idxSize == sizeof(uint32_t)) { - //os::Printer::log("Writing mesh with 32bit indices"); - for (uint32_t j=0; jgetPosition(((uint32_t*)buffer->getIndices())[j]), - buffer->getPosition(((uint32_t*)buffer->getIndices())[j+1]), - buffer->getPosition(((uint32_t*)buffer->getIndices())[j+2]), - context - ); - } + for (size_t j = 0; j < 3; j++) + { + uint32_t idx = *reinterpret_cast(idxView.getPointer(i + j)); + positions[j] = *reinterpret_cast(posView.getPointer(idx)); + } } else - { - //os::Printer::log("Writing mesh with no indices"); - for (uint32_t j=0; jgetPosition(j), - buffer->getPosition(j+1ul), - buffer->getPosition(j+2ul), - context - ); - } - } - { - system::IFile::success_t success;; - context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); - - context->fileOffset += success.getBytesProcessed(); + // TODO: what do we do with unknown index type + assert(false); } - } -#endif + writeFaceText(positions[0], positions[1], positions[2], context); + + context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); + context->fileOffset += success.getBytesProcessed(); + } context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); context->fileOffset += success.getBytesProcessed(); @@ -301,31 +279,31 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon return true; } -void CSTLMeshWriter::getVectorAsStringLine(const core::vectorSIMDf& v, std::string& s) const +void CSTLMeshWriter::getVectorAsStringLine(const pos_t& v, std::string& s) const { std::ostringstream tmp; - tmp << v.X << " " << v.Y << " " << v.Z << "\n"; + tmp << v.x << " " << v.y << " " << v.z << "\n"; s = std::string(tmp.str().c_str()); } void CSTLMeshWriter::writeFaceText( - const core::vectorSIMDf& v1, - const core::vectorSIMDf& v2, - const core::vectorSIMDf& v3, + const pos_t& v1, + const pos_t& v2, + const pos_t& v3, SContext* context) { - core::vectorSIMDf vertex1 = v3; - core::vectorSIMDf vertex2 = v2; - core::vectorSIMDf vertex3 = v1; - core::vectorSIMDf normal = core::plane3dSIMDf(vertex1, vertex2, vertex3).getNormal(); + pos_t vertex1 = v3; + pos_t vertex2 = v2; + pos_t vertex3 = v1; + normal_t normal = calculateNormal(vertex1, vertex2, vertex3); std::string tmp; auto flipVectors = [&]() { - vertex1.X = -vertex1.X; - vertex2.X = -vertex2.X; - vertex3.X = -vertex3.X; - normal = core::plane3dSIMDf(vertex1, vertex2, vertex3).getNormal(); + vertex1.x = -vertex1.x; + vertex2.x = -vertex2.x; + vertex3.x = -vertex3.x; + normal_t normal = calculateNormal(vertex1, vertex2, vertex3); }; if (!(context->writeContext.params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.h b/src/nbl/asset/interchange/CSTLMeshWriter.h index 771d9cb026..8db79b0d22 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.h +++ b/src/nbl/asset/interchange/CSTLMeshWriter.h @@ -35,24 +35,26 @@ class CSTLMeshWriter : public IGeometryWriter virtual bool writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override = nullptr) override; private: + using pos_t = hlsl::float32_t3; + using normal_t = hlsl::float32_t3; - struct SContext - { - SAssetWriteContext writeContext; - size_t fileOffset; - }; + struct SContext + { + SAssetWriteContext writeContext; + size_t fileOffset; + }; - // write binary format - bool writeMeshBinary(const ICPUPolygonGeometry* geom, SContext* context); + // write binary format + bool writeMeshBinary(const ICPUPolygonGeometry* geom, SContext* context); - // write text format - bool writeMeshASCII(const ICPUPolygonGeometry* geom, SContext* context); + // write text format + bool writeMeshASCII(const ICPUPolygonGeometry* geom, SContext* context); - // create vector output with line end into string - void getVectorAsStringLine(const core::vectorSIMDf& v, std::string& s) const; + // create vector output with line end into string + void getVectorAsStringLine(const pos_t& v, std::string& s) const; - // write face information to file - void writeFaceText(const core::vectorSIMDf& v1, const core::vectorSIMDf& v2, const core::vectorSIMDf& v3, SContext* context); + // write face information to file + void writeFaceText(const pos_t& v1, const pos_t& v2, const pos_t& v3, SContext* context); }; } // end namespace From feabf3a2968f9db9d279a56ef95a602cbbfc49c2 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 00:45:13 +0200 Subject: [PATCH 20/32] use different examples branch, success variable can't actually be reused --- examples_tests | 2 +- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 164 +++++++++++++------ 2 files changed, 117 insertions(+), 49 deletions(-) diff --git a/examples_tests b/examples_tests index 24e5f12d88..4a01642e0e 160000 --- a/examples_tests +++ b/examples_tests @@ -1 +1 @@ -Subproject commit 24e5f12d88d43695eed5b393d0480dc75c951198 +Subproject commit 4a01642e0e1f27519c8861688d39952a2bc612db diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index da00723f29..8cb15d2a11 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -29,6 +29,8 @@ CSTLMeshWriter::~CSTLMeshWriter() } +// FIXME: don't reuse success + //! writes a mesh bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override) { @@ -63,7 +65,17 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ inline static hlsl::float32_t3 calculateNormal(const hlsl::float32_t3& p1, const hlsl::float32_t3& p2, const hlsl::float32_t3& p3) { +#ifndef NDEBUG + auto u = p2 - p1; + auto v = p3 - p1; + auto c = hlsl::cross(u, v); + auto len = hlsl::length(c); + auto n = hlsl::normalize(c); + + return n; +#else return hlsl::normalize(hlsl::cross(p2 - p1, p3 - p1)); +#endif } namespace @@ -71,8 +83,10 @@ namespace template inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& noIndices, system::IFile* file, uint32_t _colorVaid, IAssetWriter::SAssetWriteContext* context, size_t* fileOffset) { - bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); - const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); + using pos_t = hlsl::float32_t3; + + // bool hasColor = inputParams.enabledAttribFlags & core::createBitmask({ COLOR_ATTRIBUTE }); + // const asset::E_FORMAT colorType = static_cast(hasColor ? inputParams.attributes[COLOR_ATTRIBUTE].format : asset::EF_UNKNOWN); auto& posView = geom->getPositionView(); auto& normalView = geom->getNormalView(); @@ -98,7 +112,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& // TODO: vertex color // TODO: I think I could get the normal from normalView, but I need to think how can I do that well - normal_t n = calculateNormal(pos[1], pos[2], pos[3]); + pos_t normal = calculateNormal(pos[1], pos[2], pos[3]); // success variable can be reused, no need to scope it system::IFile::success_t success{}; @@ -210,22 +224,32 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon using pos_t = hlsl::float32_t3; // write STL MESH header - const char headerTxt[] = "Nabla Engine "; + constexpr char headerTxt[] = "Nabla Engine "; - system::IFile::success_t success; - - context->writeContext.outputFile->write(success, "solid ", context->fileOffset, 6); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "solid ", context->fileOffset, 6); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); + context->fileOffset += success.getBytesProcessed(); + } const std::string name = context->writeContext.outputFile->getFileName().filename().replace_extension().string(); - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); + context->fileOffset += success.getBytesProcessed(); + } // TODO: what if index count is 0 auto& idxView = geom->getIndexView(); @@ -263,18 +287,30 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon writeFaceText(positions[0], positions[1], positions[2], context); - context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "\n", context->fileOffset, 1); + context->fileOffset += success.getBytesProcessed(); + } } - context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); - context->fileOffset += success.getBytesProcessed(); - - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "endsolid ", context->fileOffset, 9); + context->fileOffset += success.getBytesProcessed(); + } + + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt) - 1); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); + } return true; } @@ -282,6 +318,7 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon void CSTLMeshWriter::getVectorAsStringLine(const pos_t& v, std::string& s) const { std::ostringstream tmp; + tmp << std::fixed << std::setprecision(2); tmp << v.x << " " << v.y << " " << v.z << "\n"; s = std::string(tmp.str().c_str()); } @@ -295,7 +332,7 @@ void CSTLMeshWriter::writeFaceText( pos_t vertex1 = v3; pos_t vertex2 = v2; pos_t vertex3 = v1; - normal_t normal = calculateNormal(vertex1, vertex2, vertex3); + normal_t normal = calculateNormal(v1, v2, v3); std::string tmp; auto flipVectors = [&]() @@ -308,49 +345,80 @@ void CSTLMeshWriter::writeFaceText( if (!(context->writeContext.params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) flipVectors(); - - system::IFile::success_t success; - context->writeContext.outputFile->write(success, "facet normal ", context->fileOffset, 13); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "facet normal ", context->fileOffset, 13); + context->fileOffset += success.getBytesProcessed(); + } getVectorAsStringLine(normal, tmp); - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, " outer loop\n", context->fileOffset, 13); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, " outer loop\n", context->fileOffset, 13); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); + } getVectorAsStringLine(vertex1, tmp); - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); + } getVectorAsStringLine(vertex2, tmp); - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, " vertex ", context->fileOffset, 11); + context->fileOffset += success.getBytesProcessed(); + } getVectorAsStringLine(vertex3, tmp); - context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, tmp.c_str(), context->fileOffset, tmp.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, " endloop\n", context->fileOffset, 10); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, " endloop\n", context->fileOffset, 10); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, "endfacet\n", context->fileOffset, 9); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, "endfacet\n", context->fileOffset, 9); + context->fileOffset += success.getBytesProcessed(); + } } #endif From da2fe3e02431918240a78ac9d819daaa3790efa9 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 15:34:49 +0200 Subject: [PATCH 21/32] fix NaN normals --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 51 +++++++++----------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index 8cb15d2a11..d01dfe51c9 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -5,6 +5,8 @@ #include "nbl/system/ISystem.h" #include "nbl/system/IFile.h" +#include + #include "CSTLMeshWriter.h" #include "SColor.h" @@ -65,17 +67,7 @@ bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ inline static hlsl::float32_t3 calculateNormal(const hlsl::float32_t3& p1, const hlsl::float32_t3& p2, const hlsl::float32_t3& p3) { -#ifndef NDEBUG - auto u = p2 - p1; - auto v = p3 - p1; - auto c = hlsl::cross(u, v); - auto len = hlsl::length(c); - auto n = hlsl::normalize(c); - - return n; -#else return hlsl::normalize(hlsl::cross(p2 - p1, p3 - p1)); -#endif } namespace @@ -112,7 +104,7 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& // TODO: vertex color // TODO: I think I could get the normal from normalView, but I need to think how can I do that well - pos_t normal = calculateNormal(pos[1], pos[2], pos[3]); + pos_t normal = calculateNormal(pos[0], pos[1], pos[2]); // success variable can be reused, no need to scope it system::IFile::success_t success{}; @@ -255,34 +247,35 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon auto& idxView = geom->getIndexView(); const size_t idxCount = geom->getIndexCount(); - const size_t facesCount = idxCount / 3; const size_t idxSize = idxView.src.buffer->getSize() / idxCount; + const size_t facesCount = idxCount / 3; auto& posView = geom->getPositionView(); + const pos_t* posBufPtr = reinterpret_cast(posView.getPointer()); - for (size_t i = 0; i < facesCount; i++) + uint32_t idx[3]; + pos_t positions[3]; + for (size_t i = 0; i < idxCount; i += 3) { - pos_t positions[3] = {}; - if (idxSize == sizeof(uint16_t)) + for (size_t j = 0; j < 3; j++) { - for (size_t j = 0; j < 3; j++) + if (idxSize == sizeof(uint32_t)) { - uint16_t idx = *reinterpret_cast(idxView.getPointer(i + j)); - positions[j] = *reinterpret_cast(posView.getPointer(idx)); + const uint32_t* buf = reinterpret_cast(idxView.getPointer()); + idx[j] = *(buf + i + j); } - } - else if (idxSize == sizeof(uint32_t)) - { - for (size_t j = 0; j < 3; j++) + else if (idxSize == sizeof(uint16_t)) { - uint32_t idx = *reinterpret_cast(idxView.getPointer(i + j)); - positions[j] = *reinterpret_cast(posView.getPointer(idx)); + const uint16_t* buf = reinterpret_cast(idxView.getPointer()); + idx[j] = *(buf + i + j); } + else + assert(false); } - else + + for (size_t j = 0; j < 3; j++) { - // TODO: what do we do with unknown index type - assert(false); + positions[j] = *(posBufPtr + idx[j]); } writeFaceText(positions[0], positions[1], positions[2], context); @@ -329,9 +322,9 @@ void CSTLMeshWriter::writeFaceText( const pos_t& v3, SContext* context) { - pos_t vertex1 = v3; + pos_t vertex1 = v1; pos_t vertex2 = v2; - pos_t vertex3 = v1; + pos_t vertex3 = v3; normal_t normal = calculateNormal(v1, v2, v3); std::string tmp; From 7b9e906579ff3aaf5d90b99eab7acaa1941528f2 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 15:38:17 +0200 Subject: [PATCH 22/32] comment vertex color code instead of disabling it --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 68 ++++++++++---------- 1 file changed, 33 insertions(+), 35 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index d01dfe51c9..e98871ceff 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -120,42 +120,40 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& *fileOffset += success.getBytesProcessed(); } } -#if 0 - uint16_t color = 0u; - if (hasColor) - { - if (asset::isIntegerFormat(colorType)) - { - uint32_t res[4]; - for (uint32_t i = 0u; i < 3u; ++i) - { - uint32_t d[4]; - buffer->getAttribute(d, _colorVaid, idx[i]); - res[0] += d[0]; res[1] += d[1]; res[2] += d[2]; - } - color = video::RGB16(res[0]/3, res[1]/3, res[2]/3); - } - else - { - core::vectorSIMDf res; - for (uint32_t i = 0u; i < 3u; ++i) - { - core::vectorSIMDf d; - buffer->getAttribute(d, _colorVaid, idx[i]); - res += d; - } - res /= 3.f; - color = video::RGB16(res.X, res.Y, res.Z); - } - } - - { - system::IFile::success_t success;; - file->write(success, &color, *fileOffset, 2); // saving color using non-standard VisCAM/SolidView trick + // uint16_t color = 0u; + // if (hasColor) + // { + // if (asset::isIntegerFormat(colorType)) + // { + // uint32_t res[4]; + // for (uint32_t i = 0u; i < 3u; ++i) + // { + // uint32_t d[4]; + // buffer->getAttribute(d, _colorVaid, idx[i]); + // res[0] += d[0]; res[1] += d[1]; res[2] += d[2]; + // } + // color = video::RGB16(res[0]/3, res[1]/3, res[2]/3); + // } + // else + // { + // core::vectorSIMDf res; + // for (uint32_t i = 0u; i < 3u; ++i) + // { + // core::vectorSIMDf d; + // buffer->getAttribute(d, _colorVaid, idx[i]); + // res += d; + // } + // res /= 3.f; + // color = video::RGB16(res.X, res.Y, res.Z); + // } + // } + + //{ + // system::IFile::success_t success;; + // file->write(success, &color, *fileOffset, 2); // saving color using non-standard VisCAM/SolidView trick - *fileOffset += success.getBytesProcessed(); - } -#endif + // *fileOffset += success.getBytesProcessed(); + //} } } From 9602989aaa264327e36ab71ac2b267a16dfba9d0 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 15:49:46 +0200 Subject: [PATCH 23/32] stop reusing success variable across the whole file, update header text in binary writer --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 40 +++++++++++--------- 1 file changed, 23 insertions(+), 17 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index e98871ceff..c30ea51a43 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -31,8 +31,6 @@ CSTLMeshWriter::~CSTLMeshWriter() } -// FIXME: don't reuse success - //! writes a mesh bool CSTLMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override) { @@ -102,20 +100,22 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& pos[j] = *(vtxBufPtr + idx[j]); // TODO: vertex color - // TODO: I think I could get the normal from normalView, but I need to think how can I do that well pos_t normal = calculateNormal(pos[0], pos[1], pos[2]); // success variable can be reused, no need to scope it - system::IFile::success_t success{}; // write normal - file->write(success, &normal, *fileOffset, 12); - *fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + file->write(success, &normal, *fileOffset, 12); + *fileOffset += success.getBytesProcessed(); + } // write positions for (size_t j = 0; j < 3; j++) { + system::IFile::success_t success; file->write(success, &pos[i], *fileOffset, 12); *fileOffset += success.getBytesProcessed(); } @@ -160,19 +160,21 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SContext* context) { // write STL MESH header - const char headerTxt[] = "Irrlicht-baw Engine"; + const char headerTxt[] = "Nabla Engine"; constexpr size_t HEADER_SIZE = 80u; - system::IFile::success_t success; - - context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt)); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, headerTxt, context->fileOffset, sizeof(headerTxt)); + context->fileOffset += success.getBytesProcessed(); + } const std::string name = context->writeContext.outputFile->getFileName().filename().replace_extension().string(); // TODO: check it const int32_t sizeleft = HEADER_SIZE - sizeof(headerTxt) - name.size(); if (sizeleft < 0) { + system::IFile::success_t success; context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, HEADER_SIZE - sizeof(headerTxt)); context->fileOffset += success.getBytesProcessed(); } @@ -180,14 +182,19 @@ bool CSTLMeshWriter::writeMeshBinary(const asset::ICPUPolygonGeometry* geom, SCo { const char buf[80] = {0}; - context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, name.c_str(), context->fileOffset, name.size()); + context->fileOffset += success.getBytesProcessed(); + } - context->writeContext.outputFile->write(success, buf, context->fileOffset, sizeleft); - context->fileOffset += success.getBytesProcessed(); + { + system::IFile::success_t success; + context->writeContext.outputFile->write(success, buf, context->fileOffset, sizeleft); + context->fileOffset += success.getBytesProcessed(); + } } - // TODO: is this method (writeFacesBinary) even necessary with new ICPUPolygonGeometry? size_t idxCount = geom->getIndexCount(); size_t facesCount = idxCount / 3; @@ -241,7 +248,6 @@ bool CSTLMeshWriter::writeMeshASCII(const asset::ICPUPolygonGeometry* geom, SCon context->fileOffset += success.getBytesProcessed(); } - // TODO: what if index count is 0 auto& idxView = geom->getIndexView(); const size_t idxCount = geom->getIndexCount(); From f59ea88aab3628a626c5b910a0cfe0342eeb2db6 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 15:58:50 +0200 Subject: [PATCH 24/32] don't assume index type in binary writer, fix mistake --- src/nbl/asset/interchange/CSTLMeshWriter.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/nbl/asset/interchange/CSTLMeshWriter.cpp b/src/nbl/asset/interchange/CSTLMeshWriter.cpp index c30ea51a43..4d925c577e 100644 --- a/src/nbl/asset/interchange/CSTLMeshWriter.cpp +++ b/src/nbl/asset/interchange/CSTLMeshWriter.cpp @@ -85,8 +85,9 @@ inline void writeFacesBinary(const asset::ICPUPolygonGeometry* geom, const bool& const auto vertexCount = posView.getElementCount(); const auto idxCount = idxView.getElementCount(); - // TODO: check if I can actually assume following types, if not, handle that - const uint32_t* idxBufPtr = reinterpret_cast(idxView.getPointer()); + assert((idxView.src.buffer->getSize() / idxCount) == sizeof(IndexType)); + + const IndexType* idxBufPtr = reinterpret_cast(idxView.getPointer()); const pos_t* vtxBufPtr = reinterpret_cast(posView.getPointer()); for (size_t i = 0; i < idxCount; i+=3) From e890923ba7076bc9130358b43d032aa0e23d0b0c Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 17:48:15 +0200 Subject: [PATCH 25/32] reenable PLY writer, correct function implementations --- src/nbl/CMakeLists.txt | 2 +- src/nbl/asset/interchange/CPLYMeshWriter.cpp | 321 +++++++++---------- 2 files changed, 161 insertions(+), 162 deletions(-) diff --git a/src/nbl/CMakeLists.txt b/src/nbl/CMakeLists.txt index f4e48a1eab..93e95a427c 100755 --- a/src/nbl/CMakeLists.txt +++ b/src/nbl/CMakeLists.txt @@ -55,7 +55,7 @@ option(_NBL_COMPILE_WITH_OBJ_LOADER_ "Compile with OBJ Loader" OFF) #default off option(_NBL_COMPILE_WITH_STL_LOADER_ "Compile with STL Loader" ON) option(_NBL_COMPILE_WITH_STL_WRITER_ "Compile with STL Writer" ON) option(_NBL_COMPILE_WITH_PLY_LOADER_ "Compile with PLY Loader" ON) -option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" OFF) #default off until reimplemented +option(_NBL_COMPILE_WITH_PLY_WRITER_ "Compile with PLY Writer" ON) option(_NBL_COMPILE_WITH_JPG_LOADER_ "Compile with JPG Loader" ON) option(_NBL_COMPILE_WITH_JPG_WRITER_ "Compile with JPG Writer" ON) option(_NBL_COMPILE_WITH_PNG_LOADER_ "Compile with PNG Loader" ON) diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.cpp b/src/nbl/asset/interchange/CPLYMeshWriter.cpp index fd6fa3ea9e..8051e7b712 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.cpp +++ b/src/nbl/asset/interchange/CPLYMeshWriter.cpp @@ -9,7 +9,6 @@ #include "nbl/system/ISystem.h" #include "nbl/system/IFile.h" -#include "nbl/asset/utils/CMeshManipulator.h" namespace nbl { @@ -57,178 +56,178 @@ CPLYMeshWriter::CPLYMeshWriter() } //! writes a mesh -bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override) +bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override = nullptr) { - if (!_override) - getDefaultOverride(_override); + if (!_override) + getDefaultOverride(_override); - SAssetWriteContext inCtx{ _params, _file }; + SAssetWriteContext inCtx{ _params, _file }; - const asset::ICPUMesh* mesh = IAsset::castDown(_params.rootAsset); - if (!mesh) - return false; + const asset::ICPUPolygonGeometry* mesh = IAsset::castDown(_params.rootAsset); + if (!mesh) + return false; - system::IFile* file = _override->getOutputFile(_file, inCtx, {mesh, 0u}); + system::IFile* file = _override->getOutputFile(_file, inCtx, {mesh, 0u}); - auto meshbuffers = mesh->getMeshBuffers(); - if (!file || !mesh) - return false; + auto meshbuffers = mesh->getMeshBuffers(); + if (!file || !mesh) + return false; - SContext context = { SAssetWriteContext{ inCtx.params, file} }; + SContext context = { SAssetWriteContext{ inCtx.params, file} }; - if (meshbuffers.size() > 1) - { - #ifdef _NBL_DEBUG - context.writeContext.params.logger.log("PLY WRITER WARNING (" + std::to_string(__LINE__) + " line): Only one meshbuffer input is allowed for writing! Saving first one", system::ILogger::ELL_WARNING, file->getFileName().string().c_str()); - #endif // _NBL_DEBUG - } - - context.writeContext.params.logger.log("Writing PLY mesh", system::ILogger::ELL_INFO, file->getFileName().string().c_str()); - - const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(context.writeContext, mesh, 0u); - - auto getConvertedCpuMeshBufferWithIndexBuffer = [&]() -> core::smart_refctd_ptr - { - auto inputMeshBuffer = *meshbuffers.begin(); - const bool doesItHaveIndexBuffer = inputMeshBuffer->getIndexBufferBinding().buffer.get(); - const bool isItNotTriangleListsPrimitive = inputMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType != asset::EPT_TRIANGLE_LIST; + if (meshbuffers.size() > 1) + { + #ifdef _NBL_DEBUG + context.writeContext.params.logger.log("PLY WRITER WARNING (" + std::to_string(__LINE__) + " line): Only one meshbuffer input is allowed for writing! Saving first one", system::ILogger::ELL_WARNING, file->getFileName().string().c_str()); + #endif // _NBL_DEBUG + } + + context.writeContext.params.logger.log("Writing PLY mesh", system::ILogger::ELL_INFO, file->getFileName().string().c_str()); + + const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(context.writeContext, mesh, 0u); + + auto getConvertedCpuMeshBufferWithIndexBuffer = [&]() -> core::smart_refctd_ptr + { + auto inputMeshBuffer = *meshbuffers.begin(); + const bool doesItHaveIndexBuffer = inputMeshBuffer->getIndexBufferBinding().buffer.get(); + const bool isItNotTriangleListsPrimitive = inputMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType != asset::EPT_TRIANGLE_LIST; - if (doesItHaveIndexBuffer && isItNotTriangleListsPrimitive) - { - auto cpuConvertedMeshBuffer = core::smart_refctd_ptr_static_cast(inputMeshBuffer->clone()); - IMeshManipulator::homogenizePrimitiveTypeAndIndices(&cpuConvertedMeshBuffer, &cpuConvertedMeshBuffer + 1, asset::EPT_TRIANGLE_LIST, asset::EIT_32BIT); - return cpuConvertedMeshBuffer; - } - else - return nullptr; - }; - - const auto cpuConvertedMeshBufferWithIndexBuffer = getConvertedCpuMeshBufferWithIndexBuffer(); - const asset::ICPUMeshBuffer* rawCopyMeshBuffer = cpuConvertedMeshBufferWithIndexBuffer.get() ? cpuConvertedMeshBufferWithIndexBuffer.get() : *meshbuffers.begin(); - const bool doesItUseIndexBufferBinding = (rawCopyMeshBuffer->getIndexBufferBinding().buffer.get() && rawCopyMeshBuffer->getIndexType() != asset::EIT_UNKNOWN); - - uint32_t faceCount = {}; - size_t vertexCount = {}; - - void* indices = nullptr; - { - auto indexCount = rawCopyMeshBuffer->getIndexCount(); - - indices = _NBL_ALIGNED_MALLOC(indexCount * sizeof(uint32_t), _NBL_SIMD_ALIGNMENT); - memcpy(indices, rawCopyMeshBuffer->getIndices(), indexCount * sizeof(uint32_t)); + if (doesItHaveIndexBuffer && isItNotTriangleListsPrimitive) + { + auto cpuConvertedMeshBuffer = core::smart_refctd_ptr_static_cast(inputMeshBuffer->clone()); + IMeshManipulator::homogenizePrimitiveTypeAndIndices(&cpuConvertedMeshBuffer, &cpuConvertedMeshBuffer + 1, asset::EPT_TRIANGLE_LIST, asset::EIT_32BIT); + return cpuConvertedMeshBuffer; + } + else + return nullptr; + }; + + const auto cpuConvertedMeshBufferWithIndexBuffer = getConvertedCpuMeshBufferWithIndexBuffer(); + const asset::ICPUMeshBuffer* rawCopyMeshBuffer = cpuConvertedMeshBufferWithIndexBuffer.get() ? cpuConvertedMeshBufferWithIndexBuffer.get() : *meshbuffers.begin(); + const bool doesItUseIndexBufferBinding = (rawCopyMeshBuffer->getIndexBufferBinding().buffer.get() && rawCopyMeshBuffer->getIndexType() != asset::EIT_UNKNOWN); + + uint32_t faceCount = {}; + size_t vertexCount = {}; + + void* indices = nullptr; + { + auto indexCount = rawCopyMeshBuffer->getIndexCount(); + + indices = _NBL_ALIGNED_MALLOC(indexCount * sizeof(uint32_t), _NBL_SIMD_ALIGNMENT); + memcpy(indices, rawCopyMeshBuffer->getIndices(), indexCount * sizeof(uint32_t)); - IMeshManipulator::getPolyCount(faceCount, rawCopyMeshBuffer); - vertexCount = IMeshManipulator::upperBoundVertexID(rawCopyMeshBuffer); - } - - // write PLY header - std::string header = "ply\n"; - header += (flags & asset::EWF_BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0"; - header += "\ncomment IrrlichtBAW "; - header += NABLA_SDK_VERSION; - - // vertex definition - header += "\nelement vertex "; - header += std::to_string(vertexCount) + '\n'; - - bool vaidToWrite[4]{ 0, 0, 0, 0 }; - - const uint32_t POSITION_ATTRIBUTE = rawCopyMeshBuffer->getPositionAttributeIx(); - constexpr uint32_t COLOR_ATTRIBUTE = 1; - constexpr uint32_t UV_ATTRIBUTE = 2; - const uint32_t NORMAL_ATTRIBUTE = rawCopyMeshBuffer->getNormalAttributeIx(); - - if (rawCopyMeshBuffer->getAttribBoundBuffer(POSITION_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(POSITION_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[0] = true; - header += - "property " + typeStr + " x\n" + - "property " + typeStr + " y\n" + - "property " + typeStr + " z\n"; - } - if (rawCopyMeshBuffer->getAttribBoundBuffer(COLOR_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(COLOR_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[1] = true; - header += - "property " + typeStr + " red\n" + - "property " + typeStr + " green\n" + - "property " + typeStr + " blue\n"; - if (asset::getFormatChannelCount(t) == 4u) - { - header += "property " + typeStr + " alpha\n"; - } - } - if (rawCopyMeshBuffer->getAttribBoundBuffer(UV_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(UV_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[2] = true; - header += - "property " + typeStr + " u\n" + - "property " + typeStr + " v\n"; - } - if (rawCopyMeshBuffer->getAttribBoundBuffer(NORMAL_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(NORMAL_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[3] = true; - header += - "property " + typeStr + " nx\n" + - "property " + typeStr + " ny\n" + - "property " + typeStr + " nz\n"; - } - - asset::E_INDEX_TYPE idxT = asset::EIT_UNKNOWN; - bool forceFaces = false; - - const auto primitiveType = rawCopyMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType; - const auto indexType = rawCopyMeshBuffer->getIndexType(); + IMeshManipulator::getPolyCount(faceCount, rawCopyMeshBuffer); + vertexCount = IMeshManipulator::upperBoundVertexID(rawCopyMeshBuffer); + } + + // write PLY header + std::string header = "ply\n"; + header += (flags & asset::EWF_BINARY) ? "format binary_little_endian 1.0" : "format ascii 1.0"; + header += "\ncomment Nabla "; + header += NABLA_SDK_VERSION; + + // vertex definition + header += "\nelement vertex "; + header += std::to_string(vertexCount) + '\n'; + + bool vaidToWrite[4]{ 0, 0, 0, 0 }; + + const uint32_t POSITION_ATTRIBUTE = rawCopyMeshBuffer->getPositionAttributeIx(); + constexpr uint32_t COLOR_ATTRIBUTE = 1; + constexpr uint32_t UV_ATTRIBUTE = 2; + const uint32_t NORMAL_ATTRIBUTE = rawCopyMeshBuffer->getNormalAttributeIx(); + + if (rawCopyMeshBuffer->getAttribBoundBuffer(POSITION_ATTRIBUTE).buffer) + { + const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(POSITION_ATTRIBUTE); + std::string typeStr = getTypeString(t); + vaidToWrite[0] = true; + header += + "property " + typeStr + " x\n" + + "property " + typeStr + " y\n" + + "property " + typeStr + " z\n"; + } + if (rawCopyMeshBuffer->getAttribBoundBuffer(COLOR_ATTRIBUTE).buffer) + { + const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(COLOR_ATTRIBUTE); + std::string typeStr = getTypeString(t); + vaidToWrite[1] = true; + header += + "property " + typeStr + " red\n" + + "property " + typeStr + " green\n" + + "property " + typeStr + " blue\n"; + if (asset::getFormatChannelCount(t) == 4u) + { + header += "property " + typeStr + " alpha\n"; + } + } + if (rawCopyMeshBuffer->getAttribBoundBuffer(UV_ATTRIBUTE).buffer) + { + const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(UV_ATTRIBUTE); + std::string typeStr = getTypeString(t); + vaidToWrite[2] = true; + header += + "property " + typeStr + " u\n" + + "property " + typeStr + " v\n"; + } + if (rawCopyMeshBuffer->getAttribBoundBuffer(NORMAL_ATTRIBUTE).buffer) + { + const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(NORMAL_ATTRIBUTE); + std::string typeStr = getTypeString(t); + vaidToWrite[3] = true; + header += + "property " + typeStr + " nx\n" + + "property " + typeStr + " ny\n" + + "property " + typeStr + " nz\n"; + } + + asset::E_INDEX_TYPE idxT = asset::EIT_UNKNOWN; + bool forceFaces = false; + + const auto primitiveType = rawCopyMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType; + const auto indexType = rawCopyMeshBuffer->getIndexType(); - if (primitiveType == asset::EPT_POINT_LIST) - faceCount = 0u; - else if (doesItUseIndexBufferBinding) - { - header += "element face "; - header += std::to_string(faceCount) + '\n'; - idxT = indexType; - const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; - header += "property list uchar " + idxTypeStr + " vertex_indices\n"; - } - else if (primitiveType == asset::EPT_TRIANGLE_LIST) - { - forceFaces = true; - - header += "element face "; - header += std::to_string(faceCount) + '\n'; - idxT = vertexCount <= ((1u<<16) - 1) ? asset::EIT_16BIT : asset::EIT_32BIT; - const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; - header += "property list uchar " + idxTypeStr + " vertex_indices\n"; - } - else - faceCount = 0u; - header += "end_header\n"; - - { - system::IFile::success_t success; - file->write(success, header.c_str(), context.fileOffset, header.size()); - context.fileOffset += success.getBytesProcessed(); - } + if (primitiveType == asset::EPT_POINT_LIST) + faceCount = 0u; + else if (doesItUseIndexBufferBinding) + { + header += "element face "; + header += std::to_string(faceCount) + '\n'; + idxT = indexType; + const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; + header += "property list uchar " + idxTypeStr + " vertex_indices\n"; + } + else if (primitiveType == asset::EPT_TRIANGLE_LIST) + { + forceFaces = true; + + header += "element face "; + header += std::to_string(faceCount) + '\n'; + idxT = vertexCount <= ((1u<<16) - 1) ? asset::EIT_16BIT : asset::EIT_32BIT; + const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; + header += "property list uchar " + idxTypeStr + " vertex_indices\n"; + } + else + faceCount = 0u; + header += "end_header\n"; + + { + system::IFile::success_t success; + file->write(success, header.c_str(), context.fileOffset, header.size()); + context.fileOffset += success.getBytesProcessed(); + } - if (flags & asset::EWF_BINARY) - writeBinary(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); - else - writeText(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); + if (flags & asset::EWF_BINARY) + writeBinary(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); + else + writeText(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); - _NBL_ALIGNED_FREE(const_cast(indices)); + _NBL_ALIGNED_FREE(const_cast(indices)); - return true; + return true; } -void CPLYMeshWriter::writeBinary(const asset::ICPUMeshBuffer* _mbuf, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const +void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const { const size_t colCpa = asset::getFormatChannelCount(_mbuf->getAttribFormat(1)); @@ -318,7 +317,7 @@ void CPLYMeshWriter::writeBinary(const asset::ICPUMeshBuffer* _mbuf, size_t _vtx _NBL_ALIGNED_FREE(indices); } -void CPLYMeshWriter::writeText(const asset::ICPUMeshBuffer* _mbuf, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const +void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const { auto mbCopy = createCopyMBuffNormalizedReplacedWithTrueInt(_mbuf); @@ -446,7 +445,7 @@ void CPLYMeshWriter::writeText(const asset::ICPUMeshBuffer* _mbuf, size_t _vtxCo _NBL_ALIGNED_FREE(indices); } -void CPLYMeshWriter::writeAttribBinary(SContext& context, asset::ICPUMeshBuffer* _mbuf, uint32_t _vaid, size_t _ix, size_t _cpa, bool flipAttribute) const +void CPLYMeshWriter::writeAttribBinary(SContext& context, ICPUPolygonGeometry* geom, uint32_t _vaid, size_t _ix, size_t _cpa, bool flipAttribute) const { uint32_t ui[4]; core::vectorSIMDf f; @@ -506,7 +505,7 @@ void CPLYMeshWriter::writeAttribBinary(SContext& context, asset::ICPUMeshBuffer* } } -core::smart_refctd_ptr CPLYMeshWriter::createCopyMBuffNormalizedReplacedWithTrueInt(const asset::ICPUMeshBuffer* _mbuf) +core::smart_refctd_ptr CPLYMeshWriter::createCopyNormalizedReplacedWithTrueInt(const ICPUPolygonGeometry* geom) { auto mbCopy = core::smart_refctd_ptr_static_cast(_mbuf->clone(2)); From e73b0bdf0e55bb02e6a351f64dca708e1c582bc3 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 6 Aug 2025 19:33:04 +0200 Subject: [PATCH 26/32] get it compiling, write a basic ply header --- src/nbl/asset/interchange/CPLYMeshWriter.cpp | 119 +++++++++++-------- 1 file changed, 69 insertions(+), 50 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.cpp b/src/nbl/asset/interchange/CPLYMeshWriter.cpp index 8051e7b712..581d1df05e 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.cpp +++ b/src/nbl/asset/interchange/CPLYMeshWriter.cpp @@ -56,7 +56,7 @@ CPLYMeshWriter::CPLYMeshWriter() } //! writes a mesh -bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override = nullptr) +bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _params, IAssetWriterOverride* _override) { if (!_override) getDefaultOverride(_override); @@ -68,57 +68,42 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ return false; system::IFile* file = _override->getOutputFile(_file, inCtx, {mesh, 0u}); - - auto meshbuffers = mesh->getMeshBuffers(); if (!file || !mesh) - return false; + return false; SContext context = { SAssetWriteContext{ inCtx.params, file} }; - - if (meshbuffers.size() > 1) - { - #ifdef _NBL_DEBUG - context.writeContext.params.logger.log("PLY WRITER WARNING (" + std::to_string(__LINE__) + " line): Only one meshbuffer input is allowed for writing! Saving first one", system::ILogger::ELL_WARNING, file->getFileName().string().c_str()); - #endif // _NBL_DEBUG - } context.writeContext.params.logger.log("Writing PLY mesh", system::ILogger::ELL_INFO, file->getFileName().string().c_str()); const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(context.writeContext, mesh, 0u); - auto getConvertedCpuMeshBufferWithIndexBuffer = [&]() -> core::smart_refctd_ptr - { - auto inputMeshBuffer = *meshbuffers.begin(); - const bool doesItHaveIndexBuffer = inputMeshBuffer->getIndexBufferBinding().buffer.get(); - const bool isItNotTriangleListsPrimitive = inputMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType != asset::EPT_TRIANGLE_LIST; - - if (doesItHaveIndexBuffer && isItNotTriangleListsPrimitive) - { - auto cpuConvertedMeshBuffer = core::smart_refctd_ptr_static_cast(inputMeshBuffer->clone()); - IMeshManipulator::homogenizePrimitiveTypeAndIndices(&cpuConvertedMeshBuffer, &cpuConvertedMeshBuffer + 1, asset::EPT_TRIANGLE_LIST, asset::EIT_32BIT); - return cpuConvertedMeshBuffer; - } - else - return nullptr; - }; - - const auto cpuConvertedMeshBufferWithIndexBuffer = getConvertedCpuMeshBufferWithIndexBuffer(); - const asset::ICPUMeshBuffer* rawCopyMeshBuffer = cpuConvertedMeshBufferWithIndexBuffer.get() ? cpuConvertedMeshBufferWithIndexBuffer.get() : *meshbuffers.begin(); - const bool doesItUseIndexBufferBinding = (rawCopyMeshBuffer->getIndexBufferBinding().buffer.get() && rawCopyMeshBuffer->getIndexType() != asset::EIT_UNKNOWN); - - uint32_t faceCount = {}; - size_t vertexCount = {}; - - void* indices = nullptr; - { - auto indexCount = rawCopyMeshBuffer->getIndexCount(); - - indices = _NBL_ALIGNED_MALLOC(indexCount * sizeof(uint32_t), _NBL_SIMD_ALIGNMENT); - memcpy(indices, rawCopyMeshBuffer->getIndices(), indexCount * sizeof(uint32_t)); - - IMeshManipulator::getPolyCount(faceCount, rawCopyMeshBuffer); - vertexCount = IMeshManipulator::upperBoundVertexID(rawCopyMeshBuffer); - } + //auto getConvertedCpuMeshBufferWithIndexBuffer = [&]() -> core::smart_refctd_ptr + //{ + // auto inputMeshBuffer = *meshbuffers.begin(); + // const bool doesItHaveIndexBuffer = inputMeshBuffer->getIndexBufferBinding().buffer.get(); + // const bool isItNotTriangleListsPrimitive = inputMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType != asset::EPT_TRIANGLE_LIST; + // + // if (doesItHaveIndexBuffer && isItNotTriangleListsPrimitive) + // { + // auto cpuConvertedMeshBuffer = core::smart_refctd_ptr_static_cast(inputMeshBuffer->clone()); + // IMeshManipulator::homogenizePrimitiveTypeAndIndices(&cpuConvertedMeshBuffer, &cpuConvertedMeshBuffer + 1, asset::EPT_TRIANGLE_LIST, asset::EIT_32BIT); + // return cpuConvertedMeshBuffer; + // } + // else + // return nullptr; + //}; + + //const auto cpuConvertedMeshBufferWithIndexBuffer = getConvertedCpuMeshBufferWithIndexBuffer(); + //const asset::ICPUMeshBuffer* rawCopyMeshBuffer = cpuConvertedMeshBufferWithIndexBuffer.get() ? cpuConvertedMeshBufferWithIndexBuffer.get() : *meshbuffers.begin(); + //const bool doesItUseIndexBufferBinding = (rawCopyMeshBuffer->getIndexBufferBinding().buffer.get() && rawCopyMeshBuffer->getIndexType() != asset::EIT_UNKNOWN); + + const auto& idxView = mesh->getIndexView(); + const auto& vtxView = mesh->getPositionView(); + const auto& normalView = mesh->getNormalView(); + const auto& auxAttributes = mesh->getAuxAttributeViews(); + + // TODO: other cases + const size_t faceCount = mesh->getIndexCount() / 3; // write PLY header std::string header = "ply\n"; @@ -128,14 +113,30 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ // vertex definition header += "\nelement vertex "; - header += std::to_string(vertexCount) + '\n'; + header += std::to_string(vtxView.getElementCount()) + '\n'; - bool vaidToWrite[4]{ 0, 0, 0, 0 }; + std::string typeStr = getTypeString(vtxView.composed.format); + header += "property " + typeStr + " x\n" + + "property " + typeStr + " y\n" + + "property " + typeStr + " z\n"; + + if (normalView.getElementCount() > 0) + { + header += "element normal "; + header += std::to_string(normalView.getElementCount()) + '\n'; + + typeStr = getTypeString(normalView.composed.format); + header += "property " + typeStr + " nx\n" + + "property " + typeStr + " ny\n" + + "property " + typeStr + " nz\n"; + } - const uint32_t POSITION_ATTRIBUTE = rawCopyMeshBuffer->getPositionAttributeIx(); - constexpr uint32_t COLOR_ATTRIBUTE = 1; - constexpr uint32_t UV_ATTRIBUTE = 2; - const uint32_t NORMAL_ATTRIBUTE = rawCopyMeshBuffer->getNormalAttributeIx(); + header += "element face " + std::to_string(faceCount) + '\n'; + header += "property list " + getTypeString(idxView.composed.format) + " vertex_index\n"; + + // TODO: Texcoords and vertex colors +#if 0 + bool vaidToWrite[4]{ 0, 0, 0, 0 }; if (rawCopyMeshBuffer->getAttribBoundBuffer(POSITION_ATTRIBUTE).buffer) { @@ -224,11 +225,21 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ _NBL_ALIGNED_FREE(const_cast(indices)); +#endif + header += "end_header\n"; + + { // TODO: remove that, added for testing purposes + system::IFile::success_t success; + context.writeContext.outputFile->write(success, header.data(), context.fileOffset, header.size()); + context.fileOffset += success.getBytesProcessed(); + } + return true; } void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const { +#if 0 const size_t colCpa = asset::getFormatChannelCount(_mbuf->getAttribFormat(1)); bool flipVectors = (!(context.writeContext.params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) ? true : false; @@ -315,10 +326,12 @@ void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCou if (_forceFaces) _NBL_ALIGNED_FREE(indices); +#endif } void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const { +#if 0 auto mbCopy = createCopyMBuffNormalizedReplacedWithTrueInt(_mbuf); auto writefunc = [&context, &mbCopy, this](uint32_t _vaid, size_t _ix, size_t _cpa) @@ -443,10 +456,12 @@ void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, size_t _vtxCount if (_forceFaces) _NBL_ALIGNED_FREE(indices); +#endif } void CPLYMeshWriter::writeAttribBinary(SContext& context, ICPUPolygonGeometry* geom, uint32_t _vaid, size_t _ix, size_t _cpa, bool flipAttribute) const { +#if 0 uint32_t ui[4]; core::vectorSIMDf f; asset::E_FORMAT t = _mbuf->getAttribFormat(_vaid); @@ -503,10 +518,12 @@ void CPLYMeshWriter::writeAttribBinary(SContext& context, ICPUPolygonGeometry* g context.fileOffset += success.getBytesProcessed(); } } +#endif } core::smart_refctd_ptr CPLYMeshWriter::createCopyNormalizedReplacedWithTrueInt(const ICPUPolygonGeometry* geom) { +#if 0 auto mbCopy = core::smart_refctd_ptr_static_cast(_mbuf->clone(2)); for (size_t i = 0; i < ICPUMeshBuffer::MAX_VERTEX_ATTRIB_COUNT; ++i) @@ -519,6 +536,8 @@ core::smart_refctd_ptr CPLYMeshWriter::createCopyNormalized } return mbCopy; +#endif + return nullptr; } std::string CPLYMeshWriter::getTypeString(asset::E_FORMAT _t) From e60892916ed4eac3e0d688d52960197a594014fb Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 13 Aug 2025 14:37:09 +0200 Subject: [PATCH 27/32] correct mistake in normal writing --- src/nbl/asset/interchange/CPLYMeshWriter.cpp | 100 ++----------------- 1 file changed, 6 insertions(+), 94 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.cpp b/src/nbl/asset/interchange/CPLYMeshWriter.cpp index 581d1df05e..a38444e2a3 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.cpp +++ b/src/nbl/asset/interchange/CPLYMeshWriter.cpp @@ -122,110 +122,22 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ if (normalView.getElementCount() > 0) { - header += "element normal "; - header += std::to_string(normalView.getElementCount()) + '\n'; - - typeStr = getTypeString(normalView.composed.format); + std::string typeStr = getTypeString(normalView.composed.format); header += "property " + typeStr + " nx\n" + "property " + typeStr + " ny\n" + "property " + typeStr + " nz\n"; } header += "element face " + std::to_string(faceCount) + '\n'; - header += "property list " + getTypeString(idxView.composed.format) + " vertex_index\n"; - - // TODO: Texcoords and vertex colors -#if 0 - bool vaidToWrite[4]{ 0, 0, 0, 0 }; + header += "property list uchar " + getTypeString(idxView.composed.format) + " vertex_index\n"; - if (rawCopyMeshBuffer->getAttribBoundBuffer(POSITION_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(POSITION_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[0] = true; - header += - "property " + typeStr + " x\n" + - "property " + typeStr + " y\n" + - "property " + typeStr + " z\n"; - } - if (rawCopyMeshBuffer->getAttribBoundBuffer(COLOR_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(COLOR_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[1] = true; - header += - "property " + typeStr + " red\n" + - "property " + typeStr + " green\n" + - "property " + typeStr + " blue\n"; - if (asset::getFormatChannelCount(t) == 4u) - { - header += "property " + typeStr + " alpha\n"; - } - } - if (rawCopyMeshBuffer->getAttribBoundBuffer(UV_ATTRIBUTE).buffer) + // TODO: Texcoords, vertex colors and any additional properties + if (auxAttributes.size() > 0) + for (auto& attr : auxAttributes) { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(UV_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[2] = true; - header += - "property " + typeStr + " u\n" + - "property " + typeStr + " v\n"; + } - if (rawCopyMeshBuffer->getAttribBoundBuffer(NORMAL_ATTRIBUTE).buffer) - { - const asset::E_FORMAT t = rawCopyMeshBuffer->getAttribFormat(NORMAL_ATTRIBUTE); - std::string typeStr = getTypeString(t); - vaidToWrite[3] = true; - header += - "property " + typeStr + " nx\n" + - "property " + typeStr + " ny\n" + - "property " + typeStr + " nz\n"; - } - - asset::E_INDEX_TYPE idxT = asset::EIT_UNKNOWN; - bool forceFaces = false; - - const auto primitiveType = rawCopyMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType; - const auto indexType = rawCopyMeshBuffer->getIndexType(); - if (primitiveType == asset::EPT_POINT_LIST) - faceCount = 0u; - else if (doesItUseIndexBufferBinding) - { - header += "element face "; - header += std::to_string(faceCount) + '\n'; - idxT = indexType; - const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; - header += "property list uchar " + idxTypeStr + " vertex_indices\n"; - } - else if (primitiveType == asset::EPT_TRIANGLE_LIST) - { - forceFaces = true; - - header += "element face "; - header += std::to_string(faceCount) + '\n'; - idxT = vertexCount <= ((1u<<16) - 1) ? asset::EIT_16BIT : asset::EIT_32BIT; - const std::string idxTypeStr = idxT == asset::EIT_32BIT ? "uint32" : "uint16"; - header += "property list uchar " + idxTypeStr + " vertex_indices\n"; - } - else - faceCount = 0u; - header += "end_header\n"; - - { - system::IFile::success_t success; - file->write(success, header.c_str(), context.fileOffset, header.size()); - context.fileOffset += success.getBytesProcessed(); - } - - if (flags & asset::EWF_BINARY) - writeBinary(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); - else - writeText(rawCopyMeshBuffer, vertexCount, faceCount, idxT, indices, forceFaces, vaidToWrite, context); - - _NBL_ALIGNED_FREE(const_cast(indices)); - -#endif header += "end_header\n"; { // TODO: remove that, added for testing purposes From 5576403312db885c705284a425c518bbe8ac0780 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 13 Aug 2025 21:31:20 +0200 Subject: [PATCH 28/32] make ply loader recognize uint and uint32 types --- .../asset/interchange/CPLYMeshFileLoader.cpp | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp index 932a04b82c..ffc1aa3eb1 100644 --- a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp @@ -63,21 +63,23 @@ struct SContext { static E_FORMAT getType(const char* typeString) { - if (strcmp(typeString, "char")==0 || strcmp(typeString, "int8")==0) + if (strcmp(typeString, "char") == 0 || strcmp(typeString, "int8") == 0) return EF_R8_SINT; - else if (strcmp(typeString, "uchar")==0 || strcmp(typeString, "uint8")==0) + else if (strcmp(typeString, "uchar") == 0 || strcmp(typeString, "uint8") == 0) return EF_R8_UINT; - else if (strcmp(typeString, "short")==0 || strcmp(typeString, "int16")==0) + else if (strcmp(typeString, "short") == 0 || strcmp(typeString, "int16") == 0) return EF_R16_SINT; - else if (strcmp(typeString, "ushort")==0 || strcmp(typeString, "uint16")==0) + else if (strcmp(typeString, "ushort") == 0 || strcmp(typeString, "uint16") == 0) return EF_R16_UINT; - else if (strcmp(typeString, "long")==0 || strcmp(typeString, "int")==0 || strcmp(typeString, "int16")==0) + else if (strcmp(typeString, "long") == 0 || strcmp(typeString, "int") == 0 || strcmp(typeString, "int16") == 0) return EF_R32_SINT; - else if (strcmp(typeString, "ulong")==0 || strcmp(typeString, "uint16")==0) + else if (strcmp(typeString, "ulong") == 0 || strcmp(typeString, "uint16") == 0) return EF_R32_UINT; - else if (strcmp(typeString, "float")==0 || strcmp(typeString, "float32")==0) + else if (strcmp(typeString, "uint") == 0 || strcmp(typeString, "uint32") == 0) + return EF_R32_UINT; + else if (strcmp(typeString, "float") == 0 || strcmp(typeString, "float32") == 0) return EF_R32_SFLOAT; - else if (strcmp(typeString, "double")==0 || strcmp(typeString, "float64")==0) + else if (strcmp(typeString, "double") == 0 || strcmp(typeString, "float64") == 0) return EF_R64_SFLOAT; else return EF_UNKNOWN; From 1f1fa068123d9597b0074064457c41493d80dc15 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 13 Aug 2025 22:08:06 +0200 Subject: [PATCH 29/32] write ply header --- src/nbl/asset/interchange/CPLYMeshWriter.cpp | 72 +++++++++----------- src/nbl/asset/interchange/CPLYMeshWriter.h | 4 +- 2 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.cpp b/src/nbl/asset/interchange/CPLYMeshWriter.cpp index a38444e2a3..108a191551 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.cpp +++ b/src/nbl/asset/interchange/CPLYMeshWriter.cpp @@ -63,47 +63,34 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ SAssetWriteContext inCtx{ _params, _file }; - const asset::ICPUPolygonGeometry* mesh = IAsset::castDown(_params.rootAsset); - if (!mesh) + const asset::ICPUPolygonGeometry* geom = IAsset::castDown(_params.rootAsset); + if (!geom) return false; - system::IFile* file = _override->getOutputFile(_file, inCtx, {mesh, 0u}); - if (!file || !mesh) + system::IFile* file = _override->getOutputFile(_file, inCtx, {geom, 0u}); + if (!file || !geom) return false; SContext context = { SAssetWriteContext{ inCtx.params, file} }; - context.writeContext.params.logger.log("Writing PLY mesh", system::ILogger::ELL_INFO, file->getFileName().string().c_str()); - - const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(context.writeContext, mesh, 0u); - - //auto getConvertedCpuMeshBufferWithIndexBuffer = [&]() -> core::smart_refctd_ptr - //{ - // auto inputMeshBuffer = *meshbuffers.begin(); - // const bool doesItHaveIndexBuffer = inputMeshBuffer->getIndexBufferBinding().buffer.get(); - // const bool isItNotTriangleListsPrimitive = inputMeshBuffer->getPipeline()->getCachedCreationParams().primitiveAssembly.primitiveType != asset::EPT_TRIANGLE_LIST; - // - // if (doesItHaveIndexBuffer && isItNotTriangleListsPrimitive) - // { - // auto cpuConvertedMeshBuffer = core::smart_refctd_ptr_static_cast(inputMeshBuffer->clone()); - // IMeshManipulator::homogenizePrimitiveTypeAndIndices(&cpuConvertedMeshBuffer, &cpuConvertedMeshBuffer + 1, asset::EPT_TRIANGLE_LIST, asset::EIT_32BIT); - // return cpuConvertedMeshBuffer; - // } - // else - // return nullptr; - //}; - - //const auto cpuConvertedMeshBufferWithIndexBuffer = getConvertedCpuMeshBufferWithIndexBuffer(); - //const asset::ICPUMeshBuffer* rawCopyMeshBuffer = cpuConvertedMeshBufferWithIndexBuffer.get() ? cpuConvertedMeshBufferWithIndexBuffer.get() : *meshbuffers.begin(); - //const bool doesItUseIndexBufferBinding = (rawCopyMeshBuffer->getIndexBufferBinding().buffer.get() && rawCopyMeshBuffer->getIndexType() != asset::EIT_UNKNOWN); - - const auto& idxView = mesh->getIndexView(); - const auto& vtxView = mesh->getPositionView(); - const auto& normalView = mesh->getNormalView(); - const auto& auxAttributes = mesh->getAuxAttributeViews(); - - // TODO: other cases - const size_t faceCount = mesh->getIndexCount() / 3; + context.writeContext.params.logger.log("Writing PLY file", system::ILogger::ELL_INFO, file->getFileName().string().c_str()); + + const asset::E_WRITER_FLAGS flags = _override->getAssetWritingFlags(context.writeContext, geom, 0u); + + const auto& idxView = geom->getIndexView(); + const auto& vtxView = geom->getPositionView(); + const auto& normalView = geom->getNormalView(); + const auto& auxAttributes = geom->getAuxAttributeViews(); + + // TODO: quads? + const size_t faceCount = geom->getIndexCount() / 3; + + // indices: + // 0 for vertices (always enabled) + // 1 for normals (optional) + // 2 for vertex colors (optional) + // 3 for texcoords (optional) + bool attrsToWrite[4] = { true, false, false, false }; // write PLY header std::string header = "ply\n"; @@ -122,6 +109,7 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ if (normalView.getElementCount() > 0) { + attrsToWrite[1] = true; std::string typeStr = getTypeString(normalView.composed.format); header += "property " + typeStr + " nx\n" + "property " + typeStr + " ny\n" + @@ -131,25 +119,29 @@ bool CPLYMeshWriter::writeAsset(system::IFile* _file, const SAssetWriteParams& _ header += "element face " + std::to_string(faceCount) + '\n'; header += "property list uchar " + getTypeString(idxView.composed.format) + " vertex_index\n"; - // TODO: Texcoords, vertex colors and any additional properties if (auxAttributes.size() > 0) for (auto& attr : auxAttributes) { - + // TODO: Texcoords, vertex colors and any additional properties } header += "end_header\n"; - { // TODO: remove that, added for testing purposes + { system::IFile::success_t success; context.writeContext.outputFile->write(success, header.data(), context.fileOffset, header.size()); context.fileOffset += success.getBytesProcessed(); } + if (flags & asset::EWF_BINARY) + writeBinary(geom, attrsToWrite, true, context); + else + writeText(geom, attrsToWrite, true, context); + return true; } -void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const +void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, const bool attrsToWrite[4], bool _forceFaces, SContext& context) const { #if 0 const size_t colCpa = asset::getFormatChannelCount(_mbuf->getAttribFormat(1)); @@ -241,7 +233,7 @@ void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCou #endif } -void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const +void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, const bool attrsToWrite[4], bool _forceFaces, SContext& context) const { #if 0 auto mbCopy = createCopyMBuffNormalizedReplacedWithTrueInt(_mbuf); diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.h b/src/nbl/asset/interchange/CPLYMeshWriter.h index e709ffa0fe..bd0533217d 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.h +++ b/src/nbl/asset/interchange/CPLYMeshWriter.h @@ -41,8 +41,8 @@ class CPLYMeshWriter : public IGeometryWriter size_t fileOffset = 0; }; - void writeBinary(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const; - void writeText(const ICPUPolygonGeometry* geom, size_t _vtxCount, size_t _fcCount, asset::E_INDEX_TYPE _idxType, void* const _indices, bool _forceFaces, const bool _vaidToWrite[4], SContext& context) const; + void writeBinary(const ICPUPolygonGeometry* geom, const bool attrsToWrite[4], bool _forceFaces, SContext& context) const; + void writeText(const ICPUPolygonGeometry* geom, const bool attrsToWrite[4], bool _forceFaces, SContext& context) const; void writeAttribBinary(SContext& context, ICPUPolygonGeometry* geom, uint32_t _vaid, size_t _ix, size_t _cpa, bool flipAttribute = false) const; From 1e438234791de886bd41ec1918ad37c9b2bb8c4e Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Wed, 13 Aug 2025 22:09:02 +0200 Subject: [PATCH 30/32] basic rewrite of ply text content writing function --- src/nbl/asset/interchange/CPLYMeshWriter.cpp | 143 +++---------------- src/nbl/asset/interchange/CPLYMeshWriter.h | 36 +++-- 2 files changed, 38 insertions(+), 141 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.cpp b/src/nbl/asset/interchange/CPLYMeshWriter.cpp index 108a191551..b4ceae479a 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.cpp +++ b/src/nbl/asset/interchange/CPLYMeshWriter.cpp @@ -235,132 +235,33 @@ void CPLYMeshWriter::writeBinary(const ICPUPolygonGeometry* geom, const bool att void CPLYMeshWriter::writeText(const ICPUPolygonGeometry* geom, const bool attrsToWrite[4], bool _forceFaces, SContext& context) const { -#if 0 - auto mbCopy = createCopyMBuffNormalizedReplacedWithTrueInt(_mbuf); + auto& posView = geom->getPositionView(); + auto& normalView = geom->getNormalView(); + auto& idxView = geom->getIndexView(); - auto writefunc = [&context, &mbCopy, this](uint32_t _vaid, size_t _ix, size_t _cpa) - { - bool flipVerteciesAndNormals = false; - if (!(context.writeContext.params.flags & E_WRITER_FLAGS::EWF_MESH_IS_RIGHT_HANDED)) - if(_vaid == 0u || _vaid == 3u) - flipVerteciesAndNormals = true; + std::span positions( + reinterpret_cast(posView.getPointer()), + reinterpret_cast(posView.getPointer(posView.getElementCount())) + ); - uint32_t ui[4]; - core::vectorSIMDf f; - const asset::E_FORMAT t = mbCopy->getAttribFormat(_vaid); - if (asset::isScaledFormat(t) || asset::isIntegerFormat(t)) - { - mbCopy->getAttribute(ui, _vaid, _ix); - if (!asset::isSignedFormat(t)) - writeVectorAsText(context, ui, _cpa, flipVerteciesAndNormals); - else - { - int32_t ii[4]; - memcpy(ii, ui, 4*4); - writeVectorAsText(context, ii, _cpa, flipVerteciesAndNormals); - } - } - else - { - mbCopy->getAttribute(f, _vaid, _ix); - writeVectorAsText(context, f.pointer, _cpa, flipVerteciesAndNormals); - } - }; + const auto* idxBegPtr = reinterpret_cast(idxView.getPointer()); + std::span indices(idxBegPtr, idxBegPtr + idxView.getElementCount()); - const size_t colCpa = asset::getFormatChannelCount(_mbuf->getAttribFormat(1)); + for (size_t i = 0; i < positions.size(); i++) + writeVertexAsText(context, positions[i], (attrsToWrite[1] ? reinterpret_cast(normalView.getPointer(i)) : nullptr)); - for (size_t i = 0u; i < _vtxCount; ++i) - { - core::vectorSIMDf f; - uint32_t ui[4]; - if (_vaidToWrite[0]) - { - writefunc(0, i, 3u); - } - if (_vaidToWrite[1]) - { - writefunc(1, i, colCpa); - } - if (_vaidToWrite[2]) - { - writefunc(2, i, 2u); - } - if (_vaidToWrite[3]) - { - writefunc(3, i, 3u); - } - - { - system::IFile::success_t success; - context.writeContext.outputFile->write(success, "\n", context.fileOffset, 1); - context.fileOffset += success.getBytesProcessed(); - } - } - - const char* listSize = "3 "; - void* indices = _indices; - if (_forceFaces) - { - indices = _NBL_ALIGNED_MALLOC((_idxType == asset::EIT_32BIT ? 4 : 2) * 3 * _fcCount,_NBL_SIMD_ALIGNMENT); - if (_idxType == asset::EIT_16BIT) - { - for (uint16_t i = 0u; i < _fcCount; ++i) - ((uint16_t*)indices)[i] = i; - } - else - { - for (uint32_t i = 0u; i < _fcCount; ++i) - ((uint32_t*)indices)[i] = i; - } - } - if (_idxType == asset::EIT_32BIT) - { - uint32_t* ind = (uint32_t*)indices; - for (size_t i = 0u; i < _fcCount; ++i) - { - { - system::IFile::success_t success; - context.writeContext.outputFile->write(success, listSize, context.fileOffset, 2); - context.fileOffset += success.getBytesProcessed(); - } - - writeVectorAsText(context, ind, 3); - - { - system::IFile::success_t success; - context.writeContext.outputFile->write(success, "\n", context.fileOffset, 1); - context.fileOffset += success.getBytesProcessed(); - } - - ind += 3; - } - } - else - { - uint16_t* ind = (uint16_t*)indices; - for (size_t i = 0u; i < _fcCount; ++i) - { - { - system::IFile::success_t success; - context.writeContext.outputFile->write(success, listSize, context.fileOffset, 2); - context.fileOffset += success.getBytesProcessed(); - } - - writeVectorAsText(context, ind, 3); - - { - system::IFile::success_t success; - context.writeContext.outputFile->write(success, "\n", context.fileOffset, 1); - context.fileOffset += success.getBytesProcessed(); - } - - ind += 3; - } - } + // write indices + for (size_t i = 0; i < indices.size(); i += 3) + { + std::string str = "3 "; + for (size_t j = 0; j < 3; j++) + str += std::to_string(indices[i + j]) + " "; + str += "\n"; - if (_forceFaces) - _NBL_ALIGNED_FREE(indices); -#endif + system::IFile::success_t success; + context.writeContext.outputFile->write(success, str.data(), context.fileOffset, str.size()); + context.fileOffset += success.getBytesProcessed(); + } } void CPLYMeshWriter::writeAttribBinary(SContext& context, ICPUPolygonGeometry* geom, uint32_t _vaid, size_t _ix, size_t _cpa, bool flipAttribute) const diff --git a/src/nbl/asset/interchange/CPLYMeshWriter.h b/src/nbl/asset/interchange/CPLYMeshWriter.h index bd0533217d..c099451858 100644 --- a/src/nbl/asset/interchange/CPLYMeshWriter.h +++ b/src/nbl/asset/interchange/CPLYMeshWriter.h @@ -51,27 +51,23 @@ class CPLYMeshWriter : public IGeometryWriter static std::string getTypeString(asset::E_FORMAT _t); - template - void writeVectorAsText(SContext& context, const T* _vec, size_t _elementsToWrite, bool flipVectors = false) const + inline void writeVertexAsText(SContext& context, const hlsl::float32_t3& pos, const hlsl::float32_t3* normal) const { - constexpr size_t xID = 0u; - std::stringstream ss; - ss << std::fixed; - bool currentFlipOnVariable = false; - for (size_t i = 0u; i < _elementsToWrite; ++i) - { - if (flipVectors && i == xID) - currentFlipOnVariable = true; - else - currentFlipOnVariable = false; - - ss << std::setprecision(6) << _vec[i] * (currentFlipOnVariable ? -1 : 1) << " "; - } - auto str = ss.str(); - - system::IFile::success_t succ; - context.writeContext.outputFile->write(succ, str.c_str(), context.fileOffset, str.size()); - context.fileOffset += succ.getBytesProcessed(); + std::stringstream ss; + ss << std::fixed << std::setprecision(6) << pos.x << " " << pos.y << " " << pos.z; + + if (normal) + { + ss << " " << normal->x << " " << normal->y << " " << normal->z << "\n"; + } + else + ss << "\n"; + + const auto& str = ss.str(); + + system::IFile::success_t success; + context.writeContext.outputFile->write(success, str.data(), context.fileOffset, str.size()); + context.fileOffset += success.getBytesProcessed(); } }; From 9b3ff7780f60d3420b6fc98c21bc786519ee45cd Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Sun, 24 Aug 2025 20:57:58 +0200 Subject: [PATCH 31/32] ensure that StartPointer <= LineEndPointer in the assertion before calling std::find_first_of --- src/nbl/asset/interchange/CPLYMeshFileLoader.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp index ffc1aa3eb1..35cc8c6b0b 100644 --- a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp @@ -242,7 +242,7 @@ struct SContext } // process the next word { - assert(LineEndPointer<=EndPointer); + assert(StartPointer <= LineEndPointer && LineEndPointer<=EndPointer); const std::array WhiteSpace = {'\0',' ','\t'}; auto wordEnd = std::find_first_of(StartPointer,LineEndPointer,WhiteSpace.begin(),WhiteSpace.end()); // null terminate the next word From bc9b3718fdc048c57851754b8d3574bb13970201 Mon Sep 17 00:00:00 2001 From: YasInvolved Date: Sun, 31 Aug 2025 15:05:32 +0200 Subject: [PATCH 32/32] make readVertex correctly process the vertices in ascii format --- src/nbl/asset/interchange/CPLYMeshFileLoader.cpp | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp index 35cc8c6b0b..3079ace0b8 100644 --- a/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp +++ b/src/nbl/asset/interchange/CPLYMeshFileLoader.cpp @@ -405,8 +405,18 @@ struct SContext encodePixels(it.dstFmt,it.ptr,&tmp); } } - else - getData(it.ptr,prop.type); + else if (IsBinaryFile) + getData(it.ptr, prop.type); + else if (isIntegerFormat(prop.type)) + { + const widest_int_t i = getInt(prop.type); + *reinterpret_cast(it.ptr) = i; + } + else if (isFloatingPointFormat(prop.type)) + { + hlsl::float32_t i = static_cast(getFloat(prop.type)); + *reinterpret_cast(it.ptr) = i; + } // it.ptr += it.stride; }