• 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 "camera_component.h"
17 
18 #include <scene/ext/util.h>
19 
20 #include <3d/ecs/components/camera_component.h>
21 
22 #include <meta/interface/intf_event.h>
23 #include <meta/interface/resource/intf_dynamic_resource.h>
24 
25 #include "core/camera.h"
26 #include "core/intf_internal_raycast.h"
27 #include "entity_converting_value.h"
28 #include "postprocess/postprocess.h"
29 
30 META_TYPE(CORE3D_NS::CameraComponent::TargetUsage)
31 
32 SCENE_BEGIN_NAMESPACE()
33 
34 namespace {
35 struct FormatConverter {
36     using SourceType = ColorFormat;
37     using TargetType = CORE3D_NS::CameraComponent::TargetUsage;
38 
ConvertToSource__anon5a911c580111::FormatConverter39     static SourceType ConvertToSource(META_NS::IAny&, const TargetType& v)
40     {
41         return ColorFormat { v.format, v.usageFlags };
42     }
ConvertToTarget__anon5a911c580111::FormatConverter43     static TargetType ConvertToTarget(const SourceType& v)
44     {
45         return CORE3D_NS::CameraComponent::TargetUsage { v.format, v.usageFlags };
46     }
47 };
48 } // namespace
49 
Build(const META_NS::IMetadata::Ptr & d)50 bool CameraComponent::Build(const META_NS::IMetadata::Ptr& d)
51 {
52     return Super::Build(d);
53 }
InitDynamicProperty(const META_NS::IProperty::Ptr & p,BASE_NS::string_view path)54 bool CameraComponent::InitDynamicProperty(const META_NS::IProperty::Ptr& p, BASE_NS::string_view path)
55 {
56     if (p->GetName() == "PostProcess") {
57         auto ep = object_->CreateProperty(path).GetResult();
58         auto i = interface_cast<META_NS::IStackProperty>(p);
59         return ep && i &&
60                i->PushValue(META_NS::IValue::Ptr(
61                    new InterfacePtrEntityValue<IPostProcess>(ep, { object_->GetScene(), ClassId::PostProcess })));
62     }
63     if (p->GetName() == "ColorTargetCustomization") {
64         auto ep = object_->CreateProperty(path).GetResult();
65         auto i = interface_cast<META_NS::IStackProperty>(p);
66         return ep && i && i->PushValue(META_NS::IValue::Ptr(new ConvertingArrayValue<FormatConverter>(ep)));
67     }
68     return false;
69 }
GetName() const70 BASE_NS::string CameraComponent::GetName() const
71 {
72     return "CameraComponent";
73 }
SetActive(bool active)74 Future<bool> CameraComponent::SetActive(bool active)
75 {
76     auto flags = SceneFlags()->GetValue();
77     if (active) {
78         flags |= uint32_t(CameraSceneFlag::ACTIVE_RENDER_BIT);
79     } else {
80         flags &= ~uint32_t(CameraSceneFlag::ACTIVE_RENDER_BIT | CameraSceneFlag::MAIN_CAMERA_BIT);
81     }
82     SceneFlags()->SetValue(flags);
83     return SyncProperty(object_->GetScene(), SceneFlags());
84 }
SetRenderTarget(const IRenderTarget::Ptr & target)85 Future<bool> CameraComponent::SetRenderTarget(const IRenderTarget::Ptr& target)
86 {
87     auto scene = object_->GetScene();
88     return scene->AddTask([=] {
89         bool res = UpdateCameraRenderTarget(object_, target);
90         if (res) {
91             if (target) {
92                 if (interface_cast<META_NS::IDynamicResource>(target)) {
93                     scene->AddRenderingCamera(GetSelf<IInternalCamera>());
94                 }
95             } else {
96                 scene->RemoveRenderingCamera(GetSelf<IInternalCamera>());
97             }
98             renderTarget_ = target;
99         }
100         return res;
101     });
102 }
IsActive() const103 bool CameraComponent::IsActive() const
104 {
105     return uint32_t(SceneFlags()->GetValue()) & uint32_t(CameraSceneFlag::ACTIVE_RENDER_BIT);
106 }
NotifyRenderTargetChanged()107 void CameraComponent::NotifyRenderTargetChanged()
108 {
109     if (renderTarget_ && IsActive()) {
110         auto scene = object_->GetScene();
111         if (auto dr = interface_pointer_cast<META_NS::IDynamicResource>(renderTarget_)) {
112             // anyone listening?
113             if (dr->EventOnResourceChanged(META_NS::MetadataQuery::EXISTING)) {
114                 scene->AddTask([dr] { META_NS::Invoke<META_NS::IOnChanged>(dr->OnResourceChanged()); },
115                     scene->GetContext()->GetApplicationQueue());
116             }
117         }
118     }
119 }
120 
Attaching(const IAttach::Ptr & target,const IObject::Ptr & dataContext)121 bool CameraComponent::Attaching(const IAttach::Ptr& target, const IObject::Ptr& dataContext)
122 {
123     if (target) {
124         META_NS::IContainer::FindOptions options;
125         options.behavior = META_NS::TraversalType::NO_HIERARCHY;
126         options.uids = { IInputReceiver::UID };
127         options.strict = false;
128         inputReceivers_.SetTarget(target->GetAttachmentContainer(), options);
129     }
130     return true;
131 }
132 
Detaching(const IAttach::Ptr & target)133 bool CameraComponent::Detaching(const IAttach::Ptr& target)
134 {
135     inputReceivers_.Reset();
136     return true;
137 }
138 
SendInputEvent(PointerEvent & event)139 void CameraComponent::SendInputEvent(PointerEvent& event)
140 {
141     if (inputReceivers_.HasTarget() && !event.handled) {
142         for (auto&& receiver : inputReceivers_.FindAll()) {
143             receiver->OnInput(event);
144             if (event.handled) {
145                 // Stop iteration if event.handled = true
146                 return;
147             }
148         }
149     }
150 }
151 
CastRay(const BASE_NS::Math::Vec2 & pos,const RayCastOptions & options) const152 Future<NodeHits> CameraComponent::CastRay(const BASE_NS::Math::Vec2& pos, const RayCastOptions& options) const
153 {
154     auto scene = object_->GetScene();
155     return scene->AddTask([=] {
156         RayCastOptions ops = options;
157         if (ops.layerMask == NONE_LAYER_MASK) {
158             ops.layerMask = LayerMask()->GetValue();
159         }
160         NodeHits result;
161         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
162             result = ir->CastRay(object_, pos, ops);
163         }
164         return result;
165     });
166 }
ScreenPositionToWorld(const BASE_NS::Math::Vec3 & pos) const167 Future<BASE_NS::Math::Vec3> CameraComponent::ScreenPositionToWorld(const BASE_NS::Math::Vec3& pos) const
168 {
169     auto scene = object_->GetScene();
170     return scene->AddTask([=] {
171         BASE_NS::Math::Vec3 result;
172         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
173             result = ir->ScreenPositionToWorld(object_, pos);
174         }
175         return result;
176     });
177 }
WorldPositionToScreen(const BASE_NS::Math::Vec3 & pos) const178 Future<BASE_NS::Math::Vec3> CameraComponent::WorldPositionToScreen(const BASE_NS::Math::Vec3& pos) const
179 {
180     auto scene = object_->GetScene();
181     return scene->AddTask([=] {
182         BASE_NS::Math::Vec3 result;
183         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
184             result = ir->WorldPositionToScreen(object_, pos);
185         }
186         return result;
187     });
188 }
189 
190 SCENE_END_NAMESPACE()
191