From: Eunki, Hong Date: Thu, 4 May 2023 08:03:01 +0000 (+0900) Subject: Fix multiple primitive skinning error X-Git-Tag: dali_2.2.26~2 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=10bba66be366a12150b1a8b3c00aa60b3631826f Fix multiple primitive skinning error Since we didn't check indivisual primitive with same shader + same skeletone id, some renderer didn't applied Constraint. Now we make multiple primitive also apply bone constraints Change-Id: I7ccf7257108f9e4d05914c70bb437eee488b7b3f Signed-off-by: Eunki, Hong --- diff --git a/dali-scene3d/internal/model-components/model-node-impl.cpp b/dali-scene3d/internal/model-components/model-node-impl.cpp index 257cbd0..54db4bc 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.cpp +++ b/dali-scene3d/internal/model-components/model-node-impl.cpp @@ -319,31 +319,26 @@ void ModelNode::UpdateBoneMatrix(Scene3D::ModelPrimitive primitive) continue; } - Dali::Shader shader = renderer.GetShader(); - if(!shader) - { - continue; - } - if(boneData.constraint) { boneData.constraint.Remove(); boneData.constraint.Reset(); } - if(shader.GetPropertyIndex(boneData.propertyName) == Property::INVALID_INDEX) + auto propBoneXform = renderer.GetPropertyIndex(boneData.propertyName); + if(propBoneXform == Property::INVALID_INDEX) { - auto propBoneXform = shader.RegisterProperty(boneData.propertyName, Matrix{false}); + propBoneXform = renderer.RegisterProperty(boneData.propertyName, Matrix{false}); + } - Matrix inverseMatrix = boneData.inverseMatrix; - // Constrain bone matrix to joint transform. - boneData.constraint = Constraint::New(shader, propBoneXform, [inverseMatrix](Matrix& output, const PropertyInputContainer& inputs) - { Matrix::Multiply(output, inverseMatrix, inputs[0]->GetMatrix()); }); + Matrix inverseMatrix = boneData.inverseMatrix; + // Constrain bone matrix to joint transform. + boneData.constraint = Constraint::New(renderer, propBoneXform, [inverseMatrix](Matrix& output, const PropertyInputContainer& inputs) + { Matrix::Multiply(output, inverseMatrix, inputs[0]->GetMatrix()); }); - Actor joint = Self(); - boneData.constraint.AddSource(Source{joint, Actor::Property::WORLD_MATRIX}); - boneData.constraint.ApplyPost(); - } + Actor joint = Self(); + boneData.constraint.AddSource(Source{joint, Actor::Property::WORLD_MATRIX}); + boneData.constraint.ApplyPost(); break; } } diff --git a/dali-scene3d/public-api/loader/node-definition.cpp b/dali-scene3d/public-api/loader/node-definition.cpp index a8632e9..c00a87b 100644 --- a/dali-scene3d/public-api/loader/node-definition.cpp +++ b/dali-scene3d/public-api/loader/node-definition.cpp @@ -283,10 +283,10 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit { mesh.first.mModelPrimitive = ModelPrimitive::New(); - auto primitive = mesh.first.mModelPrimitive; + auto primitive = mesh.first.mModelPrimitive; GetImplementation(primitive).SetRenderer(renderer); - Index envIndex = resources.mMaterials[mMaterialIdx].first.mEnvironmentIdx; + Index envIndex = resources.mMaterials[mMaterialIdx].first.mEnvironmentIdx; uint32_t specularMipmap = resources.mEnvironmentMaps[envIndex].second.mSpecularMipmapLevels; GetImplementation(primitive).SetImageBasedLightTexture(resources.mEnvironmentMaps[envIndex].second.mDiffuse, resources.mEnvironmentMaps[envIndex].second.mSpecular, @@ -335,7 +335,7 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit renderer.RegisterProperty("uMask", mask); renderer.RegisterProperty("uAlphaThreshold", alphaCutoff); - Index envIndex = matDef.mEnvironmentIdx; + Index envIndex = matDef.mEnvironmentIdx; uint32_t specularMipmap = resources.mEnvironmentMaps[envIndex].second.mSpecularMipmapLevels; renderer.RegisterProperty(IBL_MAXLOD.data(), static_cast(specularMipmap)); renderer.RegisterProperty(IBL_INTENSITY_STRING.data(), resources.mEnvironmentMaps[envIndex].first.mIblIntensity); @@ -344,8 +344,8 @@ void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinit node.SetProperty(Actor::Property::COLOR, mColor); { - matDef.mMaterial = Material::New(); - auto material = matDef.mMaterial; + matDef.mMaterial = Material::New(); + auto material = matDef.mMaterial; uint32_t textureIndexOffset = (mesh.second.blendShapeGeometry) ? 1 : 0; uint32_t textureIndex = 0; for(uint32_t i = 0; i < MAX_NUMBER_OF_MATERIAL_TEXTURE; ++i) diff --git a/dali-scene3d/public-api/loader/node-definition.h b/dali-scene3d/public-api/loader/node-definition.h index 9b73271..02d056f 100644 --- a/dali-scene3d/public-api/loader/node-definition.h +++ b/dali-scene3d/public-api/loader/node-definition.h @@ -108,7 +108,7 @@ struct DALI_SCENE3D_API SkinningShaderConfigurationRequest bool operator<(const SkinningShaderConfigurationRequest& other) const { - return mShader < other.mShader; + return mShader < other.mShader || (mShader == other.mShader && mPrimitive < other.mPrimitive); } }; @@ -124,7 +124,7 @@ struct DALI_SCENE3D_API BlendshapeShaderConfigurationRequest bool operator<(const BlendshapeShaderConfigurationRequest& other) const { - return mShader < other.mShader; + return mShader < other.mShader || (mShader == other.mShader && mPrimitive < other.mPrimitive); } }; diff --git a/dali-scene3d/public-api/loader/scene-definition.cpp b/dali-scene3d/public-api/loader/scene-definition.cpp index b1617de..10f6866 100644 --- a/dali-scene3d/public-api/loader/scene-definition.cpp +++ b/dali-scene3d/public-api/loader/scene-definition.cpp @@ -44,21 +44,16 @@ namespace Dali::Scene3D::Loader { namespace { - const std::map& GetConstraintFactory() { static const std::map sConstraintFactory = { {Property::Type::BOOLEAN, [](Actor& a, Property::Index i) { - return Constraint::New(a, i, [](bool& current, const PropertyInputContainer& inputs) { - current = inputs[0]->GetBoolean(); - }); + return Constraint::New(a, i, [](bool& current, const PropertyInputContainer& inputs) { current = inputs[0]->GetBoolean(); }); }}, {Property::Type::INTEGER, [](Actor& a, Property::Index i) { - return Constraint::New(a, i, [](int& current, const PropertyInputContainer& inputs) { - current = inputs[0]->GetInteger(); - }); + return Constraint::New(a, i, [](int& current, const PropertyInputContainer& inputs) { current = inputs[0]->GetInteger(); }); }}, {Property::Type::FLOAT, [](Actor& a, Property::Index i) { @@ -203,47 +198,43 @@ public: private: NodeDefinition::CreateParams& mCreationContext; - std::vector mActorStack; - ModelNode mRoot; + std::vector mActorStack; + ModelNode mRoot; }; -void SortAndDeduplicateSkinningRequests(std::vector& requests) +template +void SortAndDeduplicateRequests(std::vector& requests) { - // Sort requests by shaders. + // Sort requests by shaders and primitives. std::sort(requests.begin(), requests.end()); // Remove duplicates. - auto i = requests.begin(); - auto iEnd = requests.end(); - Shader s = i->mShader; - Index skeletonIdx = i->mSkeletonIdx; - ++i; + auto iter = requests.begin(); + auto iterEnd = requests.end(); + + Shader shader = iter->mShader; + ModelPrimitive modelPrimitive = iter->mPrimitive; + ++iter; do { - // Multiple identical shader instances are removed. - while(i != iEnd && i->mShader == s) + // Multiple identical shader and primitive instances are removed. + while(iter != iterEnd && iter->mShader == shader && iter->mPrimitive == modelPrimitive) { - // Cannot have multiple skeletons input to the same shader. - // NOTE: DliModel now makes sure this doesn't happen. - DALI_ASSERT_ALWAYS(i->mSkeletonIdx == skeletonIdx && - "Skinning shader must not be shared between different skeletons."); - - i->mShader = Shader(); - ++i; + // Mark as removed + iter->mShader = Shader(); + ++iter; } - if(i == iEnd) + if(iter == iterEnd) { break; } - s = i->mShader; - skeletonIdx = i->mSkeletonIdx; - ++i; + shader = iter->mShader; + modelPrimitive = iter->mPrimitive; + ++iter; } while(true); - requests.erase(std::remove_if(requests.begin(), requests.end(), [](const SkinningShaderConfigurationRequest& sscr) { - return !sscr.mShader; - }), + requests.erase(std::remove_if(requests.begin(), requests.end(), [](const RequestType& sscr) { return !sscr.mShader; }), requests.end()); } @@ -628,9 +619,7 @@ NodeDefinition* SceneDefinition::FindNode(const std::string& name, Index* outInd { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { - return nd->mName == name; - }); + auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { return nd->mName == name; }); auto result = iFind != iEnd ? iFind->get() : nullptr; if(result && outIndex) @@ -644,9 +633,7 @@ const NodeDefinition* SceneDefinition::FindNode(const std::string& name, Index* { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { - return nd->mName == name; - }); + auto iFind = std::find_if(iBegin, iEnd, [&name](const std::unique_ptr& nd) { return nd->mName == name; }); auto result = iFind != iEnd ? iFind->get() : nullptr; if(result && outIndex) @@ -660,9 +647,7 @@ Index SceneDefinition::FindNodeIndex(const NodeDefinition& node) const { auto iBegin = mNodes.begin(); auto iEnd = mNodes.end(); - auto iFind = std::find_if(iBegin, iEnd, [&node](const std::unique_ptr& n) { - return n.get() == &node; - }); + auto iFind = std::find_if(iBegin, iEnd, [&node](const std::unique_ptr& n) { return n.get() == &node; }); return iFind != iEnd ? std::distance(iBegin, iFind) : INVALID_INDEX; } @@ -814,7 +799,7 @@ void SceneDefinition::ConfigureSkinningShaders(const ResourceBundle& return; } - SortAndDeduplicateSkinningRequests(requests); + SortAndDeduplicateRequests(requests); for(auto& request : requests) { @@ -828,7 +813,7 @@ void SceneDefinition::ConfigureSkinningShaders(const ResourceBundle& Index boneIdx = 0; for(auto& joint : skeleton.mJoints) { - auto node = GetNode(joint.mNodeIdx); + auto node = GetNode(joint.mNodeIdx); ModelNode modelNode = ModelNode::DownCast(rootActor.FindChildByName(node->mName)); if(!modelNode) { @@ -849,47 +834,24 @@ bool SceneDefinition::ConfigureBlendshapeShaders(const ResourceBundle& return true; } - // Sort requests by shaders. - std::sort(requests.begin(), requests.end()); - - // Remove duplicates. - auto i = requests.begin(); - auto iEnd = requests.end(); - Shader s = i->mShader; - ++i; - do - { - // Multiple identical shader instances are removed. - while(i != iEnd && i->mShader == s) - { - i->mShader = Shader(); - ++i; - } - - if(i == iEnd) - { - break; - } - s = i->mShader; - ++i; - } while(true); + SortAndDeduplicateRequests(requests); // Configure the rest. bool ok = true; - for(auto& i : requests) + for(auto& request : requests) { Index iNode; - if(FindNode(i.mNodeName, &iNode)) + if(FindNode(request.mNodeName, &iNode)) { const auto& node = GetNode(iNode); - const auto& mesh = resources.mMeshes[i.mMeshIdx]; + const auto& mesh = resources.mMeshes[request.mMeshIdx]; if(mesh.first.HasBlendShapes()) { - Actor actor = rootActor.FindChildByName(node->mName); - Scene3D::ModelNode node = Scene3D::ModelNode::DownCast(actor); + Actor actor = rootActor.FindChildByName(node->mName); + Scene3D::ModelNode node = Scene3D::ModelNode::DownCast(actor); if(!node) { continue; @@ -906,10 +868,10 @@ bool SceneDefinition::ConfigureBlendshapeShaders(const ResourceBundle& { data.unnormalizeFactors.push_back(factor); } - data.version = mesh.first.mBlendShapeVersion; + data.version = mesh.first.mBlendShapeVersion; data.bufferOffset = mesh.second.blendShapeBufferOffset; - data.mActor = actor; - Internal::GetImplementation(node).SetBlendShapeData(data, i.mPrimitive); + data.mActor = actor; + Internal::GetImplementation(node).SetBlendShapeData(data, request.mPrimitive); } } } @@ -975,9 +937,8 @@ bool SceneDefinition::FindNode(const std::string& name, std::unique_ptr& nd) { - return nd->mName == name; - }).base(); + auto iFind = std::find_if(mNodes.rbegin(), mNodes.rend(), [&name](const std::unique_ptr& nd) { return nd->mName == name; }) + .base(); const bool success = iFind != mNodes.begin(); if(success && result)