• 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 "scene.h"
17 
18 #include <scene/ext/util.h>
19 
20 #include <render/intf_render_context.h>
21 
22 #include "component_factory.h"
23 #include "core/internal_scene.h"
24 #include "render_configuration.h"
25 
SCENE_BEGIN_NAMESPACE()26 SCENE_BEGIN_NAMESPACE()
27 
28 SceneObject::~SceneObject()
29 {
30     if (internal_) {
31         if (updateTask_) {
32             internal_->GetContext()->GetRenderQueue()->CancelTask(updateTask_);
33         }
34         // we attach asset loader to the scene, so destroy the attachments in engine thread
35         BASE_NS::vector<META_NS::IObject::Ptr> attachments = GetAttachments({}, false);
36         for (auto&& v : attachments) {
37             Detach(v);
38         }
39         internal_
40             ->AddTask([&, atts = BASE_NS::move(attachments)]() mutable {
41                 atts.clear();
42                 internal_->Uninitialize();
43                 internal_.reset();
44             })
45             .Wait();
46     }
47 }
48 
Build(const META_NS::IMetadata::Ptr & d)49 bool SceneObject::Build(const META_NS::IMetadata::Ptr& d)
50 {
51     bool res = Super::Build(d);
52     if (res) {
53         auto context = GetInterfaceBuildArg<IRenderContext>(d, "RenderContext");
54         if (!context) {
55             CORE_LOG_E("Invalid parameters to construct Scene");
56             return false;
57         }
58         auto opts = GetBuildArg<SceneOptions>(d, "Options");
59         auto in = CreateShared<InternalScene>(GetSelf<IScene>(), BASE_NS::move(context), BASE_NS::move(opts));
60 
61         internal_ = in;
62         in->SetSelf(internal_);
63         AddBuiltinComponentFactories(internal_);
64         res = internal_->Initialize();
65     }
66     return res;
67 }
68 
InitDynamicProperty(const META_NS::IProperty::Ptr & p,BASE_NS::string_view path)69 bool SceneObject::InitDynamicProperty(const META_NS::IProperty::Ptr& p, BASE_NS::string_view path)
70 {
71     if (p->GetName() == "RenderConfiguration") {
72         auto obj = CreateObject<IRenderConfiguration>(ClassId::RenderConfiguration).GetResult();
73         if (META_NS::Property<IRenderConfiguration::Ptr> t { p }) {
74             return t->SetValue(obj);
75         }
76     }
77     return false;
78 }
79 
AttachEngineProperty(const META_NS::IProperty::Ptr & p,BASE_NS::string_view path)80 bool SceneObject::AttachEngineProperty(const META_NS::IProperty::Ptr& p, BASE_NS::string_view path)
81 {
82     return false;
83 }
84 
StartAutoUpdate(META_NS::TimeSpan interval)85 void SceneObject::StartAutoUpdate(META_NS::TimeSpan interval)
86 {
87     if (updateTask_) {
88         internal_->GetContext()->GetRenderQueue()->CancelTask(updateTask_);
89     }
90     updateTask_ =
91         internal_->GetContext()->GetRenderQueue()->AddTask(META_NS::MakeCallback<META_NS::ITaskQueueTask>([&] {
92             internal_->Update();
93             return true;
94         }),
95             interval);
96 }
97 
GetRootNode() const98 Future<INode::Ptr> SceneObject::GetRootNode() const
99 {
100     return internal_->AddTask([=] { return internal_->FindNode("", {}); });
101 }
102 
CreateNode(const BASE_NS::string_view uri,META_NS::ObjectId id)103 Future<INode::Ptr> SceneObject::CreateNode(const BASE_NS::string_view uri, META_NS::ObjectId id)
104 {
105     return internal_->AddTask([=, path = BASE_NS::string(uri)] { return internal_->CreateNode(path, id); });
106 }
107 
FindNode(BASE_NS::string_view uri,META_NS::ObjectId id) const108 Future<INode::Ptr> SceneObject::FindNode(BASE_NS::string_view uri, META_NS::ObjectId id) const
109 {
110     return internal_->AddTask([=, path = BASE_NS::string(uri)] { return internal_->FindNode(path, id); });
111 }
112 
CreateObject(META_NS::ObjectId id)113 Future<META_NS::IObject::Ptr> SceneObject::CreateObject(META_NS::ObjectId id)
114 {
115     return internal_->AddTask([=] { return internal_->CreateObject(id); });
116 }
117 
ReleaseNode(INode::Ptr && node,bool recursive)118 Future<bool> SceneObject::ReleaseNode(INode::Ptr&& node, bool recursive)
119 {
120     return internal_->AddTask(
121         [=, n = BASE_NS::move(node)]() mutable { return internal_->ReleaseNode(BASE_NS::move(n), recursive); });
122 }
123 
RemoveNode(const INode::Ptr & node)124 Future<bool> SceneObject::RemoveNode(const INode::Ptr& node)
125 {
126     return internal_->AddTask([=] { return internal_->RemoveNode(node); });
127 }
128 
GetCameras() const129 Future<BASE_NS::vector<ICamera::Ptr>> SceneObject::GetCameras() const
130 {
131     return internal_->AddTask([=] { return internal_->GetCameras(); });
132 }
133 
GetAnimations() const134 Future<BASE_NS::vector<META_NS::IAnimation::Ptr>> SceneObject::GetAnimations() const
135 {
136     return internal_->AddTask([=] { return internal_->GetAnimations(); });
137 }
138 
GetInternalScene() const139 IInternalScene::Ptr SceneObject::GetInternalScene() const
140 {
141     return internal_;
142 }
143 
SetRenderMode(RenderMode mode)144 Future<bool> SceneObject::SetRenderMode(RenderMode mode)
145 {
146     return internal_->AddTask([=] { return internal_->SetRenderMode(mode); });
147 }
GetRenderMode() const148 Future<RenderMode> SceneObject::GetRenderMode() const
149 {
150     return internal_->AddTask([=] { return internal_->GetRenderMode(); });
151 }
GetComponent(const INode::Ptr & node,BASE_NS::string_view componentName) const152 IComponent::Ptr SceneObject::GetComponent(const INode::Ptr& node, BASE_NS::string_view componentName) const
153 {
154     if (const auto attach = interface_cast<META_NS::IAttach>(node)) {
155         if (auto container = attach->GetAttachmentContainer(false)) {
156             if (auto component = container->FindAny<IComponent>(componentName, META_NS::TraversalType::NO_HIERARCHY)) {
157                 return component;
158             }
159         }
160     }
161     return {};
162 }
CreateComponent(const INode::Ptr & node,BASE_NS::string_view componentName)163 Future<IComponent::Ptr> SceneObject::CreateComponent(const INode::Ptr& node, BASE_NS::string_view componentName)
164 {
165     return internal_->AddTask(
166         [=, name = BASE_NS::string(componentName)] { return internal_->CreateEcsComponent(node, name); });
167 }
CastRay(const BASE_NS::Math::Vec3 & pos,const BASE_NS::Math::Vec3 & dir,const RayCastOptions & options) const168 Future<NodeHits> SceneObject::CastRay(
169     const BASE_NS::Math::Vec3& pos, const BASE_NS::Math::Vec3& dir, const RayCastOptions& options) const
170 {
171     return internal_->AddTask([=] {
172         RayCastOptions ops;
173         if (ops.layerMask == NONE_LAYER_MASK) {
174             ops.layerMask = ALL_LAYER_MASK;
175         }
176         NodeHits result;
177         if (auto ir = interface_cast<IInternalRayCast>(internal_)) {
178             result = ir->CastRay(pos, dir, ops);
179         }
180         return result;
181     });
182 }
183 
184 SCENE_END_NAMESPACE()
185