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