• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "mesh_node.h"
17 
18 #include <3d/ecs/components/mesh_component.h>
19 #include <3d/util/intf_scene_util.h>
20 
21 #include <meta/api/make_callback.h>
22 #include <meta/interface/property/array_property.h>
23 
24 #include "ecs_component/entity_owner_component.h"
25 #include "../mesh/submesh.h"
26 
SCENE_BEGIN_NAMESPACE()27 SCENE_BEGIN_NAMESPACE()
28 
29 bool MeshNode::SetEcsObject(const IEcsObject::Ptr& o)
30 {
31     if (Super::SetEcsObject(o)) {
32         auto att = GetSelf<META_NS::IAttach>()->GetAttachments<IInternalRenderMesh>();
33         if (!att.empty()) {
34             return Init(att.front());
35         }
36     }
37     return false;
38 }
39 
CreateEntity(const IInternalScene::Ptr & scene)40 CORE_NS::Entity MeshNode::CreateEntity(const IInternalScene::Ptr& scene)
41 {
42     const auto& ecs = scene->GetEcsContext().GetNativeEcs();
43     const auto renderMeshManager = CORE_NS::GetManager<CORE3D_NS::IRenderMeshComponentManager>(*ecs);
44     const auto ownerManager = CORE_NS::GetManager<IEntityOwnerComponentManager>(*ecs);
45     const auto meshManager = CORE_NS::GetManager<CORE3D_NS::IMeshComponentManager>(*ecs);
46     if (!renderMeshManager || !meshManager || !ownerManager) {
47         return {};
48     }
49     const auto entity = ecs->GetEntityManager().Create();
50     renderMeshManager->Create(entity);
51     const auto handle = renderMeshManager->Write(entity);
52     if (!handle) {
53         ecs->GetEntityManager().Destroy(entity);
54         return {};
55     }
56     handle->mesh = ecs->GetEntityManager().Create();
57     meshManager->Create(handle->mesh);
58     ownerManager->Create(entity);
59     const auto ownerHandle = ownerManager->Write(entity);
60     if (!ownerHandle) {
61         ecs->GetEntityManager().Destroy(entity);
62         ecs->GetEntityManager().Destroy(handle->mesh);
63         return {};
64     }
65     ownerHandle->entity = ecs->GetEntityManager().GetReferenceCounted(handle->mesh);
66     return entity;
67 }
Init(IInternalRenderMesh::Ptr rmesh)68 bool MeshNode::Init(IInternalRenderMesh::Ptr rmesh)
69 {
70     auto ent = rmesh->Mesh()->GetValue();
71     if (!CORE_NS::EntityUtil::IsValid(ent)) {
72         return false;
73     }
74     auto ecsobj = object_->GetScene()->GetEcsContext().GetEcsObject(ent);
75     auto res = Init(ecsobj);
76     return res;
77 }
Init(IEcsObject::Ptr ecsobj)78 bool MeshNode::Init(IEcsObject::Ptr ecsobj)
79 {
80     if (!ecsobj) {
81         return false;
82     }
83     mesh_ = META_NS::GetObjectRegistry().Create<IMesh>(ClassId::Mesh);
84     if (!mesh_) {
85         return false;
86     }
87     if (auto acc = interface_cast<IEcsObjectAccess>(mesh_)) {
88         if (!acc->SetEcsObject(ecsobj)) {
89             return false;
90         }
91     }
92     return true;
93 }
94 
GetSubmeshes() const95 Future<BASE_NS::vector<ISubMesh::Ptr>> MeshNode::GetSubmeshes() const
96 {
97     if (auto obj = GetEcsObject()) {
98         auto scene = obj->GetScene();
99         return scene->AddTask([=] { return mesh_->GetSubmeshes().GetResult(); });
100         // this is not safe, but what can we do. Not allowed to change the submeshes while override is on
101     }
102     return {};
103         }
SetSubmeshes(const BASE_NS::vector<ISubMesh::Ptr> & s)104 Future<bool> MeshNode::SetSubmeshes(const BASE_NS::vector<ISubMesh::Ptr>& s)
105 {
106     if (auto obj = GetEcsObject()) {
107         auto scene = obj->GetScene();
108         return scene->AddTask([=] { return mesh_->SetSubmeshes(s).GetResult(); });
109     }
110     return {};
111 }
112 
SetOwnedEntity(CORE_NS::Entity ent)113 void MeshNode::SetOwnedEntity(CORE_NS::Entity ent)
114 {
115     if (auto obj = GetEcsObject()) {
116         auto ecs = obj->GetScene()->GetEcsContext().GetNativeEcs();
117         auto ownerManager = CORE_NS::GetManager<IEntityOwnerComponentManager>(*ecs);
118         if (ownerManager) {
119             if (auto ownerHandle = ownerManager->Write(obj->GetEntity())) {
120                 ownerHandle->entity = ecs->GetEntityManager().GetReferenceCounted(ent);
121             }
122         }
123     }
124 }
SetMesh(const IMesh::Ptr & m)125 Future<bool> MeshNode::SetMesh(const IMesh::Ptr& m)
126 {
127     if (auto obj = GetEcsObject()) {
128         auto scene = obj->GetScene();
129         return scene->AddTask([=] {
130             IMesh::Ptr mesh = m;
131             if (auto acc = interface_cast<IMeshAccess>(mesh)) {
132                 mesh = acc->GetMesh().GetResult();
133             }
134             if (auto objacc = interface_cast<IEcsObjectAccess>(mesh)) {
135                 if (auto obj = objacc->GetEcsObject()) {
136                     auto att = GetSelf<META_NS::IAttach>()->GetAttachments<IInternalRenderMesh>();
137                     if (!att.empty()) {
138                         att.front()->Mesh()->SetValue(obj->GetEntity());
139                         mesh_ = mesh;
140                         SetOwnedEntity(obj->GetEntity());
141                         return true;
142                     }
143                 }
144             }
145             return false;
146         });
147     }
148     return {};
149 }
GetMesh() const150 Future<IMesh::Ptr> MeshNode::GetMesh() const
151 {
152     if (auto obj = GetEcsObject()) {
153         auto scene = obj->GetScene();
154         return scene->AddTask([=] { return mesh_; });
155     }
156     return {};
157 }
158 
159 SCENE_END_NAMESPACE()
160