1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #ifndef API_ECS_SERIALIZER_ECS_ANIMATION_UTIL_H
17 #define API_ECS_SERIALIZER_ECS_ANIMATION_UTIL_H
18
19 #include <algorithm>
20
21 #include <3d/ecs/components/animation_component.h>
22 #include <3d/ecs/components/animation_track_component.h>
23 #include <3d/ecs/components/name_component.h>
24 #include <3d/ecs/systems/intf_node_system.h>
25 #include <base/containers/fixed_string.h>
26 #include <base/containers/vector.h>
27 #include <core/ecs/intf_ecs.h>
28 #include <core/property/scoped_handle.h>
29 #include <ecs_serializer/namespace.h>
30
ECS_SERIALIZER_BEGIN_NAMESPACE()31 ECS_SERIALIZER_BEGIN_NAMESPACE()
32
33 inline void UpdateAnimationTrackTargets(CORE_NS::IEcs& ecs, CORE_NS::Entity animationEntity, CORE_NS::Entity rootNode)
34 {
35 auto& nameManager_ = *CORE_NS::GetManager<CORE3D_NS::INameComponentManager>(ecs);
36 auto animationManager = CORE_NS::GetManager<CORE3D_NS::IAnimationComponentManager>(ecs);
37 auto animationTrackManager = CORE_NS::GetManager<CORE3D_NS::IAnimationTrackComponentManager>(ecs);
38 auto& entityManager = ecs.GetEntityManager();
39
40 auto* nodeSystem = CORE_NS::GetSystem<CORE3D_NS::INodeSystem>(ecs);
41 CORE_ASSERT(nodeSystem);
42 if (!nodeSystem) {
43 return;
44 }
45 auto* node = nodeSystem->GetNode(rootNode);
46 CORE_ASSERT(node);
47 if (!node) {
48 return;
49 }
50
51 if (const CORE_NS::ScopedHandle<const CORE3D_NS::AnimationComponent> animationData =
52 animationManager->Read(animationEntity);
53 animationData) {
54 BASE_NS::vector<CORE_NS::Entity> targetEntities;
55 targetEntities.reserve(animationData->tracks.size());
56 std::transform(animationData->tracks.begin(), animationData->tracks.end(), std::back_inserter(targetEntities),
57 [&nameManager = nameManager_, &node](const CORE_NS::Entity& trackEntity) {
58 if (auto nameHandle = nameManager.Read(trackEntity); nameHandle) {
59 if (nameHandle->name.empty()) {
60 return node->GetEntity();
61 } else {
62 if (auto targetNode = node->LookupNodeByPath(nameHandle->name); targetNode) {
63 return targetNode->GetEntity();
64 }
65 }
66 }
67 return CORE_NS::Entity {};
68 });
69 if (animationData->tracks.size() == targetEntities.size()) {
70 auto targetIt = targetEntities.begin();
71 for (const auto& trackEntity : animationData->tracks) {
72 if (auto track = animationTrackManager->Write(trackEntity); track) {
73 if (track->target) {
74 CORE_LOG_D("AnimationTrack %s already targetted",
75 BASE_NS::to_hex(static_cast<const CORE_NS::Entity&>(track->target).id).data());
76 }
77 track->target = entityManager.GetReferenceCounted(*targetIt);
78 }
79 ++targetIt;
80 }
81 }
82 }
83 }
84
85 ECS_SERIALIZER_END_NAMESPACE()
86
87 #endif // API_ECS_SERIALIZER_ECS_ANIMATIONUTIL_H
88