/** * @file * * @author Mamadou Babaei * * @section LICENSE * * (The MIT License) * * Copyright (c) 2020 - 2023 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 #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/SGAngles.h" #include "SGUtils/SGArrayUtils.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 FSGAngles::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& CurrentValues, const ESGDeviceType DeviceType) { std::vector CurrentValuesVector{ FSGArrayUtils::ToStdVector( CurrentValues) }; return FHapticGloveCalibrationCheckType::OutOfBounds(PreviousRange.ToSensorRange(), MoveTemp(CurrentValuesVector), FSGCoreEnumCast::ToEDeviceType(DeviceType)); } bool FSGHapticGloveCalibrationCheckImpl::MovedMinimum(const TArray& CurrentRange, const ESGDeviceType DeviceType) { std::vector CurrentRangeVector{ FSGArrayUtils::ToStdVector( CurrentRange) }; return FHapticGloveCalibrationCheckType::MovedMinimum(MoveTemp(CurrentRangeVector), FSGCoreEnumCast::ToEDeviceType(DeviceType)); } bool FSGHapticGloveCalibrationCheckImpl::MatchesLast(const TArray& CurrentRange, const TArray& LastRange, const ESGDeviceType DeviceType) { std::vector CurrentRangeVector{ FSGArrayUtils::ToStdVector( CurrentRange) }; std::vector LastRangeVector{ FSGArrayUtils::ToStdVector( LastRange) }; return FHapticGloveCalibrationCheckType::MatchesLast(MoveTemp(CurrentRangeVector), MoveTemp(LastRangeVector), FSGCoreEnumCast::ToEDeviceType(DeviceType)); } FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl() : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { } FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(const FSGSensorRangeImpl& LastCalibrationRange) : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { Pimpl->HapticGloveCalibrationCheck = FHapticGloveCalibrationCheckType(LastCalibrationRange.ToSensorRange()); } FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl( const FHapticGloveCalibrationCheckType& HapticGloveCalibrationCheck) : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { Pimpl->HapticGloveCalibrationCheck = HapticGloveCalibrationCheck; } FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl( const FSGHapticGloveCalibrationCheckImpl& Rhs) : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) { Pimpl->Owner = this; } FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl( FSGHapticGloveCalibrationCheckImpl&& Rhs) SG_NOEXCEPT = default; FSGHapticGloveCalibrationCheckImpl::~FSGHapticGloveCalibrationCheckImpl() = default; FSGHapticGloveCalibrationCheckImpl& FSGHapticGloveCalibrationCheckImpl::operator=( const FSGHapticGloveCalibrationCheckImpl& Rhs) { *Pimpl = *Rhs.Pimpl; Pimpl->Owner = this; return *this; } FSGHapticGloveCalibrationCheckImpl& FSGHapticGloveCalibrationCheckImpl::operator=( FSGHapticGloveCalibrationCheckImpl&& Rhs) SG_NOEXCEPT = default; const FSGHapticGloveCalibrationCheckImpl::FHapticGloveCalibrationCheckType& FSGHapticGloveCalibrationCheckImpl::ToHapticGloveCalibrationCheck() const { return Pimpl->HapticGloveCalibrationCheck; } 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& CurrentValues, const float DeltaSeconds, const ESGDeviceType DeviceType) { std::vector CurrentValuesVector{ FSGArrayUtils::ToStdVector( 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; }