From 963c6afad45fd6a64d6e3cd5063796eaa7d3c41a Mon Sep 17 00:00:00 2001 From: Eunki Hong Date: Sat, 18 Feb 2023 19:22:52 +0900 Subject: [PATCH] Allow to load uint32_t as indices Dali's default indices use uint16_t. But if heavy 3D model who need more than 65536 indexes loaded, It will break index. This patch make Scene3D can allow to use uint32_t type indeces load and generete Geometry by it. Change-Id: I6b8096df3fcf855443e6b407342121b9374d9ff8 Signed-off-by: Eunki Hong --- automated-tests/resources/EnvironmentTest.gltf | 1 - .../roughness_metallic_0.jpg | Bin 0 -> 8661 bytes .../roughness_metallic_1.jpg | Bin 0 -> 8685 bytes dali-scene3d/public-api/loader/mesh-definition.cpp | 129 ++++++++++++++------- 4 files changed, 86 insertions(+), 44 deletions(-) create mode 100644 automated-tests/resources/EnvironmentTest_images/roughness_metallic_0.jpg create mode 100644 automated-tests/resources/EnvironmentTest_images/roughness_metallic_1.jpg diff --git a/automated-tests/resources/EnvironmentTest.gltf b/automated-tests/resources/EnvironmentTest.gltf index 962e475..b9d85b3 100644 --- a/automated-tests/resources/EnvironmentTest.gltf +++ b/automated-tests/resources/EnvironmentTest.gltf @@ -178,7 +178,6 @@ { "attributes": { "POSITION": 0, - "NORMAL": 1, "TEXCOORD_0": 2 }, "indices": 3, diff --git a/automated-tests/resources/EnvironmentTest_images/roughness_metallic_0.jpg b/automated-tests/resources/EnvironmentTest_images/roughness_metallic_0.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8ba03d3704067c11b15e3daef1da7a228a143c50 GIT binary patch literal 8661 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 NU-Fa&Bu{DR{{X2kGd=(S literal 0 HcmV?d00001 diff --git a/automated-tests/resources/EnvironmentTest_images/roughness_metallic_1.jpg b/automated-tests/resources/EnvironmentTest_images/roughness_metallic_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..d69561883de7edfff6b1a3fb3a3b1e771273c7a7 GIT binary patch literal 8685 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 U9_hsDl}@Za>BQ=nPOQOy1B9kY761SM literal 0 HcmV?d00001 diff --git a/dali-scene3d/public-api/loader/mesh-definition.cpp b/dali-scene3d/public-api/loader/mesh-definition.cpp index b23140f..18093a5 100644 --- a/dali-scene3d/public-api/loader/mesh-definition.cpp +++ b/dali-scene3d/public-api/loader/mesh-definition.cpp @@ -35,36 +35,39 @@ namespace Loader { namespace { +template class IndexProvider { public: + using IndexType = typename std::conditional_t; IndexProvider(const uint16_t* indices) : mData(reinterpret_cast(indices)), mFunc(indices ? IncrementPointer : Increment) { } - uint16_t operator()() + IndexType operator()() { return mFunc(mData); } private: - static uint16_t Increment(uintptr_t& data) + static IndexType Increment(uintptr_t& data) { - return static_cast(data++); + // mData was 'zero' at construct time. Just simply return counter start with 0. + return static_cast(data++); } - static uint16_t IncrementPointer(uintptr_t& data) + static IndexType IncrementPointer(uintptr_t& data) { - auto iPtr = reinterpret_cast(data); + auto iPtr = reinterpret_cast(data); auto result = *iPtr; data = reinterpret_cast(++iPtr); return result; } uintptr_t mData; - uint16_t (*mFunc)(uintptr_t&); + IndexType (*mFunc)(uintptr_t&); }; const char* QUAD("quad"); @@ -212,13 +215,23 @@ void ReadJointAccessor(MeshDefinition::RawData& raw, const MeshDefinition::Acces raw.mAttribs.push_back({"aJoints", Property::VECTOR4, static_cast(outBufferSize / sizeof(Vector4)), std::move(buffer)}); } -void GenerateNormals(MeshDefinition::RawData& raw) +template> +bool GenerateNormals(MeshDefinition::RawData& raw) { + using IndexType = typename IndexProviderType::IndexType; + + // mIndicies size must be even if we use 32bit indices. + if(DALI_UNLIKELY(use32BitsIndices && !raw.mIndices.empty() && !(raw.mIndices.size() % (sizeof(IndexType) / sizeof(uint16_t)) == 0))) + { + return false; + } + auto& attribs = raw.mAttribs; DALI_ASSERT_DEBUG(attribs.size() > 0); // positions - IndexProvider getIndex(raw.mIndices.data()); - const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : static_cast(raw.mIndices.size()); + IndexProviderType getIndex(raw.mIndices.data()); + + const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : static_cast(raw.mIndices.size() / (sizeof(IndexType) / sizeof(uint16_t))); auto* positions = reinterpret_cast(attribs[0].mData.data()); @@ -227,8 +240,8 @@ void GenerateNormals(MeshDefinition::RawData& raw) for(uint32_t i = 0; i < numIndices; i += 3) { - uint16_t indices[]{getIndex(), getIndex(), getIndex()}; - Vector3 pos[]{positions[indices[0]], positions[indices[1]], positions[indices[2]]}; + IndexType indices[]{getIndex(), getIndex(), getIndex()}; + Vector3 pos[]{positions[indices[0]], positions[indices[1]], positions[indices[2]]}; Vector3 a = pos[1] - pos[0]; Vector3 b = pos[2] - pos[0]; @@ -247,14 +260,24 @@ void GenerateNormals(MeshDefinition::RawData& raw) } attribs.push_back({"aNormal", Property::VECTOR3, attribs[0].mNumElements, std::move(buffer)}); + + return true; } -template, typename = std::enable_if_t<(std::is_same::value || std::is_same::value)>> +template, typename = std::enable_if_t<(std::is_same::value || std::is_same::value)>, typename IndexProviderType = IndexProvider> bool GenerateTangents(MeshDefinition::RawData& raw) { + using IndexType = typename IndexProviderType::IndexType; + + // mIndicies size must be even if we use 32bit indices. + if(DALI_UNLIKELY(use32BitsIndices && !raw.mIndices.empty() && !(raw.mIndices.size() % (sizeof(IndexType) / sizeof(uint16_t)) == 0))) + { + return false; + } + auto& attribs = raw.mAttribs; // Required positions, normals, uvs (if we have). If not, skip generation - if(attribs.size() < (2 + static_cast(hasUvs))) + if(DALI_UNLIKELY(attribs.size() < (2 + static_cast(hasUvs)))) { return false; } @@ -264,17 +287,18 @@ bool GenerateTangents(MeshDefinition::RawData& raw) if constexpr(hasUvs) { - IndexProvider getIndex(raw.mIndices.data()); - const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : static_cast(raw.mIndices.size()); + IndexProviderType getIndex(raw.mIndices.data()); + + const uint32_t numIndices = raw.mIndices.empty() ? attribs[0].mNumElements : static_cast(raw.mIndices.size() / (sizeof(IndexType) / sizeof(uint16_t))); auto* positions = reinterpret_cast(attribs[0].mData.data()); auto* uvs = reinterpret_cast(attribs[2].mData.data()); for(uint32_t i = 0; i < numIndices; i += 3) { - uint16_t indices[]{getIndex(), getIndex(), getIndex()}; - Vector3 pos[]{positions[indices[0]], positions[indices[1]], positions[indices[2]]}; - Vector2 uv[]{uvs[indices[0]], uvs[indices[1]], uvs[indices[2]]}; + IndexType indices[]{getIndex(), getIndex(), getIndex()}; + Vector3 pos[]{positions[indices[0]], positions[indices[1]], positions[indices[2]]}; + Vector2 uv[]{uvs[indices[0]], uvs[indices[1]], uvs[indices[2]]}; float x0 = pos[1].x - pos[0].x; float y0 = pos[1].y - pos[0].y; @@ -670,18 +694,6 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& { ExceptionFlinger(ASSERT_LOCATION) << "Failed to read indices from '" << path << "'."; } - - auto u16s = raw.mIndices.data(); - auto u32s = reinterpret_cast(raw.mIndices.data()); - auto end = u32s + indexCount; - while(u32s != end) - { - *u16s = static_cast(*u32s); - ++u16s; - ++u32s; - } - - raw.mIndices.resize(indexCount); } else if(MaskMatch(mFlags, U8_INDICES)) { @@ -689,7 +701,7 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& mIndices.mBlob.mStride >= sizeof(uint8_t)) && "Index buffer length not a multiple of element size"); const auto indexCount = mIndices.mBlob.GetBufferSize() / sizeof(uint8_t); - raw.mIndices.resize(indexCount); // NOTE: we need space for uint32_ts initially. + raw.mIndices.resize(indexCount); // NOTE: we need space for uint16_ts initially. std::string path; auto u8s = reinterpret_cast(raw.mIndices.data()) + indexCount; @@ -783,8 +795,20 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& else if(mNormals.mBlob.mLength != 0 && isTriangles) { DALI_ASSERT_DEBUG(mNormals.mBlob.mLength == mPositions.mBlob.GetBufferSize()); - GenerateNormals(raw); - hasNormals = true; + static const std::function GenerateNormalsFunction[2] = + { + GenerateNormals, + GenerateNormals, + }; + const bool generateSuccessed = GenerateNormalsFunction[MaskMatch(mFlags, U32_INDICES)](raw); + if(!generateSuccessed) + { + DALI_LOG_ERROR("Failed to generate normal\n"); + } + else + { + hasNormals = true; + } } const auto hasUvs = mTexCoords.IsDefined(); @@ -815,7 +839,7 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& } } - mTexCoords.mBlob.ApplyMinMax(static_cast(bufferSize / sizeof(Vector2)), reinterpret_cast(buffer.data())); + mTexCoords.mBlob.ApplyMinMax(static_cast(uvCount), reinterpret_cast(buffer.data())); raw.mAttribs.push_back({"aTexCoord", Property::VECTOR2, static_cast(uvCount), std::move(buffer)}); } @@ -842,18 +866,29 @@ MeshDefinition::LoadRaw(const std::string& modelsPath, BufferDefinition::Vector& else if(mTangents.mBlob.mLength != 0 && hasNormals && isTriangles) { DALI_ASSERT_DEBUG(mTangents.mBlob.mLength == mNormals.mBlob.GetBufferSize()); - static const std::function GenerateTangentsFunction[2][2] = + static const std::function GenerateTangentsFunction[2][2][2] = { { - GenerateTangents, - GenerateTangents, + { + GenerateTangents, + GenerateTangents, + }, + { + GenerateTangents, + GenerateTangents, + }, }, { - GenerateTangents, - GenerateTangents, - }, - }; - const bool generateSuccessed = GenerateTangentsFunction[mTangentType == Property::VECTOR3][hasUvs](raw); + { + GenerateTangents, + GenerateTangents, + }, + { + GenerateTangents, + GenerateTangents, + }, + }}; + const bool generateSuccessed = GenerateTangentsFunction[MaskMatch(mFlags, U32_INDICES)][mTangentType == Property::VECTOR3][hasUvs](raw); if(!generateSuccessed) { DALI_LOG_ERROR("Failed to generate tangents\n"); @@ -1008,7 +1043,15 @@ MeshGeometry MeshDefinition::Load(RawData&& raw) const { if(!raw.mIndices.empty()) { - meshGeometry.geometry.SetIndexBuffer(raw.mIndices.data(), raw.mIndices.size()); + if(MaskMatch(mFlags, U32_INDICES)) + { + // TODO : We can only store indeces as uint16_type. Send Dali::Geometry that we use it as uint32_t actual. + meshGeometry.geometry.SetIndexBuffer(reinterpret_cast(raw.mIndices.data()), raw.mIndices.size() / 2); + } + else + { + meshGeometry.geometry.SetIndexBuffer(raw.mIndices.data(), raw.mIndices.size()); + } } for(auto& a : raw.mAttribs) -- 2.7.4