Cogs.Core
RayPick.h
1#pragma once
2
3#include "Base.h"
4#include "PickingFlags.h"
5#include "Components/Core/RenderComponent.h" // RenderLayers
6
7#include "Rendering/DataFormat.h"
8
9
10#include <glm/glm.hpp>
11#include <glm/gtx/quaternion.hpp>
12
13#include <cmath>
14#include <limits>
15#include <vector>
16#include <span>
17
18namespace Cogs::Core
19{
20
21 class CameraComponent;
22 class Context;
23 class IRayPickable;
24 struct Mesh;
25 struct ClipShapeData;
26 struct RayIntersectionHit;
27
28
30 {
31 public:
33 // Not constexpr: GLM drops constexpr from its vector constructors when built
34 // with SIMD enabled (GLM_CONFIG_ANONYMOUS_STRUCT), as in the wasm build.
35 inline static const glm::vec2 NoPickTextureCoords = { std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN() };
36 static constexpr size_t NoPickEntityType = static_cast<size_t>(-1);
37
39 struct COGSCORE_DLL_API Ordinal
40 {
41 uint32_t value = std::numeric_limits<uint32_t>::max();
42 };
43
45 struct COGSCORE_DLL_API RayPickFilter
46 {
47 RayPickFilter() = default;
48 RayPickFilter(RenderLayers layerMask, size_t entityTypeHash) : layerMask(layerMask), entityTypeHash(entityTypeHash) {}
49 RayPickFilter(std::span<const RenderLayers> ordering, RenderLayers layerMask, size_t entityTypeHash);
50
51 Ordinal getOrdinal(const RenderComponent& comp) const
52 {
53 for (size_t i = 0; i < std::size(ordering); i++) {
54 if ((comp.layer & ordering[i]) != RenderLayers::None) {
55 return Ordinal { static_cast<uint32_t>(i) };
56 }
57 }
58 return Ordinal { std::numeric_limits<uint32_t>::max() };
59 }
60
61 RenderLayers ordering[4] = { RenderLayers::Overlay, RenderLayers::All };
62
64 RenderLayers layerMask = RenderLayers::All;
66 size_t entityTypeHash = RayPicking::NoPickEntityType;
68 [[nodiscard]] bool isUnwantedType(const ComponentModel::Component& comp) const;
69 };
70
72 struct COGSCORE_DLL_API RayPickHit {
74 EntityId entity = NoEntity;
75
78 EntityId root = NoEntity;
79
81 glm::vec3 position;
82
85 glm::vec2 textureCoords = NoPickTextureCoords;
86
90 float distance = std::numeric_limits<float>::max();
91
94 Ordinal ordinal = { std::numeric_limits<uint32_t>::max() };
95
96 RayPickHit() = default;
98 RayPickHit(const RenderComponent& comp, bool returnChildEntity, const glm::vec3& pos, Ordinal ordinal, float dist, const glm::vec2& texCoords = NoPickTextureCoords);
99
100 // Strictly in front, i.e. not !isBehind
101 bool isInfront(Ordinal otherOrdinal, float otherDistance) const
102 {
103 // Lexicographical ordering of [order, distance]
104 if (ordinal.value == otherOrdinal.value) return distance < otherDistance;
105 return ordinal.value < otherOrdinal.value;
106 }
107
108 // Strictly behind, i.e. not !isInfront
109 bool isBehind(Ordinal otherOrdinal, float otherDistance) const
110 {
111 // Lexicographical ordering of [order, distance]
112 if (otherOrdinal.value == ordinal.value) return otherDistance < distance;
113 return otherOrdinal.value < ordinal.value;
114 }
115
116 // Needed to std::sort results without custom compare
117 bool operator<(const RayPickHit& rhs) const
118 {
119 // Lexicographical ordering of [order, distance]
120 if (ordinal.value == rhs.ordinal.value) return distance < rhs.distance;
121 return ordinal.value < rhs.ordinal.value;
122 }
123 };
124
140 COGSCORE_DLL_API bool pickCamera(Context* context,
141 const CameraComponent& camera,
142 const glm::vec2& cameraPosition,
143 float rayLength,
144 float radius,
145 PickingFlags pickingFlags,
146 PicksReturned returnFlag,
147 const RayPicking::RayPickFilter& filter,
148 std::vector<RayPicking::RayPickHit>& hits);
149
165 COGSCORE_DLL_API bool pickRay(Context* context,
166 const glm::vec3& position,
167 const glm::quat& rotation,
168 float rayLength,
169 float radius,
170 PickingFlags pickingFlags,
171 PicksReturned returnFlag,
172 const RayPicking::RayPickFilter& filter,
173 std::vector<RayPicking::RayPickHit>& hits);
174
176 COGSCORE_DLL_API void addPickable(IRayPickable * pickable);
177
179 COGSCORE_DLL_API void removePickable(IRayPickable * pickable);
180
181 private:
183 std::vector<IRayPickable *> pickables;
184 };
185
188 {
189 public:
191 enum struct Order : int32_t {
192 Default = 0,
193 Last = std::numeric_limits<int32_t>::max()
194 };
195 Order order = Order::Default;
196
197 IRayPickable(Order order = Order::Default) : order(order) {}
198
199 virtual ~IRayPickable() = default;
200
204 COGSCORE_DLL_API virtual bool pickCamera(Context* context,
205 const CameraComponent& camera,
206 const glm::vec2& queryClip,
207 float rayLength,
208 float rayRadius,
209 PickingFlags pickingFlags,
210 PicksReturned returnFlag,
211 const RayPicking::RayPickFilter& filter,
212 std::vector<RayPicking::RayPickHit>& hits) = 0;
216 COGSCORE_DLL_API virtual bool pickRay(Context* /*context*/,
217 const glm::vec3& /*startPos*/,
218 const glm::quat& /*rot*/,
219 float /*rayLength*/,
220 float /*radius*/,
221 PickingFlags /*pickingFlags*/,
222 PicksReturned /*returnFlag*/,
223 const RayPicking::RayPickFilter& /*filter*/,
224 std::vector<RayPicking::RayPickHit>& /*hits*/) { return{}; }
225 };
226
229 {
230 public:
231 COGSCORE_DLL_API bool pickCamera(Context* context,
232 const CameraComponent& camera,
233 const glm::vec2& normPosition,
234 float /*rayLength*/,
235 float radius,
236 PickingFlags pickingFlags,
237 PicksReturned returnFlag,
238 const RayPicking::RayPickFilter& filter,
239 std::vector<RayPicking::RayPickHit>& hits) override;
240
241 COGSCORE_DLL_API bool pickRay(Context* context,
242 const glm::vec3& startPos,
243 const glm::quat& rot,
244 float rayLength,
245 float radius,
246 PickingFlags pickingFlags,
247 PicksReturned returnFlag,
248 const RayPicking::RayPickFilter& filter,
249 std::vector<RayPicking::RayPickHit>& hits) override;
250
251 protected:
253 COGSCORE_DLL_API virtual bool pickImpl(Context* context,
254 const glm::mat4& worldPickMatrix,
255 const glm::mat4& rawViewProjection,
256 const glm::mat4& viewMatrix,
257 const RayPicking::RayPickFilter& filter,
258 PickingFlags pickingFlags,
259 PicksReturned returnFlag,
260 std::vector<RayPicking::RayPickHit>& hits) = 0;
261
262
263 // Helpers for picking meshes
265 const uint8_t* ptr = nullptr;
266 Cogs::DataFormat format = Cogs::DataFormat::Unknown;
267 uint32_t idOffset = 0;
268 uint32_t stride = 0;
269 uint32_t count = 0;
270 bool hasIdOffset = false;
271 };
272 [[nodiscard]] COGSCORE_DLL_API static TextureCoordinateInfo getTextureCoordinateInfo(const Cogs::Core::Mesh& mesh);
273 [[nodiscard]] COGSCORE_DLL_API static bool clippedByClipComp(const ClipShapeData& clipData, const glm::vec4& position);
274 [[nodiscard]] COGSCORE_DLL_API static glm::vec2 getTextureCoords(const TextureCoordinateInfo& textureInfo, const RayIntersectionHit& hit, const PickingFlags pickingFlags);
275 };
276}
Base class for Component instances.
Definition: Component.h:143
A Context instance contains all the services, systems and runtime components needed to use Cogs.
Definition: Context.h:83
Interface for modules implementing custom picking.
Definition: RayPick.h:188
virtual COGSCORE_DLL_API bool pickCamera(Context *context, const CameraComponent &camera, const glm::vec2 &queryClip, float rayLength, float rayRadius, PickingFlags pickingFlags, PicksReturned returnFlag, const RayPicking::RayPickFilter &filter, std::vector< RayPicking::RayPickHit > &hits)=0
Do a ray pick from a normalized screen space position in the camera direction and return all hits.
virtual COGSCORE_DLL_API bool pickRay(Context *, const glm::vec3 &, const glm::quat &, float, float, PickingFlags, PicksReturned, const RayPicking::RayPickFilter &, std::vector< RayPicking::RayPickHit > &)
Do a ray pick from a position and orientation in world space and return all hits.
Definition: RayPick.h:216
Order
Specifies run-order of picking extensions when that is needed.
Definition: RayPick.h:191
Base class for picking meshes.
Definition: RayPick.h:229
COGSCORE_DLL_API bool pickCamera(Context *context, const CameraComponent &camera, const glm::vec2 &normPosition, float, float radius, PickingFlags pickingFlags, PicksReturned returnFlag, const RayPicking::RayPickFilter &filter, std::vector< RayPicking::RayPickHit > &hits) override
Do a ray pick from a normalized screen space position in the camera direction and return all hits.
Definition: RayPick.cpp:209
virtual COGSCORE_DLL_API bool pickImpl(Context *context, const glm::mat4 &worldPickMatrix, const glm::mat4 &rawViewProjection, const glm::mat4 &viewMatrix, const RayPicking::RayPickFilter &filter, PickingFlags pickingFlags, PicksReturned returnFlag, std::vector< RayPicking::RayPickHit > &hits)=0
Each mesh rendering system should implement this function that goes through all components and calls ...
COGSCORE_DLL_API bool pickRay(Context *context, const glm::vec3 &startPos, const glm::quat &rot, float rayLength, float radius, PickingFlags pickingFlags, PicksReturned returnFlag, const RayPicking::RayPickFilter &filter, std::vector< RayPicking::RayPickHit > &hits) override
Do a ray pick from a position and orientation in world space and return all hits.
Definition: RayPick.cpp:236
COGSCORE_DLL_API bool pickRay(Context *context, const glm::vec3 &position, const glm::quat &rotation, float rayLength, float radius, PickingFlags pickingFlags, PicksReturned returnFlag, const RayPicking::RayPickFilter &filter, std::vector< RayPicking::RayPickHit > &hits)
RayPicking using defined ray starting from pos.
Definition: RayPick.cpp:129
COGSCORE_DLL_API void addPickable(IRayPickable *pickable)
Add Component / System for custom picking.
Definition: RayPick.cpp:160
COGSCORE_DLL_API bool pickCamera(Context *context, const CameraComponent &camera, const glm::vec2 &cameraPosition, float rayLength, float radius, PickingFlags pickingFlags, PicksReturned returnFlag, const RayPicking::RayPickFilter &filter, std::vector< RayPicking::RayPickHit > &hits)
RayPicking using ray from camera position along camera viewing direction.
Definition: RayPick.cpp:89
COGSCORE_DLL_API void removePickable(IRayPickable *pickable)
Remove Component / System from custom picking.
Definition: RayPick.cpp:166
std::vector< IRayPickable * > pickables
Storage for registered pick extensions (addPickable)
Definition: RayPick.h:183
static const glm::vec2 NoPickTextureCoords
Marks no match in texture.
Definition: RayPick.h:35
Base component for all rendering content.
RenderLayers layer
Layer mask used to determine visibility for a given camera viewport.
Contains the Engine, Renderer, resource managers and other systems needed to run Cogs....
PicksReturned
  * Options for returning picking hits.
Definition: PickingFlags.h:40
PickingFlags
Options for COGS picking.
Definition: PickingFlags.h:12
RenderLayers
Contains common render layers.
Meshes contain streams of vertex data in addition to index data and options defining geometry used fo...
Definition: Mesh.h:265
glm::vec3 position
The picked position.
Definition: RayPick.h:81