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 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)70bool 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)81bool 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)101void 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)114Future<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() const142Future<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