747 lines
22 KiB
C++
747 lines
22 KiB
C++
/**
|
|
* @file
|
|
*
|
|
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
*
|
|
* @section LICENSE
|
|
*
|
|
* (The MIT License)
|
|
*
|
|
* Copyright (c) 2020 - 2024 SenseGlove
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
* of this software and associated documentation files (the "Software"), to deal
|
|
* in the Software without restriction, including without limitation the rights
|
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the Software is
|
|
* furnished to do so, subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be included in all
|
|
* copies or substantial portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
* IMPLIED, INCLUDING BUT NOT LIMITED To THE WARRANTIES OF MERCHANTABILITY,
|
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, ToRT OR OTHERWISE, ARISING From,
|
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*
|
|
* @section DESCRIPTION
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
#pragma once
|
|
|
|
#include <vector>
|
|
|
|
#include "SGAngles.h"
|
|
#include "Containers/Array.h"
|
|
#include "Containers/StringConv.h"
|
|
#include "Templates/UnrealTemplate.h"
|
|
|
|
#include "SGUtils/SGUnits.h"
|
|
|
|
class SENSEGLOVEUTILS_API FSGArrayUtils final
|
|
{
|
|
public:
|
|
template<typename T>
|
|
static FORCEINLINE TArray<T> FromStdVector(const std::vector<T>& Vector)
|
|
{
|
|
const TArray<T> Array{&Vector[0], StaticCast<TArray<T>::SizeType>(Vector.size())};
|
|
return Array;
|
|
}
|
|
|
|
/// NOTE
|
|
/// std::vector<bool> is a non conforming container. Since it packs bools to be stored in one bit,
|
|
/// it cannot provide a bool reference. Thus, FSGArrayUtils::FromStdVector<bool>() cannot be used.
|
|
/// Hence, the specialization.
|
|
static TArray<bool> FromStdVector(const std::vector<bool>& Vector)
|
|
{
|
|
TArray<bool> Array;
|
|
|
|
for (const bool bValue: Vector)
|
|
{
|
|
Array.Add(bValue);
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
static TArray<FString> FromStdVector(const std::vector<std::string>& Vector)
|
|
{
|
|
TArray<FString> Array;
|
|
|
|
for (const std::string& StdString: Vector)
|
|
{
|
|
FString String{UTF8_TO_TCHAR(StdString.c_str())};
|
|
Array.Add(MoveTemp(String));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T>
|
|
static TArray<TArray<T>> FromStdVector(const std::vector<std::vector<T>>& NestedVector)
|
|
{
|
|
TArray<TArray<T>> NestedArray;
|
|
|
|
for (const std::vector<T>& InnerVector: NestedVector)
|
|
{
|
|
TArray<T> InnerArray{FromStdVector<T>(InnerVector)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T1, typename T2>
|
|
static TArray<T2> FromStdVector(const std::vector<T1>& Vector)
|
|
{
|
|
TArray<T2> Array;
|
|
|
|
for (const T1& T1Element: Vector)
|
|
{
|
|
T2 T2Element(T1Element);
|
|
Array.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2>
|
|
static TArray<TArray<T2>> FromStdVector(const std::vector<std::vector<T1>>& NestedVector)
|
|
{
|
|
TArray<TArray<T2>> NestedArray;
|
|
|
|
for (const std::vector<T1>& InnerVector: NestedVector)
|
|
{
|
|
TArray<T2> InnerArray{FromStdVector<T1, T2>(InnerVector)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename IntermediateImpl, T2(IntermediateImpl::*ToT2TypeMethod)() const>
|
|
static TArray<T2> FromStdVector(const std::vector<T1>& Vector)
|
|
{
|
|
TArray<T2> Array;
|
|
|
|
for (const T1& T1Element: Vector)
|
|
{
|
|
IntermediateImpl ImplElement(T1Element);
|
|
T2 T2Element((ImplElement.*ToT2TypeMethod)());
|
|
Array.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename IntermediateImpl, T2(IntermediateImpl::*ToT2TypeMethod)() const>
|
|
static TArray<TArray<T2>> FromStdVector(const std::vector<std::vector<T1>>& NestedVector)
|
|
{
|
|
TArray<TArray<T2>> NestedArray;
|
|
|
|
for (const std::vector<T1>& InnerVector: NestedVector)
|
|
{
|
|
TArray<T2> InnerArray{FromStdVector<T1, T2, IntermediateImpl, ToT2TypeMethod>(InnerVector)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T>
|
|
static FORCEINLINE std::vector<T> ToStdVector(const TArray<T>& Array)
|
|
{
|
|
std::vector<T> Vector(&Array[0], &Array[0] + Array.Num());
|
|
return Vector;
|
|
}
|
|
|
|
static std::vector<std::string> ToStdVector(const TArray<FString>& Array)
|
|
{
|
|
std::vector<std::string> Vector;
|
|
|
|
for (const FString& String: Array)
|
|
{
|
|
std::string StdString{TCHAR_TO_UTF8(*String)};
|
|
Vector.emplace_back(MoveTemp(StdString));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
template<typename T>
|
|
static std::vector<std::vector<T>> ToStdVector(const TArray<TArray<T>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<T>> NestedVector;
|
|
|
|
for (const TArray<T>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<T> InnerVector{ToStdVector<T>(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static std::vector<T2> ToStdVector(const TArray<T1>& Array)
|
|
{
|
|
std::vector<T2> Vector;
|
|
|
|
for (const T1& T1Element: Array)
|
|
{
|
|
T2 T2Element((T1Element.*ToUnderlyingTypeMethod)());
|
|
Vector.emplace_back(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static std::vector<std::vector<T2>> ToStdVector(const TArray<TArray<T1>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<T2>> NestedVector;
|
|
|
|
for (const TArray<T1>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<T2> InnerVector{ToStdVector<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename IntermediateImpl,
|
|
const T2&(IntermediateImpl::*ToUnderlyingTypeMethod)() const>
|
|
static std::vector<T2> ToStdVector(const TArray<T1>& Array)
|
|
{
|
|
std::vector<T2> Vector;
|
|
|
|
for (const T1& T1Element: Array)
|
|
{
|
|
IntermediateImpl ImplElement(T1Element);
|
|
T2 T2Element((ImplElement.*ToUnderlyingTypeMethod)());
|
|
Vector.emplace_back(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename IntermediateImpl,
|
|
const T2&(IntermediateImpl::*ToUnderlyingTypeMethod)() const>
|
|
static std::vector<std::vector<T2>> ToStdVector(const TArray<TArray<T1>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<T2>> NestedVector;
|
|
|
|
for (const TArray<T1>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<T2> InnerVector{ToStdVector<T1, T2, IntermediateImpl, ToUnderlyingTypeMethod>(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
template<typename T1, typename T2>
|
|
static TArray<T2> FromImplType(const TArray<T1>& ImplArray)
|
|
{
|
|
TArray<T2> Array;
|
|
|
|
for (const T1& T1Element: ImplArray)
|
|
{
|
|
T2 T2Element(T1Element);
|
|
Array.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2, T2*(*NewObjectMethod)(UObject*, const T1&)>
|
|
static TArray<T2*> FromImplType(UObject* Outer, const TArray<T1>& ImplArray)
|
|
{
|
|
TArray<T2*> Array;
|
|
|
|
for (const T1& T1Element: ImplArray)
|
|
{
|
|
T2* T2Element(NewObjectMethod(Outer, T1Element));
|
|
Array.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2>
|
|
static TArray<TArray<T2>> FromImplType(const TArray<TArray<T1>>& NestedImplArray)
|
|
{
|
|
TArray<TArray<T2>> NestedArray;
|
|
|
|
for (const TArray<T1>& InnerImplArray: NestedImplArray)
|
|
{
|
|
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, T2*(*NewObjectMethod)(UObject*, const T1&)>
|
|
static TArray<TArray<T2*>> FromImplType(UObject* Outer, const TArray<TArray<T1>>& NestedImplArray)
|
|
{
|
|
TArray<TArray<T2*>> NestedArray;
|
|
|
|
for (const TArray<T1>& InnerImplArray: NestedImplArray)
|
|
{
|
|
TArray<T2*> InnerArray{FromImplType<T1, T2, NewObjectMethod>(Outer, InnerImplArray)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename S>
|
|
static TArray<S> FromImplType(const TArray<TArray<T1>>& NestedImplArray)
|
|
{
|
|
TArray<S> NestedBPArray;
|
|
|
|
for (const TArray<T1>& InnerImplArray: NestedImplArray)
|
|
{
|
|
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
|
|
S InnerArrayContainer{MoveTemp(InnerArray)};
|
|
NestedBPArray.Add(MoveTemp(InnerArrayContainer));
|
|
}
|
|
|
|
return NestedBPArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename S, T2*(*NewObjectMethod)(UObject*, const T1&)>
|
|
static TArray<S> FromImplType(UObject* Outer, const TArray<TArray<T1>>& ImplArray)
|
|
{
|
|
TArray<S> Array;
|
|
|
|
for (const TArray<T1>& InnerImplArray: ImplArray)
|
|
{
|
|
TArray<T2*> InnerArray{FromImplType<T1, T2, NewObjectMethod>(Outer, InnerImplArray)};
|
|
S InnerArrayContainer{MoveTemp(InnerArray)};
|
|
Array.Add(MoveTemp(InnerArrayContainer));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2, typename S>
|
|
static TArray<S> FromImplType(const TArray<TArray<T1*>>& ImplArray)
|
|
{
|
|
TArray<S> Array;
|
|
|
|
for (const TArray<T1>& InnerImplArray: ImplArray)
|
|
{
|
|
TArray<T2> InnerArray{FromImplType<T1, T2>(InnerImplArray)};
|
|
S InnerArrayContainer{MoveTemp(InnerArray)};
|
|
Array.Add(MoveTemp(InnerArrayContainer));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static TArray<T2> ToImplType(const TArray<T1>& Array)
|
|
{
|
|
TArray<T2> ImplArray;
|
|
|
|
for (const T1& T1Element: Array)
|
|
{
|
|
T2 T2Element((T1Element.*ToUnderlyingTypeMethod)());
|
|
ImplArray.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static TArray<T2> ToImplType(const TArray<T1*>& Array)
|
|
{
|
|
TArray<T2> ImplArray;
|
|
|
|
for (const T1* T1Element: Array)
|
|
{
|
|
T2 T2Element((T1Element->*ToUnderlyingTypeMethod)());
|
|
ImplArray.Add(MoveTemp(T2Element));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static TArray<TArray<T2>> ToImplType(const TArray<TArray<T1>>& Array)
|
|
{
|
|
TArray<TArray<T2>> ImplArray;
|
|
|
|
for (const TArray<T1>& InnerArray: Array)
|
|
{
|
|
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
|
|
ImplArray.Add(MoveTemp(InnerImplArray));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const>
|
|
static TArray<TArray<T2>> ToImplType(const TArray<TArray<T1*>>& Array)
|
|
{
|
|
TArray<TArray<T2>> ImplArray;
|
|
|
|
for (const TArray<T1*>& InnerArray: Array)
|
|
{
|
|
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArray)};
|
|
ImplArray.Add(MoveTemp(InnerImplArray));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const, typename S, TArray<T1> S::*
|
|
InnerArray>
|
|
static TArray<TArray<T2>> ToImplType(const TArray<S>& Array)
|
|
{
|
|
TArray<TArray<T2>> ImplArray;
|
|
|
|
for (const S& InnerArrayContainer: Array)
|
|
{
|
|
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArrayContainer.*InnerArray)};
|
|
ImplArray.Add(MoveTemp(InnerImplArray));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T1, typename T2, const T2&(T1::*ToUnderlyingTypeMethod)() const, typename S, TArray<T1*> S::*
|
|
InnerArray>
|
|
static TArray<TArray<T2>> ToImplType(const TArray<S>& Array)
|
|
{
|
|
TArray<TArray<T2>> ImplArray;
|
|
|
|
for (const S& InnerArrayContainer: Array)
|
|
{
|
|
TArray<T2> InnerImplArray{ToImplType<T1, T2, ToUnderlyingTypeMethod>(InnerArrayContainer.*InnerArray)};
|
|
ImplArray.Add(MoveTemp(InnerImplArray));
|
|
}
|
|
|
|
return ImplArray;
|
|
}
|
|
|
|
template<typename T, typename S, TArray<T> S::*InnerArray>
|
|
static TArray<TArray<T>> FromNestedBPArray(const TArray<S>& NestedBPArray)
|
|
{
|
|
TArray<TArray<T>> NestedArray;
|
|
|
|
for (const S& InnerBPArrayContainer: NestedBPArray)
|
|
{
|
|
NestedArray.Add(InnerBPArrayContainer.*InnerArray);
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
template<typename T, typename S>
|
|
static TArray<S> ToNestedBPArray(const TArray<TArray<T>>& Array)
|
|
{
|
|
TArray<S> NestedBPArray;
|
|
|
|
for (const TArray<T>& InnerArray: Array)
|
|
{
|
|
S InnerBPArrayContainer{InnerArray};
|
|
NestedBPArray.Add(MoveTemp(InnerBPArrayContainer));
|
|
}
|
|
|
|
return NestedBPArray;
|
|
}
|
|
|
|
template<typename T, typename S>
|
|
static TArray<S> ToNestedBPArray(const TArray<TArray<T*>>& NestedArray)
|
|
{
|
|
TArray<S> NestedBPArray;
|
|
|
|
for (const TArray<T*>& InnerArray: NestedArray)
|
|
{
|
|
S InnerBPArrayContainer{InnerArray};
|
|
NestedBPArray.Add(MoveTemp(InnerBPArrayContainer));
|
|
}
|
|
|
|
return NestedBPArray;
|
|
}
|
|
|
|
static TArray<FRotator> QuatsToRotators(const TArray<FQuat>& QuatsArray);
|
|
static TArray<TArray<FRotator>> QuatsToRotators(const TArray<TArray<FQuat>>& QuatsArray);
|
|
|
|
template<typename S, TArray<FQuat> S::*InnerArray>
|
|
static TArray<TArray<FRotator>> QuatsToRotators(const TArray<S>& QuatsNestedArray)
|
|
{
|
|
TArray<TArray<FRotator>> RotatorsArray;
|
|
|
|
for (const S& QuatsInnerBPArrayContainer: QuatsNestedArray)
|
|
{
|
|
RotatorsArray.Add(QuatsToRotators(QuatsInnerBPArrayContainer.*InnerArray));
|
|
}
|
|
|
|
return RotatorsArray;
|
|
}
|
|
|
|
template<typename S>
|
|
static TArray<S> QuatsToRotators(const TArray<TArray<FQuat>>& QuatsArray)
|
|
{
|
|
TArray<S> RotatorsNestedBPArray;
|
|
|
|
for (const TArray<FQuat>& QuatsInnerArray: QuatsArray)
|
|
{
|
|
S RotatorsInnerBPArrayContainer{QuatsToRotators(QuatsInnerArray)};
|
|
RotatorsNestedBPArray.Add(MoveTemp(RotatorsInnerBPArrayContainer));
|
|
}
|
|
|
|
return RotatorsNestedBPArray;
|
|
}
|
|
|
|
template<typename Q, typename R, TArray<FQuat> Q::*InnerArray>
|
|
static TArray<R> QuatsToRotators(const TArray<Q>& QuatsNestedArray)
|
|
{
|
|
TArray<R> RotatorsNestedBPArray;
|
|
|
|
for (const Q& QuatsInnerArrayContainer: QuatsNestedArray)
|
|
{
|
|
R RotatorsInnerBPArrayContainer{QuatsToRotators(QuatsInnerArrayContainer.*InnerArray)};
|
|
RotatorsNestedBPArray.Add(MoveTemp(RotatorsInnerBPArrayContainer));
|
|
}
|
|
|
|
return RotatorsNestedBPArray;
|
|
}
|
|
|
|
static TArray<FQuat> RotatorsToQuats(const TArray<FRotator>& RotatorsNestedArray);
|
|
static TArray<TArray<FQuat>> RotatorsToQuats(const TArray<TArray<FRotator>>& RotatorsNestedArray);
|
|
|
|
template<typename S, TArray<FRotator> S::*InnerArray>
|
|
static TArray<TArray<FQuat>> RotatorsToQuats(const TArray<S>& RotatorsNestedArray)
|
|
{
|
|
TArray<TArray<FQuat>> QuatsArray;
|
|
|
|
for (const S& RotatorsInnerBPArrayContainer: RotatorsNestedArray)
|
|
{
|
|
QuatsArray.Add(RotatorsToQuats(RotatorsInnerBPArrayContainer.*InnerArray));
|
|
}
|
|
|
|
return QuatsArray;
|
|
}
|
|
|
|
template<typename S>
|
|
static TArray<S> RotatorsToQuats(const TArray<TArray<FRotator>>& RotatorsNestedArray)
|
|
{
|
|
TArray<S> QuatsNestedBPArray;
|
|
|
|
for (const TArray<FRotator>& RotatorsInnerArray: RotatorsNestedArray)
|
|
{
|
|
S QuatsInnerBPArrayContainer{RotatorsToQuats(RotatorsInnerArray)};
|
|
QuatsNestedBPArray.Add(MoveTemp(QuatsInnerBPArrayContainer));
|
|
}
|
|
|
|
return QuatsNestedBPArray;
|
|
}
|
|
|
|
template<typename Q, typename R, TArray<FRotator> Q::*InnerArray>
|
|
static TArray<R> RotatorsToQuats(const TArray<Q>& RotatorsNestedArray)
|
|
{
|
|
TArray<R> QuatsNestedBPArray;
|
|
|
|
for (const Q& RotatorsInnerArrayContainer: RotatorsNestedArray)
|
|
{
|
|
R QuatsInnerBPArrayContainer{RotatorsToQuats(RotatorsInnerArrayContainer.*InnerArray)};
|
|
QuatsNestedBPArray.Add(MoveTemp(QuatsInnerBPArrayContainer));
|
|
}
|
|
|
|
return QuatsNestedBPArray;
|
|
}
|
|
|
|
static TArray<float> FromMillimeters(const std::vector<float>& Vector);
|
|
static TArray<TArray<float>> FromMillimeters(const std::vector<std::vector<float>>& NestedVector);
|
|
|
|
template<typename V3D, typename V3DImpl>
|
|
static TArray<FVector> FromMillimeters(const std::vector<V3D>& Vector)
|
|
{
|
|
TArray<FVector> Array;
|
|
|
|
for (const V3D& Value: Vector)
|
|
{
|
|
Array.Add(FSGUnits::MillimetersToCentimeters<V3D, V3DImpl>(Value));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename V3D, typename V3DImpl>
|
|
static TArray<TArray<FVector>> FromMillimeters(const std::vector<std::vector<V3D>>& NestedVector)
|
|
{
|
|
TArray<TArray<FVector>> NestedArray;
|
|
|
|
for (const std::vector<V3D>& InnerVector: NestedVector)
|
|
{
|
|
TArray<FVector> InnerArray{FromMillimeters<V3D, V3DImpl>(InnerVector)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
static std::vector<float> ToMillimeters(const TArray<float>& Array);
|
|
static std::vector<std::vector<float>> ToMillimeters(const TArray<TArray<float>>& NestedArray);
|
|
|
|
template<typename S, TArray<float> S::*InnerArray>
|
|
static std::vector<std::vector<float>> ToMillimeters(const TArray<S>& NestedBPArray)
|
|
{
|
|
std::vector<std::vector<float>> NestedVector;
|
|
|
|
for (const S& InnerBPArrayContainer: NestedBPArray)
|
|
{
|
|
std::vector<float> InnerVector{ToMillimeters(InnerBPArrayContainer.*InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
template<typename V3D, typename V3DImpl>
|
|
static std::vector<V3D> ToMillimeters(const TArray<FVector>& Array)
|
|
{
|
|
std::vector<V3D> Vector;
|
|
|
|
for (const FVector& Value: Array)
|
|
{
|
|
Vector.emplace_back(FSGUnits::CentimetersToMillimeters<V3D, V3DImpl>(Value));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
template<typename V3D, typename V3DImpl>
|
|
static std::vector<std::vector<V3D>> ToMillimeters(const TArray<TArray<FVector>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<V3D>> NestedVector;
|
|
|
|
for (const TArray<FVector>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<V3D> InnerVector{ToMillimeters<V3D, V3DImpl>(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
static std::vector<float> ToSenseGloveAngles(const TArray<float>& Array)
|
|
{
|
|
std::vector<float> Vector;
|
|
|
|
for (const float Value: Array)
|
|
{
|
|
Vector.emplace_back(FSGAngles::TransformToSenseGlove(Value));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
static std::vector<std::vector<float>> ToSenseGloveAngles(const TArray<TArray<float>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<float>> NestedVector;
|
|
|
|
for (const TArray<float>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<float> InnerVector{ToSenseGloveAngles(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
template<typename V3D>
|
|
static std::vector<V3D> ToSenseGloveAngles(const TArray<FVector>& Array)
|
|
{
|
|
std::vector<V3D> Vector;
|
|
|
|
for (const FVector& Value: Array)
|
|
{
|
|
Vector.emplace_back(FSGAngles::TransformToSenseGlove<V3D>(Value));
|
|
}
|
|
|
|
return Vector;
|
|
}
|
|
|
|
template<typename V3D>
|
|
static std::vector<std::vector<V3D>> ToSenseGloveAngles(const TArray<TArray<FVector>>& NestedArray)
|
|
{
|
|
std::vector<std::vector<V3D>> NestedVector;
|
|
|
|
for (const TArray<FVector>& InnerArray: NestedArray)
|
|
{
|
|
std::vector<V3D> InnerVector{ToSenseGloveAngles<V3D>(InnerArray)};
|
|
NestedVector.emplace_back(MoveTemp(InnerVector));
|
|
}
|
|
|
|
return NestedVector;
|
|
}
|
|
|
|
static TArray<float> FromSenseGloveAngles(const std::vector<float>& Vector)
|
|
{
|
|
TArray<float> Array;
|
|
|
|
for (const float Value: Vector)
|
|
{
|
|
Array.Add(FSGAngles::TransformToUnreal(Value));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
static TArray<TArray<float>> FromSenseGloveAngles(const std::vector<std::vector<float>>& NestedVector)
|
|
{
|
|
TArray<TArray<float>> Array;
|
|
|
|
for (const std::vector<float>& InnerVector: NestedVector)
|
|
{
|
|
TArray<float> InnerArray{FromSenseGloveAngles(InnerVector)};
|
|
Array.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename V3D>
|
|
static TArray<FVector> FromSenseGloveAngles(const std::vector<V3D>& Vector)
|
|
{
|
|
TArray<FVector> Array;
|
|
|
|
for (const V3D& Value: Vector)
|
|
{
|
|
Array.Add(FSGAngles::TransformToUnreal<V3D>(Value));
|
|
}
|
|
|
|
return Array;
|
|
}
|
|
|
|
template<typename V3D>
|
|
static TArray<TArray<FVector>> FromSenseGloveAngles(const std::vector<std::vector<V3D>>& NestedVector)
|
|
{
|
|
TArray<TArray<FVector>> NestedArray;
|
|
|
|
for (const std::vector<V3D>& InnerVector: NestedVector)
|
|
{
|
|
TArray<FVector> InnerArray{FromSenseGloveAngles<V3D>(InnerVector)};
|
|
NestedArray.Add(MoveTemp(InnerArray));
|
|
}
|
|
|
|
return NestedArray;
|
|
}
|
|
|
|
public:
|
|
FSGArrayUtils() = delete;
|
|
virtual ~FSGArrayUtils() = delete;
|
|
}; |