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 #ifndef CORE_UTIL_PICKING_H
16 #define CORE_UTIL_PICKING_H
17
18 #include <3d/util/intf_picking.h>
19 #include <base/containers/string_view.h>
20 #include <core/namespace.h>
21
22 CORE_BEGIN_NAMESPACE()
23 class IEcs;
24 class IEngine;
25 CORE_END_NAMESPACE()
26
27 CORE3D_BEGIN_NAMESPACE()
28 class IJointMatricesComponentManager;
29 class IMeshComponentManager;
30 class ITransformComponentManager;
31 class IRenderMeshComponentManager;
32 class IWorldMatrixComponentManager;
33 struct CameraComponent;
34 struct MeshComponent;
35
36 class Picking : public IPicking {
37 public:
38 Picking() = default;
39 ~Picking() override = default;
40 BASE_NS::Math::Vec3 ScreenToWorld(
41 CORE_NS::IEcs const& ecs, CORE_NS::Entity cameraEntity, BASE_NS::Math::Vec3 screenCoordinate) const override;
42
43 BASE_NS::Math::Vec3 WorldToScreen(
44 CORE_NS::IEcs const& ecs, CORE_NS::Entity cameraEntity, BASE_NS::Math::Vec3 worldCoordinate) const override;
45
46 BASE_NS::vector<RayCastResult> RayCast(CORE_NS::IEcs const& ecs, const BASE_NS::Math::Vec3& start,
47 const BASE_NS::Math::Vec3& direction) const override;
48 BASE_NS::vector<RayCastResult> RayCast(CORE_NS::IEcs const& ecs, const BASE_NS::Math::Vec3& start,
49 const BASE_NS::Math::Vec3& direction, uint64_t layerMask) const override;
50 BASE_NS::vector<RayTriangleCastResult> RayCast(const BASE_NS::Math::Vec3& start,
51 const BASE_NS::Math::Vec3& direction, BASE_NS::array_view<const BASE_NS::Math::Vec3> triangles) const override;
52
53 BASE_NS::vector<RayCastResult> RayCastFromCamera(
54 CORE_NS::IEcs const& ecs, CORE_NS::Entity camera, const BASE_NS::Math::Vec2& screenPos) const override;
55 BASE_NS::vector<RayCastResult> RayCastFromCamera(CORE_NS::IEcs const& ecs, CORE_NS::Entity camera,
56 const BASE_NS::Math::Vec2& screenPos, uint64_t layerMask) const override;
57 BASE_NS::vector<RayTriangleCastResult> RayCastFromCamera(CORE_NS::IEcs const& ecs, CORE_NS::Entity camera,
58 const BASE_NS::Math::Vec2& screenPos, BASE_NS::array_view<const BASE_NS::Math::Vec3> triangles) const override;
59
60 MinAndMax GetWorldAABB(const BASE_NS::Math::Mat4X4& world, const BASE_NS::Math::Vec3& aabbMin,
61 const BASE_NS::Math::Vec3& aabbMax) const override;
62
63 MinAndMax GetWorldMatrixComponentAABB(CORE_NS::Entity entity, bool isRecursive, CORE_NS::IEcs& ecs) const override;
64
65 MinAndMax GetTransformComponentAABB(CORE_NS::Entity entity, bool isRecursive, CORE_NS::IEcs& ecs) const override;
66
67 // IInterface
68 const IInterface* GetInterface(const BASE_NS::Uid& uid) const override;
69 IInterface* GetInterface(const BASE_NS::Uid& uid) override;
70
71 void Ref() override;
72 void Unref() override;
73
74 protected:
75 /** Safely compute the inverse of a direction 1/direction with zero checking. */
DirectionVectorInverse(const BASE_NS::Math::Vec3 & direction)76 inline BASE_NS::Math::Vec3 DirectionVectorInverse(const BASE_NS::Math::Vec3& direction) const
77 {
78 BASE_NS::Math::Vec3 invDir { std::numeric_limits<float>::max(), std::numeric_limits<float>::max(),
79 std::numeric_limits<float>::max() };
80 if (direction.x != 0.f) {
81 invDir.x = 1.f / direction.x;
82 }
83 if (direction.y != 0.f) {
84 invDir.y = 1.f / direction.y;
85 }
86 if (direction.z != 0.f) {
87 invDir.z = 1.f / direction.z;
88 }
89 return invDir;
90 }
91 };
92
GetName(const IPicking *)93 inline constexpr BASE_NS::string_view GetName(const IPicking*)
94 {
95 return "IPicking";
96 }
97
98 CORE3D_END_NAMESPACE()
99
100 #endif // CORE_UTIL_PICKING_H