X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali-scene3d%2Finternal%2Fmodel-components%2Fmodel-node-impl.cpp;h=a37d4a8b278eda851f6625dbc7a55306ee83a152;hb=refs%2Fchanges%2F45%2F292445%2F12;hp=60dca00384f1aecc3a07d376c694020c7e1e631a;hpb=a015da201b3b8565c19df478476544c9ddd6911e;p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git diff --git a/dali-scene3d/internal/model-components/model-node-impl.cpp b/dali-scene3d/internal/model-components/model-node-impl.cpp index 60dca00..a37d4a8 100644 --- a/dali-scene3d/internal/model-components/model-node-impl.cpp +++ b/dali-scene3d/internal/model-components/model-node-impl.cpp @@ -20,9 +20,12 @@ // EXTERNAL INCLUDES #include +#include +#include // INTERNAL INCLUDES -#include +#include +#include namespace Dali { @@ -30,6 +33,21 @@ namespace Scene3D { namespace Internal { +namespace +{ +/** + * Creates control through type registry + */ +BaseHandle Create() +{ + return Scene3D::ModelNode::New(); +} + +// Setup properties, signals and actions using the type-registry. +DALI_TYPE_REGISTRATION_BEGIN(Scene3D::ModelNode, Dali::CustomActor, Create); +DALI_TYPE_REGISTRATION_END() +} // unnamed namespace + Dali::Scene3D::ModelNode ModelNode::New() { // Create the implementation, temporarily owned on stack @@ -46,8 +64,7 @@ Dali::Scene3D::ModelNode ModelNode::New() } ModelNode::ModelNode() -: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION), - mImpl(new Impl(*this)) +: CustomActorImpl(ActorFlags::DISABLE_SIZE_NEGOTIATION) { } @@ -58,6 +75,7 @@ ModelNode::~ModelNode() void ModelNode::Initialize() { OnInitialize(); + mLights.resize(Scene3D::Internal::Light::GetMaximumEnabledLightCount()); } void ModelNode::OnInitialize() @@ -66,12 +84,10 @@ void ModelNode::OnInitialize() void ModelNode::OnSceneConnection(int depth) { - mImpl->OnSceneConnection(depth); } void ModelNode::OnSceneDisconnection() { - mImpl->OnSceneDisconnection(); } void ModelNode::OnChildAdd(Actor& child) @@ -139,7 +155,7 @@ void ModelNode::OnLayoutNegotiated(float size, Dimension::Type dimension) ModelNode& GetImplementation(Dali::Scene3D::ModelNode& handle) { CustomActorImpl& customInterface = handle.GetImplementation(); - ModelNode& impl = dynamic_cast(customInterface); + ModelNode& impl = dynamic_cast(customInterface); return impl; } @@ -155,27 +171,107 @@ const ModelNode& GetImplementation(const Dali::Scene3D::ModelNode& handle) uint32_t ModelNode::GetModelPrimitiveCount() const { - return mImpl->GetModelPrimitiveCount(); + return static_cast(mModelPrimitiveContainer.size()); } void ModelNode::AddModelPrimitive(Dali::Scene3D::ModelPrimitive modelPrimitive) { - mImpl->AddModelPrimitive(modelPrimitive); + for(auto&& primitive : mModelPrimitiveContainer) + { + if(primitive == modelPrimitive) + { + return; + } + } + + mModelPrimitiveContainer.push_back(modelPrimitive); + + Actor self = Self(); + GetImplementation(modelPrimitive).AddPrimitiveObserver(this); + if(mDiffuseTexture && mSpecularTexture) + { + GetImplementation(modelPrimitive).SetImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels); + } + + uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount(); + for(uint32_t i = 0; i < maxLightCount; ++i) + { + if(mLights[i]) + { + GetImplementation(modelPrimitive).AddLight(mLights[i], i); + } + } + + Dali::Renderer renderer = GetImplementation(modelPrimitive).GetRenderer(); + if(renderer) + { + uint32_t rendererCount = self.GetRendererCount(); + bool exist = false; + for(uint32_t i = 0; i < rendererCount; ++i) + { + if(renderer == self.GetRendererAt(i)) + { + exist = true; + break; + } + } + if(!exist) + { + self.AddRenderer(renderer); + } + } } void ModelNode::RemoveModelPrimitive(Dali::Scene3D::ModelPrimitive modelPrimitive) { - mImpl->RemoveModelPrimitive(modelPrimitive); + uint32_t primitiveCount = GetModelPrimitiveCount(); + for(uint32_t i = 0; i < primitiveCount; ++i) + { + if(mModelPrimitiveContainer[i] != modelPrimitive) + { + continue; + } + + RemoveModelPrimitive(i); + break; + } } void ModelNode::RemoveModelPrimitive(uint32_t index) { - mImpl->RemoveModelPrimitive(index); + if(index >= mModelPrimitiveContainer.size()) + { + return; + } + + uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount(); + for(uint32_t i = 0; i < maxLightCount; ++i) + { + if(mLights[i]) + { + GetImplementation(mModelPrimitiveContainer[index]).RemoveLight(i); + } + } + + Actor self = Self(); + GetImplementation(mModelPrimitiveContainer[index]).RemovePrimitiveObserver(this); + + Dali::Renderer renderer = GetImplementation(mModelPrimitiveContainer[index]).GetRenderer(); + if(renderer) + { + self.RemoveRenderer(renderer); + } + + mModelPrimitiveContainer.erase(mModelPrimitiveContainer.begin() + index); } Dali::Scene3D::ModelPrimitive ModelNode::GetModelPrimitive(uint32_t index) const { - return mImpl->GetModelPrimitive(index); + if(index < mModelPrimitiveContainer.size()) + { + return mModelPrimitiveContainer[index]; + } + return Scene3D::ModelPrimitive(); } Scene3D::ModelNode ModelNode::FindChildModelNodeByName(std::string_view nodeName) @@ -184,24 +280,136 @@ Scene3D::ModelNode ModelNode::FindChildModelNodeByName(std::string_view nodeName return Scene3D::ModelNode::DownCast(childActor); } +void ModelNode::RetrieveBlendShapeNames(std::vector& blendShapeNames) const +{ + blendShapeNames.reserve(blendShapeNames.size() + mBlendShapeIndexMap.size()); + for(const auto& iter : mBlendShapeIndexMap) + { + blendShapeNames.push_back(iter.first); + } +} + +Loader::BlendShapes::Index ModelNode::GetBlendShapeIndexByName(std::string_view blendShapeName) const +{ + auto iter = mBlendShapeIndexMap.find(std::string(blendShapeName)); + if(iter != mBlendShapeIndexMap.end()) + { + return iter->second; + } + return Loader::BlendShapes::INVALID_INDEX; +} + void ModelNode::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float iblScaleFactor, uint32_t specularMipmapLevels) { - mImpl->SetImageBasedLightTexture(diffuseTexture, specularTexture, iblScaleFactor, specularMipmapLevels); + mDiffuseTexture = diffuseTexture; + mSpecularTexture = specularTexture; + mIblScaleFactor = iblScaleFactor; + mSpecularMipmapLevels = specularMipmapLevels; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).SetImageBasedLightTexture(diffuseTexture, specularTexture, iblScaleFactor, specularMipmapLevels); + } } void ModelNode::SetImageBasedLightScaleFactor(float iblScaleFactor) { - mImpl->SetImageBasedLightScaleFactor(iblScaleFactor); + mIblScaleFactor = iblScaleFactor; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).SetImageBasedLightScaleFactor(iblScaleFactor); + } +} + +void ModelNode::AddLight(Scene3D::Light light, uint32_t lightIndex) +{ + mLights[lightIndex] = light; + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).AddLight(light, lightIndex); + } +} + +void ModelNode::RemoveLight(uint32_t lightIndex) +{ + for(auto&& primitive : mModelPrimitiveContainer) + { + GetImplementation(primitive).RemoveLight(lightIndex); + } + mLights[lightIndex].Reset(); } void ModelNode::SetBlendShapeData(Scene3D::Loader::BlendShapes::BlendShapeData& data, Scene3D::ModelPrimitive primitive) { - mImpl->SetBlendShapeData(data, primitive); + // Update mBlendShapeIndexMap + mBlendShapeIndexMap.clear(); + const auto blendShapeCount = data.names.size(); + for(Loader::BlendShapes::Index index = 0u; index < blendShapeCount; ++index) + { + auto& name = data.names[index]; + if(!name.empty()) + { + mBlendShapeIndexMap[name] = index; + } + } + + GetImplementation(primitive).SetBlendShapeData(data); } void ModelNode::SetBoneMatrix(const Matrix& inverseMatrix, Scene3D::ModelPrimitive primitive, Scene3D::Loader::Index& boneIndex) { - mImpl->SetBoneMatrix(inverseMatrix, primitive, boneIndex); + Dali::Scene3D::Loader::Skinning::BoneData boneData; + boneData.primitive = primitive; + boneData.boneIndex = boneIndex; + char propertyNameBuffer[32]; + snprintf(propertyNameBuffer, sizeof(propertyNameBuffer), "%s[%d]", Dali::Scene3D::Loader::Skinning::BONE_UNIFORM_NAME, boneIndex); + boneData.propertyName = propertyNameBuffer; + boneData.inverseMatrix = inverseMatrix; + mBoneDataContainer.push_back(std::move(boneData)); + + UpdateBoneMatrix(primitive); +} + +void ModelNode::OnRendererCreated(Renderer renderer) +{ + Self().AddRenderer(renderer); +} + +void ModelNode::UpdateBoneMatrix(Scene3D::ModelPrimitive primitive) +{ + for(auto&& boneData : mBoneDataContainer) + { + if(boneData.primitive != primitive) + { + continue; + } + + Dali::Renderer renderer = GetImplementation(primitive).GetRenderer(); + if(!renderer) + { + continue; + } + + if(boneData.constraint) + { + boneData.constraint.Remove(); + boneData.constraint.Reset(); + } + + auto propBoneXform = renderer.GetPropertyIndex(boneData.propertyName); + if(propBoneXform == Property::INVALID_INDEX) + { + propBoneXform = renderer.RegisterProperty(boneData.propertyName, Matrix{false}); + } + + 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(); + break; + } } } // namespace Internal