#include <dali-scene3d/public-api/loader/load-result.h>
#include <dali-scene3d/public-api/loader/node-definition.h>
#include <dali-scene3d/public-api/loader/scene-definition.h>
-#include <dali-scene3d/public-api/loader/shader-definition-factory.h>
+#include <dali-scene3d/public-api/loader/shader-manager.h>
#include <dali-scene3d/public-api/model-motion/motion-index/blend-shape-index.h>
using namespace Dali;
}
}
-void AddLightRecursively(Scene3D::ModelNode node, Scene3D::Light light, uint32_t lightIndex)
+void UpdateBlendShapeNodeMapRecursively(Model::BlendShapeModelNodeMap& resultMap, const Scene3D::ModelNode& node)
{
if(!node)
{
return;
}
- GetImplementation(node).AddLight(light, lightIndex);
+ const auto childCount = node.GetChildCount();
+ for(auto i = 0u; i < childCount; ++i)
+ {
+ UpdateBlendShapeNodeMapRecursively(resultMap, Scene3D::ModelNode::DownCast(node.GetChildAt(i)));
+ }
- uint32_t childrenCount = node.GetChildCount();
- for(uint32_t i = 0; i < childrenCount; ++i)
+ std::vector<std::string> blendShapeNames;
+ node.RetrieveBlendShapeNames(blendShapeNames);
+ for(const auto& iter : blendShapeNames)
{
- Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i));
- if(childNode)
- {
- AddLightRecursively(childNode, light, lightIndex);
- }
+ // Append or create new list.
+ resultMap[iter].push_back(node);
}
}
-void RemoveLightRecursively(Scene3D::ModelNode node, uint32_t lightIndex)
+void UpdateShaderRecursively(Scene3D::ModelNode node, Scene3D::Loader::ShaderManagerPtr shaderManager)
{
if(!node)
{
return;
}
- GetImplementation(node).RemoveLight(lightIndex);
+ GetImplementation(node).UpdateShader(shaderManager);
uint32_t childrenCount = node.GetChildCount();
for(uint32_t i = 0; i < childrenCount; ++i)
Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i));
if(childNode)
{
- RemoveLightRecursively(childNode, lightIndex);
+ UpdateShaderRecursively(childNode, shaderManager);
}
}
}
-void UpdateBlendShapeNodeMapRecursively(Model::BlendShapeModelNodeMap& resultMap, const Scene3D::ModelNode& node)
+void UpdateShadowMapTextureRecursively(Scene3D::ModelNode node, Dali::Texture shadowMapTexture)
{
if(!node)
{
return;
}
- const auto childCount = node.GetChildCount();
- for(auto i = 0u; i < childCount; ++i)
- {
- UpdateBlendShapeNodeMapRecursively(resultMap, Scene3D::ModelNode::DownCast(node.GetChildAt(i)));
- }
- std::vector<std::string> blendShapeNames;
- node.RetrieveBlendShapeNames(blendShapeNames);
- for(const auto& iter : blendShapeNames)
+ GetImplementation(node).SetShadowMapTexture(shadowMapTexture);
+
+ uint32_t childrenCount = node.GetChildCount();
+ for(uint32_t i = 0; i < childrenCount; ++i)
{
- // Append or create new list.
- resultMap[iter].push_back(node);
+ Scene3D::ModelNode childNode = Scene3D::ModelNode::DownCast(node.GetChildAt(i));
+ if(childNode)
+ {
+ UpdateShadowMapTextureRecursively(childNode, shadowMapTexture);
+ }
}
}
mModelUrl(modelUrl),
mResourceDirectoryUrl(resourceDirectoryUrl),
mModelRoot(),
+ mShaderManager(new Scene3D::Loader::ShaderManager()),
mNaturalSize(Vector3::ZERO),
mModelPivot(AnchorPoint::CENTER),
mSceneIblScaleFactor(1.0f),
mModelResourceReady = true;
}
- if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
+ UpdateShaderRecursively(modelNode, mShaderManager);
+
+ if(mShadowMapTexture)
{
- UpdateImageBasedLightTexture();
- UpdateImageBasedLightScaleFactor();
+ UpdateShadowMapTextureRecursively(modelNode, mShadowMapTexture);
}
- uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount();
- for(uint32_t i = 0; i < maxLightCount; ++i)
+ if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
{
- if(mLights[i])
- {
- AddLightRecursively(modelNode, mLights[i], i);
- }
+ UpdateImageBasedLightTexture();
+ UpdateImageBasedLightScaleFactor();
}
if(Self().GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE))
{
if(mModelRoot)
{
- uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount();
- for(uint32_t i = 0; i < maxLightCount; ++i)
- {
- if(mLights[i])
- {
- RemoveLightRecursively(modelNode, i);
- }
- }
+ UpdateShaderRecursively(modelNode, nullptr);
mModelRoot.Remove(modelNode);
}
}
{
// Make ParentOrigin as Center.
Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
- mLights.resize(Scene3D::Internal::Light::GetMaximumEnabledLightCount());
}
void Model::OnSceneConnection(int depth)
{
+ Actor parent = Self().GetParent();
+ while(parent)
+ {
+ // If this Model has parent SceneView and the its ShaderManager is same with privious ShaderManager,
+ // this Model don't need to update shader.
+ Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
+ if(sceneView)
+ {
+ mParentSceneView = sceneView;
+ GetImpl(sceneView).RegisterSceneItem(this);
+ Scene3D::Loader::ShaderManagerPtr shaderManager = GetImpl(sceneView).GetShaderManager();
+ if(mShaderManager != shaderManager)
+ {
+ mShaderManager = shaderManager;
+ UpdateShaderRecursively(mModelRoot, mShaderManager);
+ }
+ break;
+ }
+ parent = parent.GetParent();
+ }
+
+ // Model can be added on Dali::Scene directly without SceneView.
+ // So, Model's mShaderManager and shaders of child ModelNodes are needed to be reset when this Model has not parent SceneView.
+ Scene3D::SceneView parentSceneView = mParentSceneView.GetHandle();
+ if(!parentSceneView)
+ {
+ mShaderManager = new Dali::Scene3D::Loader::ShaderManager();
+ UpdateShaderRecursively(mModelRoot, mShaderManager);
+ }
+
if(!mModelLoadTask && !mModelResourceReady && !mModelUrl.empty())
{
// Request model load only if we setup url.
SetImageBasedLightSource(mDiffuseIblUrl, mSpecularIblUrl, mIblScaleFactor);
}
- Actor parent = Self().GetParent();
- while(parent)
- {
- Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
- if(sceneView)
- {
- GetImpl(sceneView).RegisterSceneItem(this);
- mParentSceneView = sceneView;
- break;
- }
- parent = parent.GetParent();
- }
-
NotifyResourceReady();
mSizeNotification = Self().AddPropertyNotification(Actor::Property::SIZE, StepCondition(SIZE_STEP_CONDITION));
void Model::OnSceneDisconnection()
{
+ // If mParentSceneView is still onScene, that means this model
+ // is disconnected from mParentSceneView's sub tree.
+ // So, Unregister this Model from SceneView.
Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
- if(sceneView)
+ if(sceneView && sceneView.GetProperty<bool>(Dali::Actor::Property::CONNECTED_TO_SCENE))
{
GetImpl(sceneView).UnregisterSceneItem(this);
mParentSceneView.Reset();
camera.SetProperty(Actor::Property::SCALE, resultScale);
}
+void Model::NotifyShadowMapTexture(Dali::Texture shadowMapTexture)
+{
+ if(mShadowMapTexture != shadowMapTexture)
+ {
+ mShadowMapTexture = shadowMapTexture;
+ UpdateShadowMapTextureRecursively(mModelRoot, mShadowMapTexture);
+ }
+}
+
void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor, uint32_t specularMipmapLevels)
{
if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
}
}
-void Model::NotifyLightAdded(uint32_t lightIndex, Scene3D::Light light)
-{
- mLights[lightIndex] = light;
- AddLightRecursively(mModelRoot, light, lightIndex);
-}
-
-void Model::NotifyLightRemoved(uint32_t lightIndex)
-{
- if(mLights[lightIndex])
- {
- RemoveLightRecursively(mModelRoot, lightIndex);
- mLights[lightIndex].Reset();
- }
-}
-
void Model::OnModelLoadComplete()
{
if(!mModelLoadTask->HasSucceeded())
mDefaultSpecularTexture = resources.mEnvironmentMaps.front().second.mSpecular;
}
- uint32_t maxLightCount = Scene3D::Internal::Light::GetMaximumEnabledLightCount();
- for(uint32_t i = 0; i < maxLightCount; ++i)
+ if(mShadowMapTexture)
{
- if(mLights[i])
- {
- AddLightRecursively(mModelRoot, mLights[i], i);
- }
+ UpdateShadowMapTextureRecursively(mModelRoot, mShadowMapTexture);
}
-
UpdateImageBasedLightTexture();
UpdateImageBasedLightScaleFactor();
Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z));
void Model::CreateModel()
{
- BoundingVolume AABB;
- auto& resources = mModelLoadTask->GetResources();
- auto& scene = mModelLoadTask->GetScene();
- auto& resourceChoices = mModelLoadTask->GetResourceChoices();
- Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
- Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, {}, {}, {}};
+ BoundingVolume AABB;
+ auto& resources = mModelLoadTask->GetResources();
+ auto& scene = mModelLoadTask->GetScene();
+ auto& resourceChoices = mModelLoadTask->GetResourceChoices();
+ Dali::Scene3D::Loader::Transforms xforms{Dali::Scene3D::Loader::MatrixStack{}, Dali::Scene3D::Loader::ViewProjection{}};
+
+ Dali::Scene3D::Loader::NodeDefinition::CreateParams nodeParams{resources, xforms, mShaderManager, {}, {}, {}};
// Generate Dali handles from resource bundle. Note that we generate all scene's resouce immediatly.
resources.GenerateResources();