/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*
*/
-// EXTERNAL
-#include "dali/devel-api/common/map-wrapper.h"
-#include "dali/public-api/animation/constraints.h"
+// CLASS HEADER
+#include <dali-scene3d/public-api/loader/scene-definition.h>
+
+// EXTERNAL INCLUDES
+#include <dali/devel-api/common/map-wrapper.h>
+#include <dali/public-api/animation/constraints.h>
// INTERNAL
-#include "dali-scene3d/internal/graphics/builtin-shader-extern-gen.h"
-#include "dali-scene3d/public-api/loader/blend-shape-details.h"
-#include "dali-scene3d/public-api/loader/scene-definition.h"
-#include "dali-scene3d/public-api/loader/skinning-details.h"
-#include "dali-scene3d/public-api/loader/utils.h"
+#include <dali-scene3d/internal/graphics/builtin-shader-extern-gen.h>
+#include <dali-scene3d/internal/model-components/model-node-impl.h>
+#include <dali-scene3d/public-api/loader/blend-shape-details.h>
+#include <dali-scene3d/public-api/loader/skinning-details.h>
+#include <dali-scene3d/public-api/loader/utils.h>
-//#define DEBUG_SCENE_DEFINITION
-//#define DEBUG_JOINTS
+// #define DEBUG_SCENE_DEFINITION
+// #define DEBUG_JOINTS
#if defined(DEBUG_SCENE_DEFINITION) || defined(DEBUG_JOINTS)
#define DEBUG_ONLY(x) x
#define LOGD(x) DEBUG_ONLY(printf x; printf("\n"); fflush(stdout))
-namespace Dali
-{
-namespace Scene3D
-{
-namespace Loader
+namespace Dali::Scene3D::Loader
{
namespace
{
-const std::string JOINT_MATRIX{"jointMatrix"};
-
-const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)> sConstraintFactory = {
- {Property::Type::BOOLEAN,
- [](Actor& a, Property::Index i) {
- return Constraint::New<bool>(a, i, [](bool& current, const PropertyInputContainer& inputs) {
- current = inputs[0]->GetBoolean();
- });
- }},
- {Property::Type::INTEGER,
- [](Actor& a, Property::Index i) {
- return Constraint::New<int>(a, i, [](int& current, const PropertyInputContainer& inputs) {
- current = inputs[0]->GetInteger();
- });
- }},
- {Property::Type::FLOAT,
- [](Actor& a, Property::Index i) {
- return Constraint::New<float>(a, i, EqualToConstraint());
- }},
- {Property::Type::VECTOR2,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Vector2>(a, i, EqualToConstraint());
- }},
- {Property::Type::VECTOR3,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Vector3>(a, i, EqualToConstraint());
- }},
- {Property::Type::VECTOR4,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Vector4>(a, i, EqualToConstraint());
- }},
- {Property::Type::MATRIX,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Matrix>(a, i, EqualToConstraint());
- }},
- {Property::Type::MATRIX3,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Matrix3>(a, i, EqualToConstraint());
- }},
- {Property::Type::ROTATION,
- [](Actor& a, Property::Index i) {
- return Constraint::New<Quaternion>(a, i, EqualToConstraint());
- }},
-};
+
+const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)>& GetConstraintFactory()
+{
+ static const std::map<Property::Type, Constraint (*)(Actor&, Property::Index)> sConstraintFactory = {
+ {Property::Type::BOOLEAN,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<bool>(a, i, [](bool& current, const PropertyInputContainer& inputs) {
+ current = inputs[0]->GetBoolean();
+ });
+ }},
+ {Property::Type::INTEGER,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<int>(a, i, [](int& current, const PropertyInputContainer& inputs) {
+ current = inputs[0]->GetInteger();
+ });
+ }},
+ {Property::Type::FLOAT,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<float>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::VECTOR2,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector2>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::VECTOR3,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector3>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::VECTOR4,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Vector4>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::MATRIX,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Matrix>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::MATRIX3,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Matrix3>(a, i, EqualToConstraint());
+ }},
+ {Property::Type::ROTATION,
+ [](Actor& a, Property::Index i) {
+ return Constraint::New<Quaternion>(a, i, EqualToConstraint());
+ }},
+ };
+ return sConstraintFactory;
+}
struct ResourceReflector : IResourceReflector
{
{
mCreationContext.mXforms.modelStack.Push(n.GetLocalSpace());
- Actor a = n.CreateActor(mCreationContext);
+ ModelNode a = n.CreateModelNode(mCreationContext);
if(!mActorStack.empty())
{
mActorStack.back().Add(a);
mCreationContext.mXforms.modelStack.Pop();
}
- Actor GetRoot() const
+ ModelNode GetRoot() const
{
return mRoot;
}
private:
NodeDefinition::CreateParams& mCreationContext;
- std::vector<Actor> mActorStack;
- Actor mRoot;
+ std::vector<ModelNode> mActorStack;
+ ModelNode mRoot;
};
bool IsAncestor(const SceneDefinition& scene, Index ancestor, Index node, Index rootHint = INVALID_INDEX)
propJointMatrix = ConfigureJointMatrix(parent, ancestor, propJointMatrix);
}
- auto myPropJointMatrix = actor.GetPropertyIndex(JOINT_MATRIX);
+ auto myPropJointMatrix = actor.GetPropertyIndex(Skinning::JOINT_MATRIX);
if(myPropJointMatrix == Property::INVALID_INDEX)
{
- myPropJointMatrix = actor.RegisterProperty(JOINT_MATRIX, Matrix{false});
+ myPropJointMatrix = actor.RegisterProperty(Skinning::JOINT_MATRIX, Matrix{false});
Constraint constraint = Constraint::New<Matrix>(actor, propJointMatrix, [](Matrix& output, const PropertyInputContainer& inputs) {
Matrix jointMatrix{false};
jointMatrix.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
requests.end());
}
-void ConfigureBoneMatrix(const Matrix& ibm, Actor joint, Shader& shader, Index& boneIdx)
+void ConfigureBoneMatrix(const Matrix& ibm, ModelNode joint, ModelPrimitive primitive, Index& boneIdx)
{
// Register bone transform on shader.
- char propertyNameBuffer[32];
- snprintf(propertyNameBuffer, sizeof(propertyNameBuffer), "%s[%d]", Skinning::BONE_UNIFORM_NAME.c_str(), boneIdx);
- DALI_ASSERT_DEBUG(shader.GetPropertyIndex(propertyNameBuffer) == Property::INVALID_INDEX);
- auto propBoneXform = shader.RegisterProperty(propertyNameBuffer, Matrix{false});
-
- // Constrain bone matrix to joint transform.
- Constraint constraint = Constraint::New<Matrix>(shader, propBoneXform, [ibm](Matrix& output, const PropertyInputContainer& inputs) {
- Matrix::Multiply(output, ibm, inputs[0]->GetMatrix());
- });
-
- auto propJointMatrix = joint.GetPropertyIndex(JOINT_MATRIX);
- constraint.AddSource(Source{joint, propJointMatrix});
- constraint.Apply();
-
+ Internal::GetImplementation(joint).SetBoneMatrix(ibm, primitive, boneIdx);
++boneIdx;
}
NodeDefinition* SceneDefinition::GetNode(Index iNode)
{
- return mNodes[iNode].get();
+ if(iNode != Scene3D::Loader::INVALID_INDEX && iNode < mNodes.size())
+ {
+ return mNodes[iNode].get();
+ }
+ return nullptr;
}
void SceneDefinition::Visit(Index iNode, const Customization::Choices& choices, NodeDefinition::IVisitor& v)
Visit(iNode, choices, refCounterVisitor);
}
-Actor SceneDefinition::CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params)
+ModelNode SceneDefinition::CreateNodes(Index iNode, const Customization::Choices& choices, NodeDefinition::CreateParams& params)
{
ActorCreatorVisitor actorCreatorVisitor(params);
if(iTarget != Property::INVALID_INDEX)
{
auto propertyType = cr.mTarget.GetPropertyType(iTarget);
- auto iFind = sConstraintFactory.find(propertyType);
- if(iFind == sConstraintFactory.end())
+ auto iFind = GetConstraintFactory().find(propertyType);
+ if(iFind == GetConstraintFactory().end())
{
onError(FormatString("node '%s': Property '%s' has unsupported type '%s'; ignored.",
sourceName,
auto rootJoint = root.FindChildByName(node->mName);
DALI_ASSERT_ALWAYS(!!rootJoint);
- DALI_ASSERT_DEBUG(rootJoint.GetPropertyIndex(JOINT_MATRIX) == Property::INVALID_INDEX);
- auto propJointMatrix = rootJoint.RegisterProperty(JOINT_MATRIX, Matrix{false});
+ DALI_ASSERT_DEBUG(rootJoint.GetPropertyIndex(Skinning::JOINT_MATRIX) == Property::INVALID_INDEX);
+ auto propJointMatrix = rootJoint.RegisterProperty(Skinning::JOINT_MATRIX, Matrix{false});
Constraint constraint = Constraint::New<Matrix>(rootJoint, propJointMatrix, [](Matrix& output, const PropertyInputContainer& inputs) {
output.SetTransformComponents(Vector3::ONE, inputs[0]->GetQuaternion(), inputs[1]->GetVector3());
});
for(auto& joint : skeleton.mJoints)
{
auto node = GetNode(joint.mNodeIdx);
- Actor actor = rootActor.FindChildByName(node->mName);
- ConfigureBoneMatrix(joint.mInverseBindMatrix, actor, request.mShader, boneIdx);
+ ModelNode modelNode = ModelNode::DownCast(rootActor.FindChildByName(node->mName));
+ if(!modelNode)
+ {
+ continue;
+ }
+ ConfigureBoneMatrix(joint.mInverseBindMatrix, modelNode, request.mPrimitive, boneIdx);
}
}
}
if(mesh.first.HasBlendShapes())
{
Actor actor = rootActor.FindChildByName(node->mName);
-
- // Sets the property to be animated.
- BlendShapes::ConfigureProperties(mesh, i.mShader, actor);
+ Scene3D::ModelNode node = Scene3D::ModelNode::DownCast(actor);
+ if(!node)
+ {
+ continue;
+ }
+ BlendShapes::BlendShapeData data;
+ data.components = 0x0;
+ for(auto&& blendShape : mesh.first.mBlendShapes)
+ {
+ data.weights.push_back(blendShape.weight);
+ data.components |= (blendShape.deltas.IsDefined() * BlendShapes::Component::POSITIONS) |
+ (blendShape.normals.IsDefined() * BlendShapes::Component::NORMALS) | (blendShape.tangents.IsDefined() * BlendShapes::Component::TANGENTS);
+ }
+ for(auto&& factor : mesh.second.blendShapeUnnormalizeFactor)
+ {
+ data.unnormalizeFactors.push_back(factor);
+ }
+ data.version = mesh.first.mBlendShapeVersion;
+ data.bufferOffset = mesh.second.blendShapeBufferOffset;
+ data.mActor = actor;
+ Internal::GetImplementation(node).SetBlendShapeData(data, i.mPrimitive);
}
}
}
return success;
}
-} // namespace Loader
-} // namespace Scene3D
-} // namespace Dali
+} // namespace Dali::Scene3D::Loader