-
Notifications
You must be signed in to change notification settings - Fork 64
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Aleksander Kamiński <[email protected]>
- Loading branch information
1 parent
b18f827
commit c4edaed
Showing
15 changed files
with
520 additions
and
109 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,228 @@ | ||
/* | ||
* 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) | ||
|
||
template<RaycastResultFlags F> | ||
bool IsFlagEnabled(RaycastResultFlags flags) | ||
{ | ||
return (flags & F) == F; | ||
} | ||
|
||
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 IsFlagSatisfied(RaycastResultFlags requestedFlags) const; | ||
[[nodiscard]] bool SatisfiesResultFlags(RaycastResultFlags flags) 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::IsFlagSatisfied(RaycastResultFlags requestedFlags) const | ||
{ | ||
return !IsFlagEnabled<F>(requestedFlags) || IsFieldPresent<F>(); | ||
} | ||
|
||
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<> | ||
inline RaycastResults::FieldInternal<RaycastResultFlags::Point>& RaycastResults::GetField<RaycastResultFlags::Point>() | ||
{ | ||
return m_points; | ||
} | ||
|
||
template<> | ||
inline RaycastResults::FieldInternal<RaycastResultFlags::Range>& RaycastResults::GetField<RaycastResultFlags::Range>() | ||
{ | ||
return m_ranges; | ||
} | ||
|
||
template<> | ||
inline RaycastResults::FieldInternal<RaycastResultFlags::Intensity>& RaycastResults::GetField<RaycastResultFlags::Intensity>() | ||
{ | ||
return m_intensities; | ||
} | ||
|
||
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
Oops, something went wrong.