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()27SCENE_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)40CORE_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)68bool 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)78bool 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() const95Future<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)104Future<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)113void 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)125Future<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() const150Future<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