/** * @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 "SGCore/SGSenseGlovePose.h" #include "Runtime/Launch/Resources/Version.h" #include "SGCoreImpl/SGExportedFunctions.h" #include "SGCoreImpl/SGSenseGlovePoseImpl.h" #include "SGInterop/SGIC_FSGSenseGloveHandProfileImpl.h" #include "SGInterop/SGIC_FSGSenseGloveInfoImpl.h" #include "SGInterop/SGIC_FSGSenseGlovePoseImpl.h" #include "SGInterop/SGIC_FString.h" #include "SGInterop/SGIC_TArray_FQuat.h" #include "SGInterop/SGIC_TArray_FVector.h" #include "SGInterop/SGIC_TArray_TArray_FQuat.h" #include "SGInterop/SGIC_TArray_TArray_FVector.h" struct USGSenseGlovePose::FImpl { /************************ * Member variables ************************/ FSGSenseGlovePoseImpl SenseGlovePoseImpl; /************************ * Owner object ************************/ USGSenseGlovePose* Owner; /************************ * Constructor / Destructor ************************/ explicit FImpl(USGSenseGlovePose* InOwner); ~FImpl(); /************************ * Default copy constructor & copy assignment operator ************************/ FImpl(const FImpl& Rhs) = default; FImpl& operator=(const FImpl& Rhs) = default; /************************ * Methods ************************/ void SyncUProperties(); void SyncImplObject(); }; USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) { USGSenseGlovePose* Instance = NewObject(Outer); Instance->SetSenseGlovePoseImpl(SenseGlovePoseImpl); return Instance; } USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; SGCoreImpl_FSGSenseGlovePoseImpl_ctor(&OutSenseGlovePoseImplContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, const TArray>& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, const TArray>& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, const TArray& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{ FSGArrayUtils::FromBPNestedArray(JointPositions) }; FSGIC_TArray_TArray_FQuat JointRotationsContainer{ FSGArrayUtils::FromBPNestedArray(JointRotations) }; FSGIC_TArray_TArray_FVector GloveAnglesContainer{ FSGArrayUtils::FromBPNestedArray(GloveAngles) }; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::NewSenseGlovePose(UObject* Outer, const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, const TArray& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{ FSGArrayUtils::FromBPNestedArray(JointPositions) }; FSGIC_TArray_TArray_FQuat JointRotationsContainer{ FSGArrayUtils::RotatorsToQuats(JointRotations) }; FSGIC_TArray_TArray_FVector GloveAnglesContainer{ FSGArrayUtils::FromBPNestedArray(GloveAngles) }; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::IdlePose(UObject* Outer, const USGSenseGloveInfo* GloveInfo) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_FSGSenseGloveInfoImpl SenseGloveInfoContainer{GloveInfo->ToSenseGloveInfoImpl()}; SGCoreImpl_FSGSenseGlovePoseImpl_IdlePose(&OutSenseGlovePoseImplContainer, &SenseGloveInfoContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose* USGSenseGlovePose::Deserialize(UObject* Outer, const FString& SerializedString) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_FString SerializedStringContainer{SerializedString}; SGCoreImpl_FSGSenseGlovePoseImpl_Deserialize(&OutSenseGlovePoseImplContainer, &SerializedStringContainer); return NewSenseGlovePose(Outer, MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl)); } USGSenseGlovePose::USGSenseGlovePose() : #if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) */ { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; SGCoreImpl_FSGSenseGlovePoseImpl_ctor(&OutSenseGlovePoseImplContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, const TArray>& GloveAngles) : #if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) */ { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; FSGIC_TArray_TArray_FQuat JointRotationsContainer{JointRotations}; FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, const TArray>& JointPositions, const TArray>& JointRotations, const TArray>& GloveAngles) : #if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) */ { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{JointPositions}; FSGIC_TArray_TArray_FQuat JointRotationsContainer{FSGArrayUtils::RotatorsToQuats(JointRotations)}; FSGIC_TArray_TArray_FVector GloveAnglesContainer{GloveAngles}; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, const TArray& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{ FSGArrayUtils::FromBPNestedArray(JointPositions) }; FSGIC_TArray_TArray_FQuat JointRotationsContainer{ FSGArrayUtils::FromBPNestedArray(JointRotations) }; FSGIC_TArray_TArray_FVector GloveAnglesContainer{ FSGArrayUtils::FromBPNestedArray(GloveAngles) }; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::USGSenseGlovePose(const bool bRightHanded, const TArray& JointPositions, const TArray& JointRotations, const TArray& GloveAngles) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseImplContainer; FSGIC_TArray_TArray_FVector JointPositionsContainer{ FSGArrayUtils::FromBPNestedArray(JointPositions) }; FSGIC_TArray_TArray_FQuat JointRotationsContainer{ FSGArrayUtils::RotatorsToQuats(JointRotations) }; FSGIC_TArray_TArray_FVector GloveAnglesContainer{ FSGArrayUtils::FromBPNestedArray(GloveAngles) }; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_bRightHanded_JointPositions_JointRotations_GloveAngles( &OutSenseGlovePoseImplContainer, bRightHanded, &JointPositionsContainer, &JointRotationsContainer, &GloveAnglesContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseImplContainer.SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::USGSenseGlovePose(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) : #if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) Pimpl(TUniquePtr(new FImpl{this}, PimplDeleter)) #else Pimpl(TUniquePtr(new FImpl{this})) #endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 22 ) */ { SetSenseGlovePoseImpl(SenseGlovePoseImpl); Pimpl->SyncUProperties(); } USGSenseGlovePose::~USGSenseGlovePose() = default; void USGSenseGlovePose::SetSenseGlovePoseImpl(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) { FSGIC_FSGSenseGlovePoseImpl OutSenseGlovePoseContainer; FSGIC_FSGSenseGlovePoseImpl RhsContainer{SenseGlovePoseImpl}; SGCoreImpl_FSGSenseGlovePoseImpl_ctor_copy(&OutSenseGlovePoseContainer, &RhsContainer); Pimpl->SenseGlovePoseImpl = MoveTemp(OutSenseGlovePoseContainer.SenseGlovePoseImpl); } const FSGSenseGlovePoseImpl& USGSenseGlovePose::ToSenseGlovePoseImpl() const { Pimpl->SyncImplObject(); return Pimpl->SenseGlovePoseImpl; } bool USGSenseGlovePose::IsRight() const { FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; return SGCoreImpl_FSGSenseGlovePoseImpl_IsRight(&InstanceContainer); } TArray> USGSenseGlovePose::GetJointPositions() const { FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_TArray_FVector OutPositionsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetJointPositions(&InstanceContainer, &OutPositionsContainer); return MoveTemp(OutPositionsContainer.Array); } TArray> USGSenseGlovePose::GetJointRotationsQ() const { FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_TArray_FQuat OutRotationsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); return MoveTemp(OutRotationsContainer.Array); } TArray> USGSenseGlovePose::GetJointRotations() const { FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_TArray_FQuat OutRotationsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetJointRotations(&InstanceContainer, &OutRotationsContainer); return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); } TArray> USGSenseGlovePose::GetGloveAngles() const { FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_TArray_FVector OutAnglesContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetGloveAngles(&InstanceContainer, &OutAnglesContainer); return MoveTemp(OutAnglesContainer.Array); } TArray USGSenseGlovePose::GetThimblePositions() const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FVector OutPositionsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetThimblePositions(&InstanceContainer, &OutPositionsContainer); return MoveTemp(OutPositionsContainer.Array); } TArray USGSenseGlovePose::GetThimbleRotationsQ() const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FQuat OutRotationsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations(&InstanceContainer, &OutRotationsContainer); return MoveTemp(OutRotationsContainer.Array); } TArray USGSenseGlovePose::GetThimbleRotations() const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FQuat OutRotationsContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetThimbleRotations(&InstanceContainer, &OutRotationsContainer); return FSGArrayUtils::QuatsToRotators(OutRotationsContainer.Array); } TArray USGSenseGlovePose::GetTotalGloveAngles() const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FVector OutAnglesContainer; SGCoreImpl_FSGSenseGlovePoseImpl_GetTotalGloveAngles(&InstanceContainer, &OutAnglesContainer); return MoveTemp(OutAnglesContainer.Array); } TArray USGSenseGlovePose::CalculateFingerTips(const USGSenseGloveHandProfile* SenseGloveHandProfile) const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FVector OutFingerTipsContainer; FSGIC_FSGSenseGloveHandProfileImpl SenseGloveHandProfileImplContainer{ SenseGloveHandProfile->ToSenseGloveHandProfileImpl()}; SGCoreImpl_FSGSenseGlovePoseImpl_CalculateFingerTips_SenseGloveHandProfileImpl( &InstanceContainer, &OutFingerTipsContainer, &SenseGloveHandProfileImplContainer); return MoveTemp(OutFingerTipsContainer.Array); } TArray USGSenseGlovePose::CalculateFingerTips(const TArray& FingerOffsets) const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_TArray_FVector OutFingerTipsContainer; FSGIC_TArray_FVector FingerOffsetsContainer{FingerOffsets}; SGCoreImpl_FSGSenseGlovePoseImpl_CalculateFingerTips_FingerOffsets(&InstanceContainer, &OutFingerTipsContainer, &FingerOffsetsContainer); return MoveTemp(OutFingerTipsContainer.Array); } bool USGSenseGlovePose::Equals(const USGSenseGlovePose* SenseGlovePose) const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_FSGSenseGlovePoseImpl SenseGlovePoseContainer{SenseGlovePose->ToSenseGlovePoseImpl()}; return SGCoreImpl_FSGSenseGlovePoseImpl_Equals(&InstanceContainer, &SenseGlovePoseContainer); } FString USGSenseGlovePose::ToString(const bool bShortFormat) const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_FString OutStringContainer; SGCoreImpl_FSGSenseGlovePoseImpl_ToString(&InstanceContainer, &OutStringContainer, bShortFormat); return MoveTemp(OutStringContainer.String); } FString USGSenseGlovePose::SGSerialize() const { Pimpl->SyncImplObject(); FSGIC_FSGSenseGlovePoseImpl InstanceContainer{ToSenseGlovePoseImpl()}; FSGIC_FString OutStringContainer; SGCoreImpl_FSGSenseGlovePoseImpl_Serialize(&InstanceContainer, &OutStringContainer); return MoveTemp(OutStringContainer.String); } USGSenseGlovePose::FImpl::FImpl(USGSenseGlovePose* InOwner) : Owner(InOwner) { } USGSenseGlovePose::FImpl::~FImpl() = default; void USGSenseGlovePose::FImplDeleter::operator()(const FImpl* P) const { delete P; } void USGSenseGlovePose::FImpl::SyncUProperties() { } void USGSenseGlovePose::FImpl::SyncImplObject() { }