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 #ifndef SCENE_API_NODE_H
17 #define SCENE_API_NODE_H
18
19 #include <scene/api/post_process.h>
20 #include <scene/ext/intf_component.h>
21 #include <scene/interface/intf_camera.h>
22 #include <scene/interface/intf_environment.h>
23 #include <scene/interface/intf_light.h>
24 #include <scene/interface/intf_mesh.h>
25 #include <scene/interface/intf_node.h>
26 #include <scene/interface/intf_node_import.h>
27 #include <scene/interface/intf_scene.h>
28 #include <scene/interface/intf_text.h>
29
SCENE_BEGIN_NAMESPACE()30 SCENE_BEGIN_NAMESPACE()
31
32 namespace Internal {
33 template<const META_NS::AsyncCallType& CallType, typename SyncReturnType, typename FutureType>
34 constexpr auto UnwrapFuture(FutureType&& f)
35 {
36 if constexpr (CallType.async) {
37 return BASE_NS::forward<FutureType>(f);
38 } else {
39 return SyncReturnType(f.GetResult());
40 }
41 }
42 template<typename Type>
43 bool CheckName(const Type& target, BASE_NS::string_view name) noexcept
44 {
45 if constexpr (BASE_NS::is_same_v<Type, META_NS::IObject::Ptr>) {
46 return target && target->GetName() == name;
47 } else {
48 auto o = interface_cast<META_NS::IObject>(target);
49 return o && o->GetName() == name;
50 }
51 }
52 template<typename Result, typename Input>
53 BASE_NS::shared_ptr<Result> FindFromContainer(
54 const BASE_NS::vector<BASE_NS::shared_ptr<Input>>& container, BASE_NS::string_view name) noexcept
55 {
56 for (const auto& c : container) {
57 if (CheckName<BASE_NS::shared_ptr<Input>>(c, name)) {
58 return interface_pointer_cast<Result>(c);
59 }
60 }
61 return nullptr;
62 }
63 template<typename Interface>
64 INode::Ptr FindNode(
65 const BASE_NS::shared_ptr<Interface>& root, BASE_NS::string_view name, META_NS::TraversalType traversalType)
66 {
67 INode::Ptr n;
68 META_NS::IterateShared(
69 interface_pointer_cast<META_NS::IIterable>(root),
70 [&](const META_NS::IObject::Ptr& object) -> bool {
71 if (Internal::CheckName(object, name)) {
72 n = interface_pointer_cast<INode>(object);
73 }
74 return !n.operator bool();
75 },
76 traversalType);
77 return n;
78 }
79
80 } // namespace Internal
81
82 /// Wrapper for generic Scene nodes which implement SCENE_NS::INode.
83 class Node : public META_NS::Named {
84 public:
META_INTERFACE_OBJECT(Node,META_NS::Named,INode)85 META_INTERFACE_OBJECT(Node, META_NS::Named, INode)
86 /// @see ITransform::Position
87 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec3, Position)
88 /// @see ITransform::Scale
89 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec3, Scale)
90 /// @see ITransform::Rotation
91 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Quat, Rotation)
92 /// @see INode::Enabled
93 META_INTERFACE_OBJECT_PROPERTY(bool, Enabled)
94 /// @see INode::GetName
95 auto GetName() const
96 {
97 return META_INTERFACE_OBJECT_CALL_PTR(GetName());
98 }
99 /// @see INode::GetPath
GetPath()100 META_API_ASYNC auto GetPath() const
101 {
102 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(BASE_NS::string, GetPath());
103 }
104 /// @see INode::GetParent
GetParent()105 META_API_ASYNC auto GetParent() const
106 {
107 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(Node, GetParent());
108 }
109 /// @see INode::GetChildren
GetChildren()110 META_API_ASYNC auto GetChildren() const
111 {
112 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(META_NS::Internal::ArrayCast<Node>, GetChildren());
113 }
114 /// @see INode::AddChild
115 META_API_ASYNC auto AddChild(const INode::Ptr& child, size_t index = -1)
116 {
117 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(bool, AddChild(child, index));
118 }
119 /// @see INode::RemoveChild
RemoveChild(const INode::Ptr & child)120 META_API_ASYNC auto RemoveChild(const INode::Ptr& child)
121 {
122 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(bool, RemoveChild(child));
123 }
124 /// @see INode::GetScene
GetScene()125 auto GetScene() const
126 {
127 return META_INTERFACE_OBJECT_CALL_PTR(GetScene());
128 }
129 /**
130 * @brief Finds the first occurrence of a child node with given name from this node's hierarchy.
131 * @note If the full path is known, it is more efficient to call Scene::GetNode
132 * @param name Name of the node to find.
133 * @param traversalType Can be used to control how the scene is traversed, or to limit finding only immediate
134 * children by specifying TraversalType::NO_HIERARCHY.
135 * @return The first node matching the parameters or an invalid node in case of failure.
136 */
137 auto FindNode(
138 BASE_NS::string_view name, META_NS::TraversalType traversalType = META_NS::TraversalType::FULL_HIERARCHY) const
139 {
140 return Node(Internal::FindNode(GetPtr(), name, traversalType));
141 }
142 /**
143 * @brief Imports a Scene into this scene under this node.
144 * @param scene The scene to import.
145 * @param name The name which should be given to the root node of the imported scene, placed as a child of this
146 * node.
147 */
ImportScene(const IScene::Ptr & scene,BASE_NS::string_view name)148 META_API_ASYNC auto ImportScene(const IScene::Ptr& scene, BASE_NS::string_view name)
149 {
150 auto f = CallPtr<INodeImport>([=](auto& ni) { return ni.ImportChildScene(scene, name); });
151 return Internal::UnwrapFuture<CallType, Node>(BASE_NS::move(f));
152 }
153 /**
154 * @brief Imports a Scene from a resource under this node.
155 * @param uri Uri of the scene resource to import (.gltf or .scene)
156 * @param name The name which should be given to the root node of the imported scene, placed as a child of this
157 * node.
158 */
ImportScene(BASE_NS::string_view uri,BASE_NS::string_view name)159 META_API_ASYNC auto ImportScene(BASE_NS::string_view uri, BASE_NS::string_view name)
160 {
161 auto f = CallPtr<INodeImport>([=](auto& ni) { return ni.ImportChildScene(uri, name); });
162 return Internal::UnwrapFuture<CallType, Node>(BASE_NS::move(f));
163 }
164 };
165
166 /// Wrapper for Scene camera nodes which implement SCENE_NS::ICamera.
167 class Camera : public Node {
168 public:
META_INTERFACE_OBJECT(Camera,Node,ICamera)169 META_INTERFACE_OBJECT(Camera, Node, ICamera)
170 /// @see ICamera::FoV
171 META_INTERFACE_OBJECT_PROPERTY(float, FoV)
172 /// @see ICamera::AspectRatio
173 META_INTERFACE_OBJECT_PROPERTY(float, AspectRatio)
174 /// @see ICamera::NearPlane
175 META_INTERFACE_OBJECT_PROPERTY(float, NearPlane)
176 /// @see ICamera::FarPlane
177 META_INTERFACE_OBJECT_PROPERTY(float, FarPlane)
178 /// @see ICamera::XMagnification
179 META_INTERFACE_OBJECT_PROPERTY(float, XMagnification)
180 /// @see ICamera::YMagnification
181 META_INTERFACE_OBJECT_PROPERTY(float, YMagnification)
182 /// @see ICamera::XOffset
183 META_INTERFACE_OBJECT_PROPERTY(float, XOffset)
184 /// @see ICamera::YOffset
185 META_INTERFACE_OBJECT_PROPERTY(float, YOffset)
186 /// @see ICamera::Projection
187 META_INTERFACE_OBJECT_PROPERTY(CameraProjection, Projection)
188 /// @see ICamera::Culling
189 META_INTERFACE_OBJECT_PROPERTY(CameraCulling, Culling)
190 /// @see ICamera::RenderingPipeline
191 META_INTERFACE_OBJECT_PROPERTY(CameraPipeline, RenderingPipeline)
192 /// @see ICamera::SceneFlags
193 META_INTERFACE_OBJECT_PROPERTY(uint32_t, SceneFlags)
194 /// @see ICamera::PipelineFlags
195 META_INTERFACE_OBJECT_PROPERTY(uint32_t, PipelineFlags)
196 /// @see ICamera::Viewport
197 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec4, Viewport)
198 /// @see ICamera::Scissor
199 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec4, Scissor)
200 /// @see ICamera::RenderTargetSize
201 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::UVec2, RenderTargetSize)
202 /// @see ICamera::ClearColor
203 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec4, ClearColor)
204 /// Set ClearColor from BASE_NS::Color.
205 auto& SetClearColor(const BASE_NS::Color& color)
206 {
207 SetClearColor(BASE_NS::Math::Vec4(color.r, color.g, color.b, color.a));
208 return *this;
209 }
210 /// @see ICamera::ClearDepth
META_INTERFACE_OBJECT_PROPERTY(float,ClearDepth)211 META_INTERFACE_OBJECT_PROPERTY(float, ClearDepth)
212 /// @see ICamera::LayerMask
213 META_INTERFACE_OBJECT_PROPERTY(uint64_t, LayerMask)
214 /// @see ICamera::ColorTargetCustomization
215 META_INTERFACE_OBJECT_ARRAY_PROPERTY(ColorFormat, ColorTargetCustomization, ColorTargetCustomization)
216 /// @see ICamera::CustomProjectionMatrix
217 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Mat4X4, CustomProjectionMatrix)
218 /// @see ICamera::PostProcess
219 META_INTERFACE_OBJECT_PROPERTY(SCENE_NS::PostProcess, PostProcess)
220 META_API_ASYNC auto SetActive(bool active)
221 {
222 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(bool, SetActive(active));
223 }
IsActive()224 bool IsActive() const
225 {
226 return META_INTERFACE_OBJECT_CALL_PTR(IsActive());
227 }
SetRenderTarget(const IRenderTarget::Ptr & target)228 META_API_ASYNC auto SetRenderTarget(const IRenderTarget::Ptr& target)
229 {
230 return META_INTERFACE_OBJECT_ASYNC_CALL_PTR(bool, SetRenderTarget(target));
231 }
232 /// @see ICamera::SendInputEvent
SendInputEvent(SCENE_NS::PointerEvent & event)233 void SendInputEvent(SCENE_NS::PointerEvent& event)
234 {
235 META_INTERFACE_OBJECT_CALL_PTR(SendInputEvent(event));
236 }
237 /// Helper method for sending pointer down event for a single pointer
238 void SendPointerDown(uint32_t pointerId, const BASE_NS::Math::Vec2& position, META_NS::TimeSpan time = {})
239 {
240 SendPointerEvent(pointerId, SCENE_NS::PointerEvent::PointerState::POINTER_DOWN, position, time);
241 }
242 /// Helper method for sending pointer up event for a single pointer
243 void SendPointerUp(uint32_t pointerId, const BASE_NS::Math::Vec2& position, META_NS::TimeSpan time = {})
244 {
245 SendPointerEvent(pointerId, SCENE_NS::PointerEvent::PointerState::POINTER_UP, position, time);
246 }
247
248 private:
249 void SendPointerEvent(uint32_t pointerId, SCENE_NS::PointerEvent::PointerState state,
250 const BASE_NS::Math::Vec2& position, META_NS::TimeSpan time = {})
251 {
252 SCENE_NS::PointerEvent event;
253 event.time = time;
254 event.pointers = { { pointerId, position, state } };
255 SendInputEvent(event);
256 }
257 };
258
259 /// Wrapper for Scene light nodes which implement SCENE_NS::ILight.
260 class Light : public Node {
261 public:
262 META_INTERFACE_OBJECT(Light, Node, ILight)
263 /// @see ILight::Color
264 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Color, Color)
265 /// @see ILight::Intensity
266 META_INTERFACE_OBJECT_PROPERTY(float, Intensity)
267 /// @see ILight::NearPlane
268 META_INTERFACE_OBJECT_PROPERTY(float, NearPlane)
269 /// @see ILight::ShadowEnabled
270 META_INTERFACE_OBJECT_PROPERTY(bool, ShadowEnabled)
271 /// @see ILight::ShadowStrength
272 META_INTERFACE_OBJECT_PROPERTY(float, ShadowStrength)
273 /// @see ILight::ShadowDepthBias
274 META_INTERFACE_OBJECT_PROPERTY(float, ShadowDepthBias)
275 /// @see ILight::ShadowNormalBias
276 META_INTERFACE_OBJECT_PROPERTY(float, ShadowNormalBias)
277 /// @see ILight::SpotInnerAngle
278 META_INTERFACE_OBJECT_PROPERTY(float, SpotInnerAngle)
279 /// @see ILight::SpotOuterAngle
280 META_INTERFACE_OBJECT_PROPERTY(float, SpotOuterAngle)
281 /// @see ILight::Type
282 META_INTERFACE_OBJECT_PROPERTY(LightType, Type)
283 /// @see ILight::AdditionalFactor
284 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec4, AdditionalFactor)
285 /// @see ILight::LightLayerMask
286 META_INTERFACE_OBJECT_PROPERTY(uint64_t, LightLayerMask)
287 /// @see ILight::ShadowLayerMask
288 META_INTERFACE_OBJECT_PROPERTY(uint64_t, ShadowLayerMask)
289 };
290
291 /// Wrapper for Scene geometry nodes which implement SCENE_NS::IMesh.
292 class Geometry : public Node {
293 public:
META_INTERFACE_OBJECT(Geometry,Node,IMesh)294 META_INTERFACE_OBJECT(Geometry, Node, IMesh)
295 /// @see IMesh::AABBMin
296 META_INTERFACE_OBJECT_READONLY_PROPERTY(BASE_NS::Math::Vec3, AABBMin)
297 /// @see IMesh::AABBMax
298 META_INTERFACE_OBJECT_READONLY_PROPERTY(BASE_NS::Math::Vec3, AABBMax)
299 /// @see IMorphAccess::Morpher
300 auto GetMorpher() const
301 {
302 return Morpher(META_NS::GetValue(CallPtr<IMorphAccess>([](auto& p) { return p.Morpher(); })));
303 }
304 /// @see IMesh::Mesh
GetMesh()305 META_API_ASYNC auto GetMesh() const
306 {
307 auto f = CallPtr<IMeshAccess>([](const auto& ma) { return ma.GetMesh(); });
308 return Internal::UnwrapFuture<CallType, Mesh>(BASE_NS::move(f));
309 }
310 };
311
312 /// Wrapper for Scene text nodes which implement SCENE_NS::IText.
313 class Text3D : public Node {
314 public:
META_INTERFACE_OBJECT(Text3D,Node,IText)315 META_INTERFACE_OBJECT(Text3D, Node, IText)
316 /// @see IText::Test
317 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::string, Text)
318 /// @see IText::FontFamily
319 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::string, FontFamily)
320 /// @see IText::FontStyle
321 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::string, FontStyle)
322 /// @see IText::FontSize
323 META_INTERFACE_OBJECT_PROPERTY(float, FontSize)
324 /// @see IText::Font3DThickness
325 META_INTERFACE_OBJECT_PROPERTY(float, Font3DThickness)
326 /// @see IText::FontMethod
327 META_INTERFACE_OBJECT_PROPERTY(SCENE_NS::FontMethod, FontMethod)
328 /// @see IText::TextColor
329 META_INTERFACE_OBJECT_PROPERTY(BASE_NS::Math::Vec4, TextColor)
330 /// Set TextColor from BASE_NS::Color.
331 auto& SetTextColor(const BASE_NS::Color& color)
332 {
333 SetTextColor(BASE_NS::Math::Vec4(color.r, color.g, color.b, color.a));
334 return *this;
335 }
336 };
337
338 SCENE_END_NAMESPACE()
339
340 #endif // SCENE_API_NODE_H
341