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 static constexpr glm::vec2 NoPickTextureCoords = { std::numeric_limits<float>::quiet_NaN(), std::numeric_limits<float>::quiet_NaN() };
34 static constexpr size_t NoPickEntityType = static_cast<size_t>(-1);
35
37 struct COGSCORE_DLL_API Ordinal
38 {
39 uint32_t value = std::numeric_limits<uint32_t>::max();
40 };
41
43 struct COGSCORE_DLL_API RayPickFilter
44 {
45 RayPickFilter() = default;
46 RayPickFilter(RenderLayers layerMask, size_t entityTypeHash) : layerMask(layerMask), entityTypeHash(entityTypeHash) {}
47 RayPickFilter(std::span<const RenderLayers> ordering, RenderLayers layerMask, size_t entityTypeHash);
48
49 Ordinal getOrdinal(const RenderComponent& comp) const
50 {
51 for (size_t i = 0; i < std::size(ordering); i++) {
52 if ((comp.layer & ordering[i]) != RenderLayers::None) {
53 return Ordinal { static_cast<uint32_t>(i) };
54 }
55 }
56 return Ordinal { std::numeric_limits<uint32_t>::max() };
57 }
58
59 RenderLayers ordering[4] = { RenderLayers::Overlay, RenderLayers::All };
60
62 RenderLayers layerMask = RenderLayers::All;
64 size_t entityTypeHash = RayPicking::NoPickEntityType;
66 [[nodiscard]] bool isUnwantedType(const ComponentModel::Component& comp) const;
67 };
68
70 struct COGSCORE_DLL_API RayPickHit {
72 EntityId entity = NoEntity;
73
76 EntityId root = NoEntity;
77
79 glm::vec3 position;
80
83 glm::vec2 textureCoords = NoPickTextureCoords;
84
88 float distance = std::numeric_limits<float>::max();
89
92 Ordinal ordinal = { std::numeric_limits<uint32_t>::max() };
93
94 RayPickHit() = default;
96 RayPickHit(const RenderComponent& comp, bool returnChildEntity, const glm::vec3& pos, Ordinal ordinal, float dist, const glm::vec2& texCoords = NoPickTextureCoords);
97
98 // Strictly in front, i.e. not !isBehind
99 bool isInfront(Ordinal otherOrdinal, float otherDistance) const
100 {
101 // Lexicographical ordering of [order, distance]
102 if (ordinal.value == otherOrdinal.value) return distance < otherDistance;
103 return ordinal.value < otherOrdinal.value;
104 }
105
106 // Strictly behind, i.e. not !isInfront
107 bool isBehind(Ordinal otherOrdinal, float otherDistance) const
108 {
109 // Lexicographical ordering of [order, distance]
110 if (otherOrdinal.value == ordinal.value) return otherDistance < distance;
111 return otherOrdinal.value < ordinal.value;
112 }
113
114 // Needed to std::sort results without custom compare
115 bool operator<(const RayPickHit& rhs) const
116 {
117 // Lexicographical ordering of [order, distance]
118 if (ordinal.value == rhs.ordinal.value) return distance < rhs.distance;
119 return ordinal.value < rhs.ordinal.value;
120 }
121 };
122
138 COGSCORE_DLL_API bool pickCamera(Context* context,
139 const CameraComponent& camera,
140 const glm::vec2& cameraPosition,
141 float rayLength,
142 float radius,
143 PickingFlags pickingFlags,
144 PicksReturned returnFlag,
145 const RayPicking::RayPickFilter& filter,
146 std::vector<RayPicking::RayPickHit>& hits);
147
163 COGSCORE_DLL_API bool pickRay(Context* context,
164 const glm::vec3& position,
165 const glm::quat& rotation,
166 float rayLength,
167 float radius,
168 PickingFlags pickingFlags,
169 PicksReturned returnFlag,
170 const RayPicking::RayPickFilter& filter,
171 std::vector<RayPicking::RayPickHit>& hits);
172
174 COGSCORE_DLL_API void addPickable(IRayPickable * pickable);
175
177 COGSCORE_DLL_API void removePickable(IRayPickable * pickable);
178
179 private:
181 std::vector<IRayPickable *> pickables;
182 };
183
186 {
187 public:
189 enum struct Order : int32_t {
190 Default = 0,
191 Last = std::numeric_limits<int32_t>::max()
192 };
193 Order order = Order::Default;
194
195 IRayPickable(Order order = Order::Default) : order(order) {}
196
197 virtual ~IRayPickable() = default;
198
202 COGSCORE_DLL_API virtual bool pickCamera(Context* context,
203 const CameraComponent& camera,
204 const glm::vec2& queryClip,
205 float rayLength,
206 float rayRadius,
207 PickingFlags pickingFlags,
208 PicksReturned returnFlag,
209 const RayPicking::RayPickFilter& filter,
210 std::vector<RayPicking::RayPickHit>& hits) = 0;
214 COGSCORE_DLL_API virtual bool pickRay(Context* /*context*/,
215 const glm::vec3& /*startPos*/,
216 const glm::quat& /*rot*/,
217 float /*rayLength*/,
218 float /*radius*/,
219 PickingFlags /*pickingFlags*/,
220 PicksReturned /*returnFlag*/,
221 const RayPicking::RayPickFilter& /*filter*/,
222 std::vector<RayPicking::RayPickHit>& /*hits*/) { return{}; }
223 };
224
227 {
228 public:
229 COGSCORE_DLL_API bool pickCamera(Context* context,
230 const CameraComponent& camera,
231 const glm::vec2& normPosition,
232 float /*rayLength*/,
233 float radius,
234 PickingFlags pickingFlags,
235 PicksReturned returnFlag,
236 const RayPicking::RayPickFilter& filter,
237 std::vector<RayPicking::RayPickHit>& hits) override;
238
239 COGSCORE_DLL_API bool pickRay(Context* context,
240 const glm::vec3& startPos,
241 const glm::quat& rot,
242 float rayLength,
243 float radius,
244 PickingFlags pickingFlags,
245 PicksReturned returnFlag,
246 const RayPicking::RayPickFilter& filter,
247 std::vector<RayPicking::RayPickHit>& hits) override;
248
249 protected:
251 COGSCORE_DLL_API virtual bool pickImpl(Context* context,
252 const glm::mat4& worldPickMatrix,
253 const glm::mat4& rawViewProjection,
254 const glm::mat4& viewMatrix,
255 const RayPicking::RayPickFilter& filter,
256 PickingFlags pickingFlags,
257 PicksReturned returnFlag,
258 std::vector<RayPicking::RayPickHit>& hits) = 0;
259
260
261 // Helpers for picking meshes
263 const uint8_t* ptr = nullptr;
264 Cogs::DataFormat format = Cogs::DataFormat::Unknown;
265 uint32_t idOffset = 0;
266 uint32_t stride = 0;
267 uint32_t count = 0;
268 bool hasIdOffset = false;
269 };
270 [[nodiscard]] COGSCORE_DLL_API static TextureCoordinateInfo getTextureCoordinateInfo(const Cogs::Core::Mesh& mesh);
271 [[nodiscard]] COGSCORE_DLL_API static bool clippedByClipComp(const ClipShapeData& clipData, const glm::vec4& position);
272 [[nodiscard]] COGSCORE_DLL_API static glm::vec2 getTextureCoords(const TextureCoordinateInfo& textureInfo, const RayIntersectionHit& hit, const PickingFlags pickingFlags);
273 };
274}
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:186
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:214
Order
Specifies run-order of picking extensions when that is needed.
Definition: RayPick.h:189
Base class for picking meshes.
Definition: RayPick.h:227
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:181
static constexpr glm::vec2 NoPickTextureCoords
Marks no match in texture.
Definition: RayPick.h:33
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:79