Merge "Add log for font load validation" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / node-definition.cpp
1 /*
2  * Copyright (c) 2022 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // INTERNAL
19 #include "dali-scene-loader/public-api/node-definition.h"
20 #include "dali-scene-loader/public-api/renderer-state.h"
21 #include "dali-scene-loader/public-api/utils.h"
22
23 namespace Dali
24 {
25 namespace
26 {
27 constexpr std::string_view IBL_INTENSITY_STRING("uIblIntensity");
28 constexpr std::string_view IBL_Y_DIRECTION("uYDirection");
29 }
30
31 namespace SceneLoader
32 {
33 bool NodeDefinition::Renderable::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
34 {
35   return false;
36 }
37
38 void NodeDefinition::Renderable::RegisterResources(IResourceReceiver& receiver) const
39 {
40   receiver.Register(ResourceType::Shader, mShaderIdx);
41 }
42
43 void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
44 {
45   reflector.Reflect(ResourceType::Shader, mShaderIdx);
46 }
47
48 void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params, Actor& actor) const
49 {
50   DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
51   auto&  resources = params.mResources;
52   Shader shader    = resources.mShaders[mShaderIdx].second;
53
54   static Geometry defaultGeometry = Geometry::New();
55   Renderer        renderer        = Renderer::New(defaultGeometry, shader);
56
57   RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
58
59   actor.AddRenderer(renderer);
60 }
61
62 const std::string NodeDefinition::ORIGINAL_MATRIX_PROPERTY_NAME = "originalMatrix";
63
64 Actor NodeDefinition::CreateActor(CreateParams& params) const
65 {
66   Actor actor = Actor::New();
67   SetActorCentered(actor);
68
69   actor.SetProperty(Actor::Property::NAME, mName);
70   actor.SetProperty(Actor::Property::POSITION, mPosition);
71   actor.SetProperty(Actor::Property::ORIENTATION, mOrientation);
72   actor.SetProperty(Actor::Property::SCALE, mScale);
73   actor.SetProperty(Actor::Property::SIZE, mSize);
74   actor.SetProperty(Actor::Property::VISIBLE, mIsVisible);
75
76   actor.RegisterProperty(ORIGINAL_MATRIX_PROPERTY_NAME, GetLocalSpace(), Property::AccessMode::READ_ONLY);
77
78   if(mRenderable)
79   {
80     mRenderable->OnCreate(*this, params, actor);
81   }
82
83   for(auto& e : mExtras)
84   {
85     actor.RegisterProperty(e.mKey, e.mValue);
86   }
87
88   for(auto& c : mConstraints)
89   {
90     params.mConstrainables.push_back(ConstraintRequest{&c, actor});
91   }
92
93   return actor;
94 }
95
96 Matrix NodeDefinition::GetLocalSpace() const
97 {
98   Matrix localSpace{false};
99   localSpace.SetTransformComponents(mScale, mOrientation, mPosition);
100   return localSpace;
101 }
102
103 std::string_view NodeDefinition::GetIblScaleFactorUniformName()
104 {
105   return IBL_INTENSITY_STRING;
106 }
107
108 std::string_view NodeDefinition::GetIblYDirectionUniformName()
109 {
110   return IBL_Y_DIRECTION;
111 }
112
113 bool NodeDefinition::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
114 {
115   if(mRenderable)
116   {
117     if(!mRenderable->GetExtents(resources, min, max))
118     {
119       // If the renderable node don't have mesh accessor, use size to compute extents.
120       min = -mSize / 2.0f;
121       max = mSize / 2.0f;
122     }
123     return true;
124   }
125   return false;
126 }
127
128 bool ModelNode::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
129 {
130   auto& mesh = resources.mMeshes[mMeshIdx];
131   uint32_t minSize = mesh.first.mPositions.mBlob.mMin.size();
132   uint32_t maxSize = mesh.first.mPositions.mBlob.mMax.size();
133   if(minSize == maxSize && minSize >= 2u && maxSize >= 2u)
134   {
135     min = Vector3(mesh.first.mPositions.mBlob.mMin[0], mesh.first.mPositions.mBlob.mMin[1], 0.0f);
136     max = Vector3(mesh.first.mPositions.mBlob.mMax[0], mesh.first.mPositions.mBlob.mMax[1], 0.0f);
137     if(minSize == 3u)
138     {
139       min.z = mesh.first.mPositions.mBlob.mMin[2];
140       max.z = mesh.first.mPositions.mBlob.mMax[2];
141     }
142     return true;
143   }
144   return false;
145 }
146
147 void ModelNode::RegisterResources(IResourceReceiver& receiver) const
148 {
149   Renderable::RegisterResources(receiver);
150   receiver.Register(ResourceType::Mesh, mMeshIdx);
151   receiver.Register(ResourceType::Material, mMaterialIdx);
152 }
153
154 void ModelNode::ReflectResources(IResourceReflector& reflector)
155 {
156   Renderable::ReflectResources(reflector);
157   reflector.Reflect(ResourceType::Mesh, mMeshIdx);
158   reflector.Reflect(ResourceType::Material, mMaterialIdx);
159 }
160
161 void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
162 {
163   DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
164   Renderable::OnCreate(node, params, actor);
165
166   auto& resources = params.mResources;
167   auto& mesh      = resources.mMeshes[mMeshIdx];
168
169   auto     renderer = actor.GetRendererAt(0);
170   Geometry geometry = mesh.second.geometry;
171   renderer.SetGeometry(geometry);
172
173   auto shader = renderer.GetShader();
174
175   if(mesh.first.IsSkinned())
176   {
177     params.mSkinnables.push_back(SkinningShaderConfigurationRequest{mesh.first.mSkeletonIdx, shader});
178   }
179
180   if(mesh.first.HasBlendShapes())
181   {
182     params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{node.mName, mMeshIdx, shader});
183   }
184
185   TextureSet textures = resources.mMaterials[mMaterialIdx].second;
186
187   // Set the blend shape texture.
188   if(mesh.second.blendShapeGeometry)
189   {
190     TextureSet newTextureSet = TextureSet::New();
191     newTextureSet.SetTexture(0u, mesh.second.blendShapeGeometry);
192
193     const unsigned int numberOfTextures = textures.GetTextureCount();
194     for(unsigned int index = 0u; index < numberOfTextures; ++index)
195     {
196       const unsigned int newIndex = index + 1u;
197       newTextureSet.SetTexture(newIndex, textures.GetTexture(index));
198       newTextureSet.SetSampler(newIndex, textures.GetSampler(index));
199     }
200
201     textures = newTextureSet;
202   }
203
204   renderer.SetTextures(textures);
205
206   actor.SetProperty(Actor::Property::COLOR, mColor);
207
208   actor.RegisterProperty("uHasVertexColor", static_cast<float>(mesh.first.mColors.IsDefined()));
209
210   auto& matDef = resources.mMaterials[mMaterialIdx].first;
211   actor.RegisterProperty("uColorFactor", matDef.mBaseColorFactor);
212   actor.RegisterProperty("uMetallicFactor", matDef.mMetallic);
213   actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness);
214   actor.RegisterProperty("uNormalScale", matDef.mNormalScale);
215   if(matDef.mFlags & MaterialDefinition::OCCLUSION)
216   {
217     actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
218   }
219   if(matDef.mFlags & MaterialDefinition::EMISSIVE)
220   {
221     actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor);
222   }
223
224   Index envIdx = matDef.mEnvironmentIdx;
225   actor.RegisterProperty(IBL_INTENSITY_STRING.data(), resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
226   actor.RegisterProperty(IBL_Y_DIRECTION.data(), resources.mEnvironmentMaps[envIdx].first.mYDirection);
227
228   float opaque      = 0.0f;
229   float mask        = 0.0f;
230   float alphaCutoff = matDef.GetAlphaCutoff();
231   if(!MaskMatch(matDef.mFlags, MaterialDefinition::TRANSPARENCY))
232   {
233     opaque = 1.0f;
234   }
235   else
236   {
237     if(alphaCutoff > 0.f)
238     {
239       mask = 1.0f;
240     }
241   }
242   actor.RegisterProperty("uOpaque", opaque);
243   actor.RegisterProperty("uMask", mask);
244   actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
245 }
246
247 void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
248 {
249   ModelNode::OnCreate(node, params, actor);
250
251   actor.RegisterProperty("antiAliasing", mAntiAliasing ? 1 : 0);
252   actor.RegisterProperty("arcCaps", mArcCaps);
253   actor.RegisterProperty("radius", mRadius);
254
255   const float startAngleRadians = mStartAngleDegrees * Math::PI_OVER_180;
256   Vector2     startPolar{std::cos(startAngleRadians), std::sin(startAngleRadians)};
257   actor.RegisterProperty("startAngle", startPolar);
258
259   const float endAngleRadians = mEndAngleDegrees * Math::PI_OVER_180;
260   Vector2     endPolar{std::cos(endAngleRadians), std::sin(endAngleRadians)};
261   actor.RegisterProperty("endAngle", endPolar);
262 }
263
264 void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vector2& endVector)
265 {
266   float endAngle = 0.f;
267
268   if(diffAngle <= 0.001f)
269   {
270     //0.001 is used to ensure is empty arc when startAngle = endAngle + 360 * N
271     endAngle = startAngle + 0.001f;
272   }
273   else if(diffAngle >= 360.f)
274   {
275     endAngle = diffAngle + 359.99f;
276   }
277   else
278   {
279     endAngle = startAngle + 360.0f + diffAngle;
280   }
281   endVector.x = cosf(endAngle * Math::PI_OVER_180);
282   endVector.y = sinf(endAngle * Math::PI_OVER_180);
283 }
284
285 } // namespace SceneLoader
286 } // namespace Dali