forked from o3de/o3de-extras
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ROS2] Raycast Results Refactor (o3de#751)
Signed-off-by: Aleksander Kamiński <[email protected]>
- Loading branch information
1 parent
c3de922
commit c03d27c
Showing
15 changed files
with
491 additions
and
112 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
/* | ||
* Copyright (c) Contributors to the Open 3D Engine Project. | ||
* For complete copyright and license terms please see the LICENSE at the root of this distribution. | ||
* | ||
* SPDX-License-Identifier: Apache-2.0 OR MIT | ||
* | ||
*/ | ||
#pragma once | ||
|
||
#include <AzCore/std/containers/span.h> | ||
|
||
namespace ROS2 | ||
{ | ||
enum class RaycastResultFlags : AZ::u8 | ||
{ | ||
Point = (1 << 0), //!< return 3D point coordinates | ||
Range = (1 << 1), //!< return array of distances | ||
Intensity = (1 << 2), //!< return intensity data | ||
}; | ||
|
||
//! Bitwise operators for RaycastResultFlags | ||
AZ_DEFINE_ENUM_BITWISE_OPERATORS(RaycastResultFlags) | ||
|
||
inline bool IsFlagEnabled(RaycastResultFlags flag, RaycastResultFlags flags) | ||
{ | ||
return (flags & flag) == flag; | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
struct ResultTraits; | ||
|
||
template<> | ||
struct ResultTraits<RaycastResultFlags::Point> | ||
{ | ||
using Type = AZ::Vector3; | ||
}; | ||
|
||
template<> | ||
struct ResultTraits<RaycastResultFlags::Range> | ||
{ | ||
using Type = float; | ||
}; | ||
|
||
template<> | ||
struct ResultTraits<RaycastResultFlags::Intensity> | ||
{ | ||
using Type = float; | ||
}; | ||
|
||
//! Class used for storing the results of a raycast. | ||
//! It guarantees a uniform length of all its fields. | ||
class RaycastResults | ||
{ | ||
public: | ||
template<RaycastResultFlags F, typename RT = typename ResultTraits<F>::Type> | ||
using FieldSpan = AZStd::span<RT>; | ||
|
||
template<RaycastResultFlags F> | ||
using ConstFieldSpan = FieldSpan<F, const typename ResultTraits<F>::Type>; | ||
|
||
explicit RaycastResults(RaycastResultFlags flags, size_t count = 0U); | ||
RaycastResults(const RaycastResults& other) = default; | ||
RaycastResults(RaycastResults&& other); | ||
|
||
[[nodiscard]] bool IsEmpty() const; | ||
|
||
template<RaycastResultFlags F> | ||
[[nodiscard]] bool IsFieldPresent() const; | ||
|
||
[[nodiscard]] size_t GetCount() const; | ||
|
||
template<RaycastResultFlags F> | ||
AZStd::optional<ConstFieldSpan<F>> GetConstFieldSpan() const; | ||
|
||
template<RaycastResultFlags F> | ||
AZStd::optional<FieldSpan<F>> GetFieldSpan(); | ||
|
||
void Clear(); | ||
void Resize(size_t count); | ||
|
||
RaycastResults& operator=(const RaycastResults& other) = default; | ||
RaycastResults& operator=(RaycastResults&& other); | ||
|
||
private: | ||
template<RaycastResultFlags F, typename RT = typename ResultTraits<F>::Type> | ||
using FieldInternal = AZStd::optional<AZStd::vector<RT>>; | ||
|
||
template<RaycastResultFlags F> | ||
const FieldInternal<F>& GetField() const; | ||
|
||
template<RaycastResultFlags F> | ||
FieldInternal<F>& GetField(); | ||
|
||
template<RaycastResultFlags F> | ||
void ResizeFieldIfPresent(size_t count); | ||
|
||
template<RaycastResultFlags F> | ||
void EnsureFlagSatisfied(RaycastResultFlags flags, size_t count); | ||
|
||
template<RaycastResultFlags F> | ||
void ClearFieldIfPresent(); | ||
|
||
size_t m_count{}; | ||
FieldInternal<RaycastResultFlags::Point> m_points; | ||
FieldInternal<RaycastResultFlags::Range> m_ranges; | ||
FieldInternal<RaycastResultFlags::Intensity> m_intensities; | ||
}; | ||
|
||
template<RaycastResultFlags F> | ||
bool RaycastResults::IsFieldPresent() const | ||
{ | ||
return GetField<F>().has_value(); | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
AZStd::optional<RaycastResults::ConstFieldSpan<F>> RaycastResults::GetConstFieldSpan() const | ||
{ | ||
auto& field = GetField<F>(); | ||
if (!field.has_value()) | ||
{ | ||
return {}; | ||
} | ||
|
||
return AZStd::span(field->begin(), field->size()); | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
AZStd::optional<RaycastResults::FieldSpan<F>> RaycastResults::GetFieldSpan() | ||
{ | ||
auto& field = GetField<F>(); | ||
if (!field.has_value()) | ||
{ | ||
return {}; | ||
} | ||
|
||
return AZStd::span(field->begin(), field->size()); | ||
} | ||
|
||
template<> | ||
inline const RaycastResults::FieldInternal<RaycastResultFlags::Point>& RaycastResults::GetField<RaycastResultFlags::Point>() const | ||
{ | ||
return m_points; | ||
} | ||
|
||
template<> | ||
inline const RaycastResults::FieldInternal<RaycastResultFlags::Range>& RaycastResults::GetField<RaycastResultFlags::Range>() const | ||
{ | ||
return m_ranges; | ||
} | ||
|
||
template<> | ||
inline const RaycastResults::FieldInternal<RaycastResultFlags::Intensity>& RaycastResults::GetField<RaycastResultFlags::Intensity>() | ||
const | ||
{ | ||
return m_intensities; | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
RaycastResults::FieldInternal<F>& RaycastResults::GetField() | ||
{ | ||
return const_cast<FieldInternal<F>&>(static_cast<const RaycastResults*>(this)->GetField<F>()); | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
void RaycastResults::ClearFieldIfPresent() | ||
{ | ||
auto& field = GetField<F>(); | ||
if (!field.has_value()) | ||
{ | ||
return; | ||
} | ||
|
||
field->clear(); | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
void RaycastResults::ResizeFieldIfPresent(size_t count) | ||
{ | ||
auto& field = GetField<F>(); | ||
if (!field.has_value()) | ||
{ | ||
return; | ||
} | ||
|
||
field->resize(count); | ||
} | ||
|
||
template<RaycastResultFlags F> | ||
void RaycastResults::EnsureFlagSatisfied(RaycastResultFlags flags, size_t count) | ||
{ | ||
if (!IsFlagEnabled(F, flags)) | ||
{ | ||
return; | ||
} | ||
|
||
auto& field = GetField<F>(); | ||
if (!field.has_value()) | ||
{ | ||
field = AZStd::vector<typename ResultTraits<F>::Type>(count); | ||
} | ||
else | ||
{ | ||
field->resize(count); | ||
} | ||
} | ||
} // namespace ROS2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.