7542782ccf93199263c4766332705e5b3f634d87
[platform/core/uifw/dali-toolkit.git] / dali-scene-loader / public-api / node-definition.cpp
1 /*
2  * Copyright (c) 2021 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 SceneLoader
26 {
27 void NodeDefinition::Renderable::RegisterResources(IResourceReceiver& receiver) const
28 {
29   receiver.Register(ResourceType::Shader, mShaderIdx);
30 }
31
32 void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
33 {
34   reflector.Reflect(ResourceType::Shader, mShaderIdx);
35 }
36
37 void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params, Actor& actor) const
38 {
39   DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
40   auto&  resources = params.mResources;
41   Shader shader    = resources.mShaders[mShaderIdx].second;
42
43   static Geometry defaultGeometry = Geometry::New();
44   Renderer        renderer        = Renderer::New(defaultGeometry, shader);
45
46   RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
47
48   actor.AddRenderer(renderer);
49 }
50
51 const std::string NodeDefinition::ORIGINAL_MATRIX_PROPERTY_NAME = "originalMatrix";
52
53 Actor NodeDefinition::CreateActor(CreateParams& params) const
54 {
55   Actor actor = Actor::New();
56   SetActorCentered(actor);
57
58   actor.SetProperty(Actor::Property::NAME, mName);
59   actor.SetProperty(Actor::Property::POSITION, mPosition);
60   actor.SetProperty(Actor::Property::ORIENTATION, mOrientation);
61   actor.SetProperty(Actor::Property::SCALE, mScale);
62   actor.SetProperty(Actor::Property::SIZE, mSize);
63   actor.SetProperty(Actor::Property::VISIBLE, mIsVisible);
64
65   actor.RegisterProperty(ORIGINAL_MATRIX_PROPERTY_NAME, GetLocalSpace(), Property::AccessMode::READ_ONLY);
66
67   if(mRenderable)
68   {
69     mRenderable->OnCreate(*this, params, actor);
70   }
71
72   for(auto& e : mExtras)
73   {
74     actor.RegisterProperty(e.mKey, e.mValue);
75   }
76
77   for(auto& c : mConstraints)
78   {
79     params.mConstrainables.push_back(ConstraintRequest{&c, actor});
80   }
81
82   return actor;
83 }
84
85 Matrix NodeDefinition::GetLocalSpace() const
86 {
87   Matrix localSpace{false};
88   localSpace.SetTransformComponents(mScale, mOrientation, mPosition);
89   return localSpace;
90 }
91
92 void ModelNode::RegisterResources(IResourceReceiver& receiver) const
93 {
94   Renderable::RegisterResources(receiver);
95   receiver.Register(ResourceType::Mesh, mMeshIdx);
96   receiver.Register(ResourceType::Material, mMaterialIdx);
97 }
98
99 void ModelNode::ReflectResources(IResourceReflector& reflector)
100 {
101   Renderable::ReflectResources(reflector);
102   reflector.Reflect(ResourceType::Mesh, mMeshIdx);
103   reflector.Reflect(ResourceType::Material, mMaterialIdx);
104 }
105
106 void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
107 {
108   DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
109   Renderable::OnCreate(node, params, actor);
110
111   auto& resources = params.mResources;
112   auto& mesh      = resources.mMeshes[mMeshIdx];
113
114   auto     renderer = actor.GetRendererAt(0);
115   Geometry geometry = mesh.second.geometry;
116   renderer.SetGeometry(geometry);
117
118   auto shader = renderer.GetShader();
119
120   if(mesh.first.IsSkinned())
121   {
122     params.mSkinnables.push_back(SkinningShaderConfigurationRequest{mesh.first.mSkeletonIdx, shader});
123   }
124
125   if(mesh.first.HasBlendShapes())
126   {
127     params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{node.mName, mMeshIdx, shader});
128   }
129
130   TextureSet textures = resources.mMaterials[mMaterialIdx].second;
131
132   // Set the blend shape texture.
133   if(mesh.second.blendShapeGeometry)
134   {
135     TextureSet newTextureSet = TextureSet::New();
136     newTextureSet.SetTexture(0u, mesh.second.blendShapeGeometry);
137
138     const unsigned int numberOfTextures = textures.GetTextureCount();
139     for(unsigned int index = 0u; index < numberOfTextures; ++index)
140     {
141       const unsigned int newIndex = index + 1u;
142       newTextureSet.SetTexture(newIndex, textures.GetTexture(index));
143       newTextureSet.SetSampler(newIndex, textures.GetSampler(index));
144     }
145
146     textures = newTextureSet;
147   }
148
149   renderer.SetTextures(textures);
150
151   actor.SetProperty(Actor::Property::COLOR, mColor);
152
153   actor.RegisterProperty("uHasVertexColor", static_cast<float>(mesh.first.mColors.IsDefined()));
154
155   auto& matDef = resources.mMaterials[mMaterialIdx].first;
156   actor.RegisterProperty("uColorFactor", matDef.mBaseColorFactor);
157   actor.RegisterProperty("uMetallicFactor", matDef.mMetallic);
158   actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness);
159   actor.RegisterProperty("uNormalScale", matDef.mNormalScale);
160   if(matDef.mFlags & MaterialDefinition::OCCLUSION)
161   {
162     actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
163   }
164   if(matDef.mFlags & MaterialDefinition::EMISSIVE)
165   {
166     actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor);
167   }
168
169   Index envIdx = matDef.mEnvironmentIdx;
170   actor.RegisterProperty("uIblIntensity", resources.mEnvironmentMaps[envIdx].first.mIblIntensity);
171
172   float opaque = 0.0f;
173   float mask = 0.0f;
174   float alphaCutoff = matDef.GetAlphaCutoff();
175   if(!MaskMatch(matDef.mFlags, MaterialDefinition::TRANSPARENCY))
176   {
177     opaque = 1.0f;
178   }
179   else
180   {
181     if(alphaCutoff > 0.f)
182     {
183       mask = 1.0f;
184     }
185   }
186   actor.RegisterProperty("uOpaque", opaque);
187   actor.RegisterProperty("uMask", mask);
188   actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
189 }
190
191 void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
192 {
193   ModelNode::OnCreate(node, params, actor);
194
195   actor.RegisterProperty("antiAliasing", mAntiAliasing ? 1 : 0);
196   actor.RegisterProperty("arcCaps", mArcCaps);
197   actor.RegisterProperty("radius", mRadius);
198
199   const float startAngleRadians = mStartAngleDegrees * Math::PI_OVER_180;
200   Vector2     startPolar{std::cos(startAngleRadians), std::sin(startAngleRadians)};
201   actor.RegisterProperty("startAngle", startPolar);
202
203   const float endAngleRadians = mEndAngleDegrees * Math::PI_OVER_180;
204   Vector2     endPolar{std::cos(endAngleRadians), std::sin(endAngleRadians)};
205   actor.RegisterProperty("endAngle", endPolar);
206 }
207
208 void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vector2& endVector)
209 {
210   float endAngle = 0.f;
211
212   if(diffAngle <= 0.001f)
213   {
214     //0.001 is used to ensure is empty arc when startAngle = endAngle + 360 * N
215     endAngle = startAngle + 0.001f;
216   }
217   else if(diffAngle >= 360.f)
218   {
219     endAngle = diffAngle + 359.99f;
220   }
221   else
222   {
223     endAngle = startAngle + 360.0f + diffAngle;
224   }
225   endVector.x = cosf(endAngle * Math::PI_OVER_180);
226   endVector.y = sinf(endAngle * Math::PI_OVER_180);
227 }
228
229 } // namespace SceneLoader
230 } // namespace Dali