/** * @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/SGHapticGloveCalibrationSequenceImpl.h" #include #include #include "Containers/StringConv.h" #include "Runtime/Launch/Resources/Version.h" #include "SGBuildHacks/SGInclude_Core_CalibrationDataPoint.h" #include "SGBuildHacks/SGInclude_Core_HandPose.h" #include "SGBuildHacks/SGInclude_Core_HandProfile.h" #include "SGBuildHacks/SGInclude_Core_HapticGlove.h" #include "SGBuildHacks/SGInclude_Core_HapticGloveCalibrationSequence.h" #include "SGBuildHacks/SGInclude_Core_HapticGloveQuickCalibration.h" #include "SGBuildHacks/SGInclude_Core_SensorRange.h" #include "SGBuildHacks/SGInclude_Core_Vect3D.h" #include "SGCoreImpl/SGCalibrationDataPointImpl.h" #include "SGCoreImpl/SGCoreEnumCast.h" #include "SGCoreImpl/SGHandPoseImpl.h" #include "SGCoreImpl/SGHandProfileImpl.h" #include "SGCoreImpl/SGHapticGloveImpl.h" #include "SGCoreImpl/SGHapticGloveQuickCalibrationImpl.h" #include "SGCoreImpl/SGSensorRangeImpl.h" #include "SGCoreImpl/SGVect3DImpl.h" #include "SGUtils/SGArrayUtils.h" #include "Templates/Casts.h" struct FSGHapticGloveCalibrationSequenceImpl::FImpl { /************************ * Static methods ************************/ static TSharedPtr MakeNewHapticGloveCalibrationSequence( TSharedPtr Ptr); /************************ * Member variables ************************/ TSharedPtr HapticGloveCalibrationSequence; /************************ * Owner object ************************/ FSGHapticGloveCalibrationSequenceImpl* Owner; /************************ * Constructor / Destructor ************************/ explicit FImpl(FSGHapticGloveCalibrationSequenceImpl* InOwner); ~FImpl(); /************************ * The copy constructor & copy assignment operator ************************/ FImpl(const FImpl& Rhs); FImpl& operator=(const FImpl& Rhs); }; int32 FSGHapticGloveCalibrationSequenceImpl::GetMaxDataPoints() { return FHapticGloveCalibrationSequenceType::GetMaxDataPoints(); } bool FSGHapticGloveCalibrationSequenceImpl::CompileProfile(const FSGSensorRangeImpl& SensorRange, const ESGDeviceType ForDevice, const bool bRightHanded, FSGHandProfileImpl& OutProfile) { FSGHandProfileImpl::FHandProfileType Profile; const bool bResult = FHapticGloveCalibrationSequenceType::CompileProfile( SensorRange.ToSensorRange(), FSGCoreEnumCast::ToEDeviceType(ForDevice), bRightHanded, Profile); OutProfile = FSGHandProfileImpl{Profile}; return bResult; } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl() : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl( const TSharedRef LinkedGlove) : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { Pimpl->HapticGloveCalibrationSequence = MakeShared( LinkedGlove->ToHapticGlovePtrChecked()); } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl( const FHapticGloveCalibrationSequenceType& HapticGloveCalibrationSequence) : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { Pimpl->HapticGloveCalibrationSequence = MakeShared( HapticGloveCalibrationSequence); } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl( TSharedRef HapticGloveCalibrationSequence) : Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) { Pimpl->HapticGloveCalibrationSequence = Pimpl->MakeNewHapticGloveCalibrationSequence(HapticGloveCalibrationSequence); } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl( const FSGHapticGloveCalibrationSequenceImpl& Rhs) : Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) { Pimpl->Owner = this; } FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl( FSGHapticGloveCalibrationSequenceImpl&& Rhs) SG_NOEXCEPT = default; FSGHapticGloveCalibrationSequenceImpl::~FSGHapticGloveCalibrationSequenceImpl() = default; FSGHapticGloveCalibrationSequenceImpl& FSGHapticGloveCalibrationSequenceImpl::operator=( const FSGHapticGloveCalibrationSequenceImpl& Rhs) { *Pimpl = *Rhs.Pimpl; Pimpl->Owner = this; return *this; } FSGHapticGloveCalibrationSequenceImpl& FSGHapticGloveCalibrationSequenceImpl::operator=( FSGHapticGloveCalibrationSequenceImpl&& Rhs) SG_NOEXCEPT = default; const FSGHapticGloveCalibrationSequenceImpl::FHapticGloveCalibrationSequenceType& FSGHapticGloveCalibrationSequenceImpl::ToHapticGloveCalibrationSequence() const { return *Pimpl->HapticGloveCalibrationSequence; } TSharedRef FSGHapticGloveCalibrationSequenceImpl::ToHapticGloveCalibrationSequenceRef() const { return Pimpl->HapticGloveCalibrationSequence.ToSharedRef(); } TSharedRef FSGHapticGloveCalibrationSequenceImpl:: ToHapticGloveCalibrationSequenceImplRef() { return SharedThis(this); } TSharedRef FSGHapticGloveCalibrationSequenceImpl:: ToHapticGloveQuickCalibrationImplRef() { FSGHapticGloveQuickCalibrationImpl* HapticGloveQuickCalibration{ dynamic_cast(this)}; ensureAlwaysMsgf(HapticGloveQuickCalibration, TEXT("Invalid HapticGloveQuickCalibration!")); return SharedThis(HapticGloveQuickCalibration); } TSharedRef FSGHapticGloveCalibrationSequenceImpl::GetLinkedGlove() const { FSGHapticGloveImpl::FHapticGlovePtrType Glove{Pimpl->HapticGloveCalibrationSequence->GetLinkedGlove()}; return MakeShared(MoveTemp(Glove)); } void FSGHapticGloveCalibrationSequenceImpl::SetLinkedGlove(const TSharedRef LinkedGlove) { Pimpl->HapticGloveCalibrationSequence->SetLinkedGlove(LinkedGlove->ToHapticGlovePtrChecked()); } TArray FSGHapticGloveCalibrationSequenceImpl::GetCalibrationPoints() const { const TArray CalibrationPoints{ FSGArrayUtils::FromStdVector( Pimpl->HapticGloveCalibrationSequence->GetCalibrationPoints()) }; return CalibrationPoints; } float FSGHapticGloveCalibrationSequenceImpl::GetElapsedTime() const { return Pimpl->HapticGloveCalibrationSequence->GetElapsedTime(); } bool FSGHapticGloveCalibrationSequenceImpl::IsManuallyCompleted() const { return Pimpl->HapticGloveCalibrationSequence->IsManuallyCompleted(); } int32 FSGHapticGloveCalibrationSequenceImpl::GetCurrentStage() const { return Pimpl->HapticGloveCalibrationSequence->GetCurrentStage(); } SIZE_T FSGHapticGloveCalibrationSequenceImpl::GetCalibrationPointsCount() const { return Pimpl->HapticGloveCalibrationSequence->GetCalibrationPointsCount(); } bool FSGHapticGloveCalibrationSequenceImpl::AutoCompleted() const { return Pimpl->HapticGloveCalibrationSequence->AutoCompleted(); } bool FSGHapticGloveCalibrationSequenceImpl::Completed() const { return Pimpl->HapticGloveCalibrationSequence->Completed(); } void FSGHapticGloveCalibrationSequenceImpl::Reset() { Pimpl->HapticGloveCalibrationSequence.Reset(); } void FSGHapticGloveCalibrationSequenceImpl::Update(const float DeltaSeconds) { return Pimpl->HapticGloveCalibrationSequence->Update(DeltaSeconds); } void FSGHapticGloveCalibrationSequenceImpl::AddDataPoint(const TArray& CalibrationData) { std::vector CalibrationDataVector{ FSGArrayUtils::ToStdVector( CalibrationData) }; Pimpl->HapticGloveCalibrationSequence->AddDataPoint(MoveTemp(CalibrationDataVector)); } void FSGHapticGloveCalibrationSequenceImpl::ConfirmCurrentStep() { Pimpl->HapticGloveCalibrationSequence->ConfirmCurrentStep(); } bool FSGHapticGloveCalibrationSequenceImpl::CompileRange(FSGSensorRangeImpl& OutSensorRange) const { FSGSensorRangeImpl::FSensorRangeType SensorRange; const bool bResult = Pimpl->HapticGloveCalibrationSequence->CompileRange(SensorRange); OutSensorRange = FSGSensorRangeImpl{SensorRange}; return bResult; } bool FSGHapticGloveCalibrationSequenceImpl::CompileProfile(const ESGDeviceType ForDevice, const bool bRightHanded, FSGHandProfileImpl& OutProfile) const { FSGHandProfileImpl::FHandProfileType Profile; const bool bResult = Pimpl->HapticGloveCalibrationSequence->CompileProfile( FSGCoreEnumCast::ToEDeviceType(ForDevice), bRightHanded, Profile); OutProfile = FSGHandProfileImpl{Profile}; return bResult; } bool FSGHapticGloveCalibrationSequenceImpl::GetHandPose(FSGHandPoseImpl& OutCurrentHandPose) const { FSGHandPoseImpl::FHandPoseType CurrentHandPose; const bool bResult = Pimpl->HapticGloveCalibrationSequence->GetHandPose(CurrentHandPose); OutCurrentHandPose = FSGHandPoseImpl{CurrentHandPose}; return bResult; } bool FSGHapticGloveCalibrationSequenceImpl::GetHandPose(const bool bRightHanded, FSGHandPoseImpl& OutCurrentHandPose) const { FSGHandPoseImpl::FHandPoseType CurrentHandPose; const bool bResult = Pimpl->HapticGloveCalibrationSequence->GetHandPose(bRightHanded, CurrentHandPose); OutCurrentHandPose = FSGHandPoseImpl{CurrentHandPose}; return bResult; } FString FSGHapticGloveCalibrationSequenceImpl::GetCurrentInstruction(const FString& NextStepKey) const { std::string NextStepKeyString{TCHAR_TO_UTF8(*NextStepKey)}; const FString CurrentInstruction{TCHAR_TO_UTF8(Pimpl->HapticGloveCalibrationSequence->GetCurrentInstruction( MoveTemp(NextStepKeyString)).c_str())}; return CurrentInstruction; } TSharedPtr FSGHapticGloveCalibrationSequenceImpl::FImpl::MakeNewHapticGloveCalibrationSequence( const TSharedPtr Ptr) { { FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType* HapticGloveQuickCalibration{ dynamic_cast( Ptr.Get()) }; if (HapticGloveQuickCalibration) { return MakeShared( *HapticGloveQuickCalibration); } } return MakeShared(*Ptr); } FSGHapticGloveCalibrationSequenceImpl::FImpl::FImpl(FSGHapticGloveCalibrationSequenceImpl* InOwner) : HapticGloveCalibrationSequence(MakeShared()), Owner(InOwner) { } FSGHapticGloveCalibrationSequenceImpl::FImpl::~FImpl() = default; FSGHapticGloveCalibrationSequenceImpl::FImpl::FImpl(const FImpl& Rhs) : HapticGloveCalibrationSequence(MakeNewHapticGloveCalibrationSequence(Rhs.HapticGloveCalibrationSequence)) { } FSGHapticGloveCalibrationSequenceImpl::FImpl& FSGHapticGloveCalibrationSequenceImpl::FImpl::operator=(const FImpl& Rhs) { HapticGloveCalibrationSequence = MakeNewHapticGloveCalibrationSequence(Rhs.HapticGloveCalibrationSequence); return *this; } void FSGHapticGloveCalibrationSequenceImpl::FImplDeleter::operator()(const FImpl* P) const { delete P; }