// EXTERNAL INCLUDES
#include <dali-toolkit/dali-toolkit.h>
-#include <dali-toolkit/devel-api/controls/control-devel.h>
#include <dali-toolkit/internal/controls/control/control-data-impl.h>
#include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
#include <dali/integration-api/debug.h>
#include <filesystem>
// INTERNAL INCLUDES
+#include <dali-scene3d/internal/controls/scene-view/scene-view-impl.h>
#include <dali-scene3d/public-api/controls/model-view/model-view.h>
#include <dali-scene3d/public-api/loader/animation-definition.h>
#include <dali-scene3d/public-api/loader/camera-parameters.h>
-#include <dali-scene3d/public-api/loader/cube-data.h>
#include <dali-scene3d/public-api/loader/cube-map-loader.h>
#include <dali-scene3d/public-api/loader/dli-loader.h>
#include <dali-scene3d/public-api/loader/gltf2-loader.h>
Vector3 pointMax;
};
-Texture LoadCubeMap(const std::string& cubeMapPath)
-{
- Texture cubeTexture;
- Dali::Scene3D::Loader::CubeData cubeData;
- if(Dali::Scene3D::Loader::LoadCubeMapData(cubeMapPath, cubeData))
- {
- cubeTexture = cubeData.CreateTexture();
- }
- else
- {
- DALI_LOG_ERROR("Fail to load cube map, %s\n", cubeMapPath.c_str());
- }
-
- return cubeTexture;
-}
-
void ConfigureBlendShapeShaders(
Dali::Scene3D::Loader::ResourceBundle& resources, const Dali::Scene3D::Loader::SceneDefinition& scene, Actor root, std::vector<Dali::Scene3D::Loader::BlendshapeShaderConfigurationRequest>&& requests)
{
} // anonymous namespace
ModelView::ModelView(const std::string& modelPath, const std::string& resourcePath)
-: Control(ControlBehaviour(CONTROL_BEHAVIOUR_DEFAULT)),
+: Control(ControlBehaviour(DISABLE_SIZE_NEGOTIATION | DISABLE_STYLE_CHANGE_SIGNALS)),
mModelPath(modelPath),
mResourcePath(resourcePath),
- mModelLayer(),
mModelRoot(),
mNaturalSize(Vector3::ZERO),
mModelPivot(AnchorPoint::CENTER),
mIblScaleFactor(1.0f),
- mFitSize(false),
- mFitCenter(false)
+ mFitSize(true),
+ mFitCenter(true),
+ mModelResourceReady(false),
+ mIBLResourceReady(true)
{
}
void ModelView::SetImageBasedLightSource(const std::string& diffuse, const std::string& specular, float scaleFactor)
{
- Texture diffuseTexture = LoadCubeMap(diffuse);
- if(diffuseTexture)
+ mIBLResourceReady = false;
+ Texture diffuseTexture = Dali::Scene3D::Loader::LoadCubeMap(diffuse);
+ Texture specularTexture = Dali::Scene3D::Loader::LoadCubeMap(specular);
+ SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
+ mIBLResourceReady = true;
+
+ // If Model resource is already ready, then set resource ready.
+ // If Model resource is still not ready, wait for model resource ready.
+ if(IsResourceReady())
{
- Texture specularTexture = LoadCubeMap(specular);
- if(specularTexture)
- {
- mDiffuseTexture = diffuseTexture;
- mSpecularTexture = specularTexture;
- mIblScaleFactor = scaleFactor;
+ SetResourceReady(false);
+ }
+}
- SetImageBasedLight(mModelRoot);
- }
+void ModelView::SetImageBasedLightTexture(Dali::Texture diffuse, Dali::Texture specular, float scaleFactor)
+{
+ if(diffuse && specular)
+ {
+ mDiffuseTexture = diffuse;
+ mSpecularTexture = specular;
+ mIblScaleFactor = scaleFactor;
+
+ UpdateImageBasedLight();
}
}
LoadModel();
}
+ Actor parent = Self().GetParent();
+ while(parent)
+ {
+ Scene3D::SceneView sceneView = Scene3D::SceneView::DownCast(parent);
+ if(sceneView)
+ {
+ GetImpl(sceneView).RegisterModelView(Scene3D::ModelView::DownCast(Self()));
+ mParentSceneView = sceneView;
+ break;
+ }
+ parent = parent.GetParent();
+ }
+
Control::OnSceneConnection(depth);
}
-void ModelView::OnInitialize()
+void ModelView::OnSceneDisconnection()
{
- Actor self = Self();
- mModelLayer = Layer::New();
- mModelLayer.SetProperty(Layer::Property::BEHAVIOR, Layer::LAYER_3D);
- mModelLayer.SetProperty(Layer::Property::DEPTH_TEST, true);
- mModelLayer.SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
- mModelLayer.SetProperty(Dali::Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
- mModelLayer.SetResizePolicy(ResizePolicy::FILL_TO_PARENT,
- Dimension::ALL_DIMENSIONS);
-
- // Models in glTF and dli are defined as right hand coordinate system.
- // DALi uses left hand coordinate system. Scaling negative is for change winding order.
- mModelLayer.SetProperty(Dali::Actor::Property::SCALE_Y, -1.0f);
- self.Add(mModelLayer);
+ Scene3D::SceneView sceneView = mParentSceneView.GetHandle();
+ if(sceneView)
+ {
+ GetImpl(sceneView).UnregisterModelView(Scene3D::ModelView::DownCast(Self()));
+ mParentSceneView.Reset();
+ }
+ Control::OnSceneDisconnection();
}
Vector3 ModelView::GetNaturalSize()
ScaleModel();
}
+bool ModelView::IsResourceReady() const
+{
+ return mModelResourceReady && mIBLResourceReady;
+}
+
void ModelView::LoadModel()
{
std::filesystem::path modelPath(mModelPath);
}
}
- SetImageBasedLight(mModelRoot);
+ mRenderableActors.clear();
+ CollectRenderableActor(mModelRoot);
+ UpdateImageBasedLight();
mNaturalSize = AABB.CalculateSize();
mModelPivot = AABB.CalculatePivot();
mModelRoot.SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
+ Vector3 controlSize = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+ if(controlSize.x == 0.0f || controlSize.y == 0.0f)
+ {
+ Self().SetProperty(Dali::Actor::Property::SIZE, mNaturalSize);
+ }
FitModelPosition();
ScaleModel();
- mModelLayer.Add(mModelRoot);
+ Self().Add(mModelRoot);
+
+ Self().SetProperty(Dali::Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
+ Self().SetProperty(Dali::Actor::Property::ANCHOR_POINT, Vector3(mModelPivot.x, 1.0f - mModelPivot.y, mModelPivot.z));
+
+ mModelResourceReady = true;
+
+ Control::SetResourceReady(false);
}
void ModelView::ScaleModel()
{
if(mModelRoot)
{
- if(mFitSize)
+ Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
+ if(mFitSize && size.x > 0.0f && size.y > 0.0f)
{
- Vector3 size = Self().GetProperty<Vector3>(Dali::Actor::Property::SIZE);
- if(size.x > 0.0f && size.y > 0.0f)
- {
- float scaleFactor = MAXFLOAT;
- scaleFactor = std::min(size.x / mNaturalSize.x, scaleFactor);
- scaleFactor = std::min(size.y / mNaturalSize.y, scaleFactor);
- mModelRoot.SetProperty(Dali::Actor::Property::SCALE, scaleFactor);
- }
- else
- {
- DALI_LOG_ERROR("ModelView size is wrong.");
- }
+ float scaleFactor = MAXFLOAT;
+ scaleFactor = std::min(size.x / mNaturalSize.x, scaleFactor);
+ scaleFactor = std::min(size.y / mNaturalSize.y, scaleFactor);
+ // Models in glTF and dli are defined as right hand coordinate system.
+ // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+ mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION * scaleFactor);
}
else
{
- mModelRoot.SetProperty(Dali::Actor::Property::SCALE, 1.0f);
+ // Models in glTF and dli are defined as right hand coordinate system.
+ // DALi uses left hand coordinate system. Scaling negative is for change winding order.
+ mModelRoot.SetProperty(Dali::Actor::Property::SCALE, Y_DIRECTION);
}
}
}
}
}
-void ModelView::SetImageBasedLight(Actor node)
+void ModelView::CollectRenderableActor(Actor actor)
{
- if(!mDiffuseTexture || !mSpecularTexture || !node)
+ uint32_t rendererCount = actor.GetRendererCount();
+ if(rendererCount)
{
- return;
+ mRenderableActors.push_back(actor);
}
- uint32_t rendererCount = node.GetRendererCount();
- if(rendererCount)
+ uint32_t childrenCount = actor.GetChildCount();
+ for(uint32_t i = 0; i < childrenCount; ++i)
+ {
+ CollectRenderableActor(actor.GetChildAt(i));
+ }
+}
+
+void ModelView::UpdateImageBasedLight()
+{
+ if(!mDiffuseTexture || !mSpecularTexture)
{
- node.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), mIblScaleFactor);
+ return;
}
- for(uint32_t i = 0; i < rendererCount; ++i)
+ for(auto&& actor : mRenderableActors)
{
- Dali::Renderer renderer = node.GetRendererAt(i);
- if(renderer)
+ Actor renderableActor = actor.GetHandle();
+ if(renderableActor)
{
- Dali::TextureSet textures = renderer.GetTextures();
- if(textures)
+ renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), mIblScaleFactor);
+
+ uint32_t rendererCount = renderableActor.GetRendererCount();
+ for(uint32_t i = 0; i < rendererCount; ++i)
{
- uint32_t textureCount = textures.GetTextureCount();
- // EnvMap requires at least 2 texture, diffuse and specular
- if(textureCount > 2u)
+ Dali::Renderer renderer = renderableActor.GetRendererAt(i);
+ if(renderer)
{
- textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, mDiffuseTexture);
- textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, mSpecularTexture);
+ Dali::TextureSet textures = renderer.GetTextures();
+ if(textures)
+ {
+ uint32_t textureCount = textures.GetTextureCount();
+ // EnvMap requires at least 2 texture, diffuse and specular
+ if(textureCount > 2u)
+ {
+ textures.SetTexture(textureCount - OFFSET_FOR_DIFFUSE_CUBE_TEXTURE, mDiffuseTexture);
+ textures.SetTexture(textureCount - OFFSET_FOR_SPECULAR_CUBE_TEXTURE, mSpecularTexture);
+ }
+ }
}
}
}
}
-
- uint32_t childrenCount = node.GetChildCount();
- for(uint32_t i = 0; i < childrenCount; ++i)
- {
- SetImageBasedLight(node.GetChildAt(i));
- }
}
} // namespace Internal