281 lines
9.7 KiB
C++
281 lines
9.7 KiB
C++
/**
|
|
* @file
|
|
*
|
|
* @author Mamadou Babaei <mamadou@senseglove.com>
|
|
*
|
|
* @section LICENSE
|
|
*
|
|
* (The MIT License)
|
|
*
|
|
* Copyright (c) 2020 - 2022 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
|
|
*
|
|
*
|
|
*/
|
|
|
|
|
|
#include "SGCoreImpl/SGHapticGloveCalibrationCheckImpl.h"
|
|
|
|
#include <vector>
|
|
|
|
#include "Runtime/Launch/Resources/Version.h"
|
|
|
|
#include "SGBuildHacks/SGInclude_Core_HapticGloveCalibrationCheck.h"
|
|
#include "SGBuildHacks/SGInclude_Core_SensorRange.h"
|
|
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
|
|
#include "SGCoreImpl/SGCoreEnumCast.h"
|
|
#include "SGCoreImpl/SGSensorRangeImpl.h"
|
|
#include "SGCoreImpl/SGVect3DImpl.h"
|
|
#include "SGUtils/SGArrayUtils.h"
|
|
#include "SGUtils/SGCoordinates.h"
|
|
|
|
struct FSGHapticGloveCalibrationCheckImpl::FImpl
|
|
{
|
|
/************************
|
|
* Member variables
|
|
************************/
|
|
|
|
FHapticGloveCalibrationCheckType HapticGloveCalibrationCheck;
|
|
|
|
/************************
|
|
* Owner object
|
|
************************/
|
|
|
|
FSGHapticGloveCalibrationCheckImpl* Owner;
|
|
|
|
/************************
|
|
* Constructor / Destructor
|
|
************************/
|
|
|
|
explicit FImpl(FSGHapticGloveCalibrationCheckImpl* InOwner);
|
|
~FImpl();
|
|
|
|
/************************
|
|
* Default copy constructor & copy assignment operator
|
|
************************/
|
|
|
|
FImpl(const FImpl& Rhs) = default;
|
|
FImpl& operator=(const FImpl& Rhs) = default;
|
|
};
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetSenseGloveThreshold()
|
|
{
|
|
return FHapticGloveCalibrationCheckType::GetSenseGloveThreshold();
|
|
}
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetNovaGloveThreshold()
|
|
{
|
|
return FHapticGloveCalibrationCheckType::GetNovaGloveThreshold();
|
|
}
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetSenseGloveMinFlexion()
|
|
{
|
|
/// TODO
|
|
/// Though flexion should not be translated, should we still call the translation function?
|
|
return FHapticGloveCalibrationCheckType::GetSenseGloveMinFlexion();
|
|
}
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetNovaGloveMinFlexion()
|
|
{
|
|
return FHapticGloveCalibrationCheckType::GetNovaGloveMinFlexion();
|
|
}
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetSenseGloveMinAbduction()
|
|
{
|
|
/// TODO
|
|
/// Maybe use enums?
|
|
return FSGCoordinates::TransformToUnreal(2, FHapticGloveCalibrationCheckType::GetSenseGloveMinAbduction());
|
|
}
|
|
|
|
float FSGHapticGloveCalibrationCheckImpl::GetNovaGloveMinAbduction()
|
|
{
|
|
/// NOTE
|
|
/// Nova abduction translation is redundant.
|
|
return FHapticGloveCalibrationCheckType::GetNovaGloveMinAbduction();
|
|
}
|
|
|
|
bool FSGHapticGloveCalibrationCheckImpl::NeedsCheck(const ESGDeviceType DeviceType)
|
|
{
|
|
return FHapticGloveCalibrationCheckType::NeedsCheck(FSGCoreEnumCast::ToEDeviceType(DeviceType));
|
|
}
|
|
|
|
int32 FSGHapticGloveCalibrationCheckImpl::OutOfBounds(const FSGSensorRangeImpl& PreviousRange,
|
|
const TArray<FVector>& CurrentValues,
|
|
const ESGDeviceType DeviceType)
|
|
{
|
|
std::vector<FSGVect3DImpl::FVect3DType> CurrentValuesVector{
|
|
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
|
|
CurrentValues)
|
|
};
|
|
return FHapticGloveCalibrationCheckType::OutOfBounds(PreviousRange.ToSensorRange(), MoveTemp(CurrentValuesVector),
|
|
FSGCoreEnumCast::ToEDeviceType(DeviceType));
|
|
}
|
|
|
|
bool FSGHapticGloveCalibrationCheckImpl::MovedMinimum(const TArray<FVector>& CurrentRange,
|
|
const ESGDeviceType DeviceType)
|
|
{
|
|
std::vector<FSGVect3DImpl::FVect3DType> CurrentRangeVector{
|
|
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
|
|
CurrentRange)
|
|
};
|
|
return FHapticGloveCalibrationCheckType::MovedMinimum(MoveTemp(CurrentRangeVector),
|
|
FSGCoreEnumCast::ToEDeviceType(DeviceType));
|
|
}
|
|
|
|
bool FSGHapticGloveCalibrationCheckImpl::MatchesLast(const TArray<FVector>& CurrentRange,
|
|
const TArray<FVector>& LastRange, const ESGDeviceType DeviceType)
|
|
{
|
|
std::vector<FSGVect3DImpl::FVect3DType> CurrentRangeVector{
|
|
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
|
|
CurrentRange)
|
|
};
|
|
std::vector<FSGVect3DImpl::FVect3DType> LastRangeVector{
|
|
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
|
|
LastRange)
|
|
};
|
|
return FHapticGloveCalibrationCheckType::MatchesLast(MoveTemp(CurrentRangeVector), MoveTemp(LastRangeVector),
|
|
FSGCoreEnumCast::ToEDeviceType(DeviceType));
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl()
|
|
:
|
|
#if SG_CPP17
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
#else
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}))
|
|
#endif /* SG_CPP17 */
|
|
{
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(const FSGSensorRangeImpl& LastCalibrationRange)
|
|
:
|
|
#if SG_CPP17
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
#else
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}))
|
|
#endif /* SG_CPP17 */
|
|
{
|
|
Pimpl->HapticGloveCalibrationCheck = FHapticGloveCalibrationCheckType(LastCalibrationRange.ToSensorRange());
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(
|
|
const FHapticGloveCalibrationCheckType& HapticGloveCalibrationCheck)
|
|
:
|
|
#if SG_CPP17
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
#else
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}))
|
|
#endif /* SG_CPP17 */
|
|
{
|
|
Pimpl->HapticGloveCalibrationCheck = HapticGloveCalibrationCheck;
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(
|
|
const FSGHapticGloveCalibrationCheckImpl& Rhs)
|
|
:
|
|
#if SG_CPP17
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
|
|
#else
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}))
|
|
#endif /* SG_CPP17 */
|
|
{
|
|
Pimpl->Owner = this;
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(
|
|
FSGHapticGloveCalibrationCheckImpl&& Rhs)
|
|
#if SG_CPP17
|
|
noexcept
|
|
#endif /* SG_CPP17 */
|
|
= default;
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::~FSGHapticGloveCalibrationCheckImpl() = default;
|
|
|
|
FSGHapticGloveCalibrationCheckImpl& FSGHapticGloveCalibrationCheckImpl::operator=(
|
|
const FSGHapticGloveCalibrationCheckImpl& Rhs)
|
|
{
|
|
*Pimpl = *Rhs.Pimpl;
|
|
Pimpl->Owner = this;
|
|
return *this;
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl& FSGHapticGloveCalibrationCheckImpl::operator=(
|
|
FSGHapticGloveCalibrationCheckImpl&& Rhs)
|
|
#if SG_CPP17
|
|
noexcept
|
|
#endif /* SG_CPP17 */
|
|
= default;
|
|
|
|
const FSGHapticGloveCalibrationCheckImpl::FHapticGloveCalibrationCheckType&
|
|
FSGHapticGloveCalibrationCheckImpl::ToHapticGloveCalibrationCheck() const
|
|
{
|
|
return Pimpl->HapticGloveCalibrationCheck;
|
|
}
|
|
|
|
FSGSensorRangeImpl FSGHapticGloveCalibrationCheckImpl::GetLastSensorRange() const
|
|
{
|
|
return FSGSensorRangeImpl{Pimpl->HapticGloveCalibrationCheck.GetLastSensorRange()};
|
|
}
|
|
|
|
void FSGHapticGloveCalibrationCheckImpl::SetLastSensorRange(const FSGSensorRangeImpl& LastSensorRange)
|
|
{
|
|
Pimpl->HapticGloveCalibrationCheck.SetLastSensorRange(LastSensorRange.ToSensorRange());
|
|
}
|
|
|
|
ESGCalibrationStage FSGHapticGloveCalibrationCheckImpl::GetCalibrationStage() const
|
|
{
|
|
return FSGCoreEnumCast::ToESGCalibrationStage(Pimpl->HapticGloveCalibrationCheck.GetCalibrationStage());
|
|
}
|
|
|
|
bool FSGHapticGloveCalibrationCheckImpl::ReachedConclusion() const
|
|
{
|
|
return Pimpl->HapticGloveCalibrationCheck.ReachedConclusion();
|
|
}
|
|
|
|
void FSGHapticGloveCalibrationCheckImpl::Reset()
|
|
{
|
|
Pimpl->HapticGloveCalibrationCheck.Reset();
|
|
}
|
|
|
|
void FSGHapticGloveCalibrationCheckImpl::CheckRange(const TArray<FVector>& CurrentValues, const float DeltaSeconds,
|
|
const ESGDeviceType DeviceType)
|
|
{
|
|
std::vector<FSGVect3DImpl::FVect3DType> CurrentValuesVector{
|
|
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
|
|
CurrentValues)
|
|
};
|
|
Pimpl->HapticGloveCalibrationCheck.CheckRange(MoveTemp(CurrentValuesVector), DeltaSeconds,
|
|
FSGCoreEnumCast::ToEDeviceType(DeviceType));
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FImpl::FImpl(FSGHapticGloveCalibrationCheckImpl* InOwner)
|
|
: HapticGloveCalibrationCheck(),
|
|
Owner(InOwner)
|
|
{
|
|
}
|
|
|
|
FSGHapticGloveCalibrationCheckImpl::FImpl::~FImpl() = default;
|
|
|
|
void FSGHapticGloveCalibrationCheckImpl::FImplDeleter::operator()(const FImpl* P) const
|
|
{
|
|
delete P;
|
|
} |