/** * @file * * @author Mamadou Babaei * * @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/SGSenseGlovePoseImpl.h" #include #include #include "Containers/StringConv.h" #include "Runtime/Launch/Resources/Version.h" #include "SGBuildHacks/SGInclude_Core_Quat.h" #include "SGBuildHacks/SGInclude_Core_SenseGlovePose.h" #include "SGBuildHacks/SGInclude_Core_Vect3D.h" #include "SGCoreImpl/SGSenseGloveHandProfileImpl.h" #include "SGCoreImpl/SGSenseGloveInfoImpl.h" #include "SGCoreImpl/SGQuatImpl.h" #include "SGCoreImpl/SGVect3DImpl.h" #include "SGUtils/SGArrayUtils.h" struct FSGSenseGlovePoseImpl::FImpl { /************************ * Member variables ************************/ FSenseGlovePoseType SenseGlovePose; /************************ * Owner object ************************/ FSGSenseGlovePoseImpl* Owner; /************************ * Constructor / Destructor ************************/ explicit FImpl(FSGSenseGlovePoseImpl* InOwner); ~FImpl(); /************************ * Default copy constructor & copy assignment operator ************************/ FImpl(const FImpl& Rhs) = default; FImpl& operator=(const FImpl& Rhs) = default; }; FSGSenseGlovePoseImpl FSGSenseGlovePoseImpl::IdlePose(const FSGSenseGloveInfoImpl& GloveInfo) { FSGSenseGlovePoseImpl GlovePoseImpl(FSenseGlovePoseType::IdlePose(GloveInfo.ToSenseGloveInfo())); return MoveTemp(GlovePoseImpl); } FSGSenseGlovePoseImpl FSGSenseGlovePoseImpl::Deserialize(const FString& SerializedString) { std::string Serialized(TCHAR_TO_UTF8(*SerializedString)); FSGSenseGlovePoseImpl GlovePose(FSenseGlovePoseType::Deserialize(MoveTemp(Serialized))); return MoveTemp(GlovePose); } FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl() : #if SG_CPP17 Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* SG_CPP17 */ { } FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, const TArray>& GloveAngles) : #if SG_CPP17 Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* SG_CPP17 */ { std::vector> JointPositionsVector{ FSGArrayUtils::ToMillimeters(JointPositions) }; std::vector> JointRotationsVector{ FSGArrayUtils::ToStdVector(JointRotations) }; std::vector> GloveAnglesVector{ FSGArrayUtils::ToSenseGloveAngles(GloveAngles) }; Pimpl->SenseGlovePose = FSenseGlovePoseType(bRightHanded, MoveTemp(JointPositionsVector), MoveTemp(JointRotationsVector), MoveTemp(GloveAnglesVector)); } FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const FSenseGlovePoseType& SenseGlovePose) : #if SG_CPP17 Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* SG_CPP17 */ { Pimpl->SenseGlovePose = SenseGlovePose; } FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& Rhs) : #if SG_CPP17 Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{*Rhs.Pimpl})) #endif /* SG_CPP17 */ { Pimpl->Owner = this; } FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(FSGSenseGlovePoseImpl&& Rhs) #if SG_CPP17 noexcept #endif /* SG_CPP17 */ = default; FSGSenseGlovePoseImpl::~FSGSenseGlovePoseImpl() = default; FSGSenseGlovePoseImpl& FSGSenseGlovePoseImpl::operator=(const FSGSenseGlovePoseImpl& Rhs) { *Pimpl = *Rhs.Pimpl; Pimpl->Owner = this; return *this; } FSGSenseGlovePoseImpl& FSGSenseGlovePoseImpl::operator=(FSGSenseGlovePoseImpl&& Rhs) #if SG_CPP17 noexcept #endif /* SG_CPP17 */ = default; const FSGSenseGlovePoseImpl::FSenseGlovePoseType& FSGSenseGlovePoseImpl::ToSenseGlovePose() const { return Pimpl->SenseGlovePose; } bool FSGSenseGlovePoseImpl::IsRight() const { return Pimpl->SenseGlovePose.IsRight(); } void FSGSenseGlovePoseImpl::SetIsRight(const bool bRightHanded) const { Pimpl->SenseGlovePose.SetIsRight(bRightHanded); } TArray> FSGSenseGlovePoseImpl::GetJointPositions() const { TArray> JointPositions{ FSGArrayUtils::FromMillimeters( Pimpl->SenseGlovePose.GetJointPositions()) }; return MoveTemp(JointPositions); } void FSGSenseGlovePoseImpl::SetJointPositions(const TArray>& JointPositions) const { std::vector> JointPositionsVector{ FSGArrayUtils::ToMillimeters(JointPositions) }; Pimpl->SenseGlovePose.SetJointPositions(MoveTemp(JointPositionsVector)); } TArray> FSGSenseGlovePoseImpl::GetJointRotations() const { TArray> JointRotations{ FSGArrayUtils::FromStdVector( Pimpl->SenseGlovePose.GetJointRotations()) }; return MoveTemp(JointRotations); } void FSGSenseGlovePoseImpl::SetJointRotations(const TArray>& JointRotations) const { std::vector> JointRotationsVector{ FSGArrayUtils::ToStdVector( JointRotations) }; Pimpl->SenseGlovePose.SetJointRotations(MoveTemp(JointRotationsVector)); } TArray> FSGSenseGlovePoseImpl::GetGloveAngles() const { TArray> GloveAngles{ FSGArrayUtils::FromSenseGloveAngles( Pimpl->SenseGlovePose.GetGloveAngles()) }; return MoveTemp(GloveAngles); } void FSGSenseGlovePoseImpl::SetGloveAngles(const TArray>& GloveAngles) const { std::vector> HandAnglesVector{ FSGArrayUtils::ToSenseGloveAngles( GloveAngles) }; Pimpl->SenseGlovePose.SetGloveAngles(MoveTemp(HandAnglesVector)); } TArray FSGSenseGlovePoseImpl::GetThimblePositions() const { TArray ThimblePositions{ FSGArrayUtils::FromMillimeters( Pimpl->SenseGlovePose.GetThimblePositions()) }; return MoveTemp(ThimblePositions); } TArray FSGSenseGlovePoseImpl::GetThimbleRotations() const { TArray ThimbleRotations{ FSGArrayUtils::FromStdVector( Pimpl->SenseGlovePose.GetThimbleRotations()) }; return MoveTemp(ThimbleRotations); } TArray FSGSenseGlovePoseImpl::GetTotalGloveAngles() const { TArray TotalGloveAngles{ FSGArrayUtils::FromSenseGloveAngles(Pimpl->SenseGlovePose.GetTotalGloveAngles()) }; return MoveTemp(TotalGloveAngles); } TArray FSGSenseGlovePoseImpl::CalculateFingerTips( const FSGSenseGloveHandProfileImpl& SenseGloveHandProfileImpl) const { TArray FingerTips{ FSGArrayUtils::FromMillimeters( Pimpl->SenseGlovePose.CalculateFingerTips(SenseGloveHandProfileImpl.ToSenseGloveHandProfile())) }; return MoveTemp(FingerTips); } TArray FSGSenseGlovePoseImpl::CalculateFingerTips(const TArray& FingerOffsets) const { std::vector FingerOffsetsVector{ FSGArrayUtils::ToMillimeters(FingerOffsets) }; TArray FingerTips{ FSGArrayUtils::FromMillimeters( Pimpl->SenseGlovePose.CalculateFingerTips(MoveTemp(FingerOffsetsVector))) }; return MoveTemp(FingerTips); } bool FSGSenseGlovePoseImpl::Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) const { return Pimpl->SenseGlovePose.Equals(SenseGlovePoseImpl.ToSenseGlovePose()); } FString FSGSenseGlovePoseImpl::ToString(bool bShortFormat) const { FString String(UTF8_TO_TCHAR(Pimpl->SenseGlovePose.ToString(bShortFormat).c_str())); return MoveTemp(String); } FString FSGSenseGlovePoseImpl::Serialize() const { FString Serialized(UTF8_TO_TCHAR(Pimpl->SenseGlovePose.Serialize().c_str())); return MoveTemp(Serialized); } FSGSenseGlovePoseImpl::FImpl::FImpl(FSGSenseGlovePoseImpl* InOwner) : Owner(InOwner) { } FSGSenseGlovePoseImpl::FImpl::~FImpl() = default; void FSGSenseGlovePoseImpl::FImplDeleter::operator()(const FImpl* P) const { delete P; }