ModelView using scene-loader
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / node-definition.cpp
index a277371..e8dafa8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
 
 namespace Dali
 {
+namespace
+{
+constexpr std::string_view IBL_INTENSITY_STRING("uIblIntensity");
+constexpr std::string_view IBL_Y_DIRECTION("uYDirection");
+}
+
 namespace SceneLoader
 {
+bool NodeDefinition::Renderable::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
+{
+  return false;
+}
 
 void NodeDefinition::Renderable::RegisterResources(IResourceReceiver& receiver) const
 {
@@ -35,15 +45,14 @@ void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
   reflector.Reflect(ResourceType::Shader, mShaderIdx);
 }
 
-void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params,
-  Actor& actor) const
+void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params, Actor& actor) const
 {
   DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
-  auto& resources = params.mResources;
-  Shader shader = resources.mShaders[mShaderIdx].second;
+  auto&  resources = params.mResources;
+  Shader shader    = resources.mShaders[mShaderIdx].second;
 
   static Geometry defaultGeometry = Geometry::New();
-  Renderer renderer = Renderer::New(defaultGeometry, shader);
+  Renderer        renderer        = Renderer::New(defaultGeometry, shader);
 
   RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
 
@@ -66,19 +75,19 @@ Actor NodeDefinition::CreateActor(CreateParams& params) const
 
   actor.RegisterProperty(ORIGINAL_MATRIX_PROPERTY_NAME, GetLocalSpace(), Property::AccessMode::READ_ONLY);
 
-  if (mRenderable)
+  if(mRenderable)
   {
     mRenderable->OnCreate(*this, params, actor);
   }
 
-  for (auto& e : mExtras)
+  for(auto& e : mExtras)
   {
     actor.RegisterProperty(e.mKey, e.mValue);
   }
 
-  for (auto& c : mConstraints)
+  for(auto& c : mConstraints)
   {
-    params.mConstrainables.push_back(ConstraintRequest{ &c, actor });
+    params.mConstrainables.push_back(ConstraintRequest{&c, actor});
   }
 
   return actor;
@@ -86,11 +95,55 @@ Actor NodeDefinition::CreateActor(CreateParams& params) const
 
 Matrix NodeDefinition::GetLocalSpace() const
 {
-  Matrix localSpace{ false };
+  Matrix localSpace{false};
   localSpace.SetTransformComponents(mScale, mOrientation, mPosition);
   return localSpace;
 }
 
+std::string_view NodeDefinition::GetIblScaleFactorUniformName()
+{
+  return IBL_INTENSITY_STRING;
+}
+
+std::string_view NodeDefinition::GetIblYDirectionUniformName()
+{
+  return IBL_Y_DIRECTION;
+}
+
+bool NodeDefinition::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
+{
+  if(mRenderable)
+  {
+    if(!mRenderable->GetExtents(resources, min, max))
+    {
+      // If the renderable node don't have mesh accessor, use size to compute extents.
+      min = -mSize / 2.0f;
+      max = mSize / 2.0f;
+    }
+    return true;
+  }
+  return false;
+}
+
+bool ModelNode::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
+{
+  auto& mesh = resources.mMeshes[mMeshIdx];
+  uint32_t minSize = mesh.first.mPositions.mBlob.mMin.size();
+  uint32_t maxSize = mesh.first.mPositions.mBlob.mMax.size();
+  if(minSize == maxSize && minSize >= 2u && maxSize >= 2u)
+  {
+    min = Vector3(mesh.first.mPositions.mBlob.mMin[0], mesh.first.mPositions.mBlob.mMin[1], 0.0f);
+    max = Vector3(mesh.first.mPositions.mBlob.mMax[0], mesh.first.mPositions.mBlob.mMax[1], 0.0f);
+    if(minSize == 3u)
+    {
+      min.z = mesh.first.mPositions.mBlob.mMin[2];
+      max.z = mesh.first.mPositions.mBlob.mMax[2];
+    }
+    return true;
+  }
+  return false;
+}
+
 void ModelNode::RegisterResources(IResourceReceiver& receiver) const
 {
   Renderable::RegisterResources(receiver);
@@ -111,34 +164,34 @@ void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParam
   Renderable::OnCreate(node, params, actor);
 
   auto& resources = params.mResources;
-  auto& mesh = resources.mMeshes[mMeshIdx];
+  auto& mesh      = resources.mMeshes[mMeshIdx];
 
-  auto renderer = actor.GetRendererAt(0);
+  auto     renderer = actor.GetRendererAt(0);
   Geometry geometry = mesh.second.geometry;
   renderer.SetGeometry(geometry);
 
   auto shader = renderer.GetShader();
 
-  if (mesh.first.IsSkinned())
+  if(mesh.first.IsSkinned())
   {
-    params.mSkinnables.push_back(SkinningShaderConfigurationRequest{ mesh.first.mSkeletonIdx, shader });
+    params.mSkinnables.push_back(SkinningShaderConfigurationRequest{mesh.first.mSkeletonIdx, shader});
   }
 
-  if (mesh.first.HasBlendShapes())
+  if(mesh.first.HasBlendShapes())
   {
-    params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{ node.mName, mMeshIdx, shader });
+    params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{node.mName, mMeshIdx, shader});
   }
 
   TextureSet textures = resources.mMaterials[mMaterialIdx].second;
 
   // Set the blend shape texture.
