• 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 
59     ownerManager->Create(entity);
60     const auto ownerHandle = ownerManager->Write(entity);
61     if (!ownerHandle) {
62         ecs->GetEntityManager().Destroy(entity);
63         ecs->GetEntityManager().Destroy(handle->mesh);
64         return {};
65     }
66     ownerHandle->entity = ecs->GetEntityManager().GetReferenceCounted(handle->mesh);
67     return entity;
68 }
69 
Init(const IInternalRenderMesh::Ptr & rmesh)70 bool MeshNode::Init(const IInternalRenderMesh::Ptr& rmesh)
71 {
72     auto ent = rmesh->Mesh()->GetValue();
73     if (!CORE_NS::EntityUtil::IsValid(ent)) {
74         return false;
75     }
76     auto ecsobj = object_->GetScene()->GetEcsContext().GetEcsObject(ent);
77     auto res = Init(ecsobj);
78     return res;
79 }
80 
Init(const IEcsObject::Ptr & ecsobj)81 bool MeshNode::Init(const IEcsObject::Ptr& ecsobj)
82 {
83     if (!ecsobj) {
84         return false;
85     }
86     mesh_ = META_NS::GetObjectRegistry().Create<IMesh>(ClassId::Mesh);
87     if (!mesh_) {
88         return false;
89     }
90     if (auto acc = interface_cast<IEcsObjectAccess>(mesh_)) {
91         if (!acc->SetEcsObject(ecsobj)) {
92             return false;
93         }
94     }
95     if (auto morph = GetAttachments({ IMorpher::UID }, false); !morph.empty()) {
96         Morpher()->SetValue(interface_pointer_cast<IMorpher>(morph.front()));
97     }
98     return true;
99 }
100 
SetOwnedEntity(CORE_NS::Entity ent)101 void MeshNode::SetOwnedEntity(CORE_NS::Entity ent)
102 {
103     if (auto obj = GetEcsObject()) {
104         auto ecs = obj->GetScene()->GetEcsContext().GetNativeEcs();
105         auto ownerManager = CORE_NS::GetManager<IEntityOwnerComponentManager>(*ecs);
106         if (ownerManager) {
107             if (auto ownerHandle = ownerManager->Write(obj->GetEntity())) {
108                 ownerHandle->entity = ecs->GetEntityManager().GetReferenceCounted(ent);
109             }
110         }
111     }
112 }
113 
SetMesh(const IMesh::Ptr & m)114 Future<bool> MeshNode::SetMesh(const IMesh::Ptr& m)
115 {
116     if (auto obj = GetEcsObject()) {
117         auto scene = obj->GetScene();
118         return scene->AddTask([=] {
119             IMesh::Ptr mesh = m;
120             // in case it is mesh node, use the embedded mesh
121             if (auto acc = interface_cast<IMeshAccess>(mesh)) {
122                 mesh = acc->GetMesh().GetResult();
123             }
124             if (auto objacc = interface_cast<IEcsObjectAccess>(mesh)) {
125                 if (auto obj = objacc->GetEcsObject()) {
126                     auto att = GetSelf<META_NS::IAttach>()->GetAttachments<IInternalRenderMesh>();
127                     if (!att.empty()) {
128                         auto prop = att.front()->Mesh();
129                         prop->SetValue(obj->GetEntity());
130                         scene->SyncProperty(prop, META_NS::EngineSyncDirection::TO_ENGINE);
131                         mesh_ = mesh;
132                         SetOwnedEntity(obj->GetEntity());
133                         return true;
134                     }
135                 }
136             }
137             return false;
138         });
139     }
140     return {};
141 }
GetMesh() const142 Future<IMesh::Ptr> MeshNode::GetMesh() const
143 {
144     if (auto obj = GetEcsObject()) {
145         auto scene = obj->GetScene();
146         return scene->AddTask([=] { return mesh_; });
147     }
148     return {};
149 }
150 
151 SCENE_END_NAMESPACE()
152