2 * Copyright (c) 2022 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
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"
27 constexpr std::string_view IBL_INTENSITY_STRING("uIblIntensity");
28 constexpr std::string_view IBL_Y_DIRECTION("uYDirection");
35 bool NodeDefinition::Renderable::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
40 void NodeDefinition::Renderable::RegisterResources(IResourceReceiver& receiver) const
42 receiver.Register(ResourceType::Shader, mShaderIdx);
45 void NodeDefinition::Renderable::ReflectResources(IResourceReflector& reflector)
47 reflector.Reflect(ResourceType::Shader, mShaderIdx);
50 void NodeDefinition::Renderable::OnCreate(const NodeDefinition& node, CreateParams& params, Actor& actor) const
52 DALI_ASSERT_DEBUG(mShaderIdx != INVALID_INDEX);
53 auto& resources = params.mResources;
54 Shader shader = resources.mShaders[mShaderIdx].second;
56 static Geometry defaultGeometry = Geometry::New();
57 Renderer renderer = Renderer::New(defaultGeometry, shader);
59 RendererState::Apply(resources.mShaders[mShaderIdx].first.mRendererState, renderer);
61 actor.AddRenderer(renderer);
64 const std::string NodeDefinition::ORIGINAL_MATRIX_PROPERTY_NAME = "originalMatrix";
66 Actor NodeDefinition::CreateActor(CreateParams& params) const
68 Actor actor = Actor::New();
69 SetActorCentered(actor);
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);
78 actor.RegisterProperty(ORIGINAL_MATRIX_PROPERTY_NAME, GetLocalSpace(), Property::AccessMode::READ_ONLY);
82 mRenderable->OnCreate(*this, params, actor);
85 for(auto& e : mExtras)
87 actor.RegisterProperty(e.mKey, e.mValue);
90 for(auto& c : mConstraints)
92 params.mConstrainables.push_back(ConstraintRequest{&c, actor});
98 Matrix NodeDefinition::GetLocalSpace() const
100 Matrix localSpace{false};
101 localSpace.SetTransformComponents(mScale, mOrientation, mPosition);
105 std::string_view NodeDefinition::GetIblScaleFactorUniformName()
107 return IBL_INTENSITY_STRING;
110 std::string_view NodeDefinition::GetIblYDirectionUniformName()
112 return IBL_Y_DIRECTION;
115 bool NodeDefinition::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
119 if(!mRenderable->GetExtents(resources, min, max))
121 // If the renderable node don't have mesh accessor, use size to compute extents.
130 bool ModelNode::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
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)
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);
141 min.z = mesh.first.mPositions.mBlob.mMin[2];
142 max.z = mesh.first.mPositions.mBlob.mMax[2];
149 void ModelNode::RegisterResources(IResourceReceiver& receiver) const
151 Renderable::RegisterResources(receiver);
152 receiver.Register(ResourceType::Mesh, mMeshIdx);
153 receiver.Register(ResourceType::Material, mMaterialIdx);
156 void ModelNode::ReflectResources(IResourceReflector& reflector)
158 Renderable::ReflectResources(reflector);
159 reflector.Reflect(ResourceType::Mesh, mMeshIdx);
160 reflector.Reflect(ResourceType::Material, mMaterialIdx);
163 void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
165 DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
166 Renderable::OnCreate(node, params, actor);
168 auto& resources = params.mResources;
169 auto& mesh = resources.mMeshes[mMeshIdx];
171 auto renderer = actor.GetRendererAt(0);
172 Geometry geometry = mesh.second.geometry;
173 renderer.SetGeometry(geometry);
175 auto shader = renderer.GetShader();
177 if(mesh.first.IsSkinned())
179 params.mSkinnables.push_back(SkinningShaderConfigurationRequest{mesh.first.mSkeletonIdx, shader});
182 if(mesh.first.HasBlendShapes())
184 params.mBlendshapeRequests.push_back(BlendshapeShaderConfigurationRequest{node.mName, mMeshIdx, shader});
187 TextureSet textures = resources.mMaterials[mMaterialIdx].second;
189 // Set the blend shape texture.
190 if(mesh.second.blendShapeGeometry)
192 TextureSet newTextureSet = TextureSet::New();
193 newTextureSet.SetTexture(0u, mesh.second.blendShapeGeometry);
195 const unsigned int numberOfTextures = textures.GetTextureCount();
196 for(unsigned int index = 0u; index < numberOfTextures; ++index)
198 const unsigned int newIndex = index + 1u;
199 newTextureSet.SetTexture(newIndex, textures.GetTexture(index));
200 newTextureSet.SetSampler(newIndex, textures.GetSampler(index));
203 textures = newTextureSet;
206 renderer.SetTextures(textures);
208 actor.SetProperty(Actor::Property::COLOR, mColor);
210 actor.RegisterProperty("uHasVertexColor", static_cast<float>(mesh.first.mColors.IsDefined()));
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)
219 actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
221 if(matDef.mFlags & MaterialDefinition::EMISSIVE)
223 actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor);
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);
232 float alphaCutoff = matDef.GetAlphaCutoff();
233 if(!MaskMatch(matDef.mFlags, MaterialDefinition::TRANSPARENCY))
239 if(alphaCutoff > 0.f)
244 actor.RegisterProperty("uOpaque", opaque);
245 actor.RegisterProperty("uMask", mask);
246 actor.RegisterProperty("uAlphaThreshold", alphaCutoff);
249 void ArcNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
251 ModelNode::OnCreate(node, params, actor);
253 actor.RegisterProperty("antiAliasing", mAntiAliasing ? 1 : 0);
254 actor.RegisterProperty("arcCaps", mArcCaps);
255 actor.RegisterProperty("radius", mRadius);
257 const float startAngleRadians = mStartAngleDegrees * Math::PI_OVER_180;
258 Vector2 startPolar{std::cos(startAngleRadians), std::sin(startAngleRadians)};
259 actor.RegisterProperty("startAngle", startPolar);
261 const float endAngleRadians = mEndAngleDegrees * Math::PI_OVER_180;
262 Vector2 endPolar{std::cos(endAngleRadians), std::sin(endAngleRadians)};
263 actor.RegisterProperty("endAngle", endPolar);
266 void ArcNode::GetEndVectorWithDiffAngle(float startAngle, float diffAngle, Vector2& endVector)
268 float endAngle = 0.f;
270 if(diffAngle <= 0.001f)
272 //0.001 is used to ensure is empty arc when startAngle = endAngle + 360 * N
273 endAngle = startAngle + 0.001f;
275 else if(diffAngle >= 360.f)
277 endAngle = diffAngle + 359.99f;
281 endAngle = startAngle + 360.0f + diffAngle;
283 endVector.x = cosf(endAngle * Math::PI_OVER_180);
284 endVector.y = sinf(endAngle * Math::PI_OVER_180);
287 } // namespace Loader
288 } // namespace Scene3D