• 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 #include "../core/camera.h"
25 #include "../core/intf_internal_raycast.h"
26 #include "../entity_converting_value.h"
27 #include "../postprocess/postprocess.h"
28 
29 META_TYPE(CORE3D_NS::CameraComponent::TargetUsage)
30 
31 SCENE_BEGIN_NAMESPACE()
32 
33 namespace {
34 struct FormatConverter {
35     using SourceType = ColorFormat;
36     using TargetType = CORE3D_NS::CameraComponent::TargetUsage;
37 
ConvertToSource__anon09d2bbb60111::FormatConverter38     static SourceType ConvertToSource(META_NS::IAny&, const TargetType& v)
39     {
40         return ColorFormat { v.format, v.usageFlags };
41     }
ConvertToTarget__anon09d2bbb60111::FormatConverter42     static TargetType ConvertToTarget(const SourceType& v)
43     {
44         return CORE3D_NS::CameraComponent::TargetUsage { v.format, v.usageFlags };
45     }
46 };
47 } // namespace
48 
Build(const META_NS::IMetadata::Ptr & d)49 bool CameraComponent::Build(const META_NS::IMetadata::Ptr& d)
50 {
51     return Super::Build(d);
52 }
InitDynamicProperty(const META_NS::IProperty::Ptr & p,BASE_NS::string_view path)53 bool CameraComponent::InitDynamicProperty(const META_NS::IProperty::Ptr& p, BASE_NS::string_view path)
54 {
55     if (p->GetName() == "PostProcess") {
56         auto ep = object_->CreateEngineProperty(path).GetResult();
57         auto i = interface_cast<META_NS::IStackProperty>(p);
58         return ep && i &&
59                i->PushValue(META_NS::IValue::Ptr(
60                    new InterfacePtrEntityValue<IPostProcess>(ep, { object_->GetScene(), ClassId::PostProcess })));
61     }
62     if (p->GetName() == "ColorTargetCustomization") {
63         auto ep = object_->CreateEngineProperty(path).GetResult();
64         auto i = interface_cast<META_NS::IStackProperty>(p);
65         return ep && i && i->PushValue(META_NS::IValue::Ptr(new ConvertingArrayValue<FormatConverter>(ep)));
66     }
67     return false;
68 }
GetName() const69 BASE_NS::string CameraComponent::GetName() const
70 {
71     return "CameraComponent";
72 }
SetActive(bool active)73 Future<bool> CameraComponent::SetActive(bool active)
74 {
75     auto flags = SceneFlags()->GetValue();
76     if (active) {
77         flags |= static_cast<uint32_t>(CameraSceneFlag::ACTIVE_RENDER_BIT);
78     } else {
79         flags &= ~static_cast<uint32_t>(CameraSceneFlag::ACTIVE_RENDER_BIT | CameraSceneFlag::MAIN_CAMERA_BIT);
80     }
81     SceneFlags()->SetValue(flags);
82     return SyncProperty(object_->GetScene(), SceneFlags());
83 }
SetRenderTarget(const IRenderTarget::Ptr & target)84 Future<bool> CameraComponent::SetRenderTarget(const IRenderTarget::Ptr& target)
85 {
86     auto scene = object_->GetScene();
87     return scene->AddTask([=] {
88         bool res = UpdateCameraRenderTarget(object_, target);
89         if (res) {
90             if (target) {
91                 if (interface_cast<META_NS::IDynamicResource>(target)) {
92                     scene->AddRenderingCamera(GetSelf<IInternalCamera>());
93                 }
94             } else {
95                 scene->RemoveRenderingCamera(GetSelf<IInternalCamera>());
96             }
97             renderTarget_ = target;
98         }
99         return res;
100     });
101 }
IsActive() const102 bool CameraComponent::IsActive() const
103 {
104     return SceneFlags()->GetValue() & static_cast<uint32_t>(CameraSceneFlag::ACTIVE_RENDER_BIT);
105 }
NotifyRenderTargetChanged()106 void CameraComponent::NotifyRenderTargetChanged()
107 {
108     if (renderTarget_ && IsActive()) {
109         auto scene = object_->GetScene();
110         if (auto dr = interface_pointer_cast<META_NS::IDynamicResource>(renderTarget_)) {
111             if (dr->EventOnResourceChanged(META_NS::MetadataQuery::EXISTING)) {
112                 scene->AddTask(
113                     [dr] { META_NS::Invoke<META_NS::IOnChanged>(dr->OnResourceChanged()); }, scene->GetAppTaskQueue());
114             }
115         }
116     }
117 }
118 
CastRay(const BASE_NS::Math::Vec2 & pos,const RayCastOptions & options) const119 Future<NodeHits> CameraComponent::CastRay(const BASE_NS::Math::Vec2& pos, const RayCastOptions& options) const
120 {
121     auto scene = object_->GetScene();
122     return scene->AddTask([=] {
123         RayCastOptions ops = options;
124         if (ops.layerMask == NONE_LAYER_MASK) {
125             ops.layerMask = LayerMask()->GetValue();
126         }
127         NodeHits result;
128         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
129             result = ir->CastRay(object_, pos, ops);
130         }
131         return result;
132     });
133 }
ScreenPositionToWorld(const BASE_NS::Math::Vec3 & pos) const134 Future<BASE_NS::Math::Vec3> CameraComponent::ScreenPositionToWorld(const BASE_NS::Math::Vec3& pos) const
135 {
136     auto scene = object_->GetScene();
137     return scene->AddTask([=] {
138         BASE_NS::Math::Vec3 result;
139         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
140             result = ir->ScreenPositionToWorld(object_, pos);
141         }
142         return result;
143     });
144 }
WorldPositionToScreen(const BASE_NS::Math::Vec3 & pos) const145 Future<BASE_NS::Math::Vec3> CameraComponent::WorldPositionToScreen(const BASE_NS::Math::Vec3& pos) const
146 {
147     auto scene = object_->GetScene();
148     return scene->AddTask([=] {
149         BASE_NS::Math::Vec3 result;
150         if (auto ir = interface_cast<IInternalRayCast>(scene)) {
151             result = ir->WorldPositionToScreen(object_, pos);
152         }
153         return result;
154     });
155 }
156 SCENE_END_NAMESPACE()