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