-  if (mesh.second.blendShapeGeometry)
+  if(mesh.second.blendShapeGeometry)
   {
     TextureSet newTextureSet = TextureSet::New();
     newTextureSet.SetTexture(0u, mesh.second.blendShapeGeometry);
 
     const unsigned int numberOfTextures = textures.GetTextureCount();
-    for (unsigned int index = 0u; index < numberOfTextures; ++index)
+    for(unsigned int index = 0u; index < numberOfTextures; ++index)
     {
       const unsigned int newIndex = index + 1u;
       newTextureSet.SetTexture(newIndex, textures.GetTexture(index));
@@ -152,22 +205,46 @@ void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParam
 
   actor.SetProperty(Actor::Property::COLOR, mColor);
 
+  actor.RegisterProperty("uHasVertexColor", static_cast<float>(mesh.first.mColors.IsDefined()));
+
   auto& matDef = resources.mMaterials[mMaterialIdx].first;
+  actor.RegisterProperty("uColorFactor", matDef.mBaseColorFactor);
   actor.RegisterProperty("uMetallicFactor", matDef.mMetallic);
   actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness);
+  actor.RegisterProperty("uNormalScale", matDef.mNormalScale);
+  if(matDef.mFlags & MaterialDefinition::OCCLUSION)
+  {
+    actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
+  }
+  if(matDef.mFlags & MaterialDefinition::EMISSIVE)
+  {
+    actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor);
+  }
 
   Index envIdx = matDef.mEnvironmentIdx;
-  actor.RegisterProperty("uIblIntensity", resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
+  actor.RegisterProperty(IBL_INTENSITY_STRING.data(), resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
+  actor.RegisterProperty(IBL_Y_DIRECTION.data(), resources.mEnvironmentMaps[envIdx].first.mYDirection);
 
-  const auto alphaCutoff = matDef.GetAlphaCutoff();
-  if (alphaCutoff > 0.f)
+  float opaque      = 0.0f;
+  float mask        = 0.0f;
+  float alphaCutoff = matDef.GetAlphaCutoff();
+  if(!MaskMatch(matDef.mFlags, MaterialDefinition::TRANSPARENCY))
+  {
+    opaque = 1.0f;
+  }
+  else
   {
-    actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
+    if(alphaCutoff > 0.f)
+    {
+      mask = 1.0f;
+    }
   }
+  actor.RegisterProperty("uOpaque", opaque);
+  actor.RegisterProperty("uMask", mask);
+  actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
 }
 
-void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params,
-  Actor& actor) const
+void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
 {
   ModelNode::OnCreate(node, params, actor);
 
@@ -176,11 +253,11 @@ void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams&
   actor.RegisterProperty("radius", mRadius);
 
   const float startAngleRadians = mStartAngleDegrees * Math::PI_OVER_180;
-  Vector2 startPolar{ std::cos(startAngleRadians), std::sin(startAngleRadians) };
+  Vector2     startPolar{std::cos(startAngleRadians), std::sin(startAngleRadians)};
   actor.RegisterProperty("startAngle", startPolar);
 
   const float endAngleRadians = mEndAngleDegrees * Math::PI_OVER_180;
-  Vector2 endPolar{ std::cos(endAngleRadians), std::sin(endAngleRadians) };
+  Vector2     endPolar{std::cos(endAngleRadians), std::sin(endAngleRadians)};
   actor.RegisterProperty("endAngle", endPolar);
 }
 
@@ -188,12 +265,12 @@ void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vecto
 {
   float endAngle = 0.f;
 
-  if (diffAngle <= 0.001f)
+  if(diffAngle <= 0.001f)
   {
     //0.001 is used to ensure is empty arc when startAngle = endAngle + 360 * N
     endAngle = startAngle + 0.001f;
   }
-  else if (diffAngle >= 360.f)
+  else if(diffAngle >= 360.f)
   {
     endAngle = diffAngle + 359.99f;
   }
@@ -205,5 +282,5 @@ void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vecto
   endVector.y = sinf(endAngle * Math::PI_OVER_180);
 }
 
-}
-}
+} // namespace SceneLoader
+} // namespace Dali