implement the nova2 api updates and bump the senseglove libraries to v2.101.0-3e1693fb

This commit is contained in:
Mamadou Babaei
2024-03-22 20:54:09 +01:00
parent 695d4f01ba
commit d83251a57c
574 changed files with 22013 additions and 27569 deletions
@@ -75,6 +75,12 @@ float FSGAnatomyImpl::GetThumbJointLimit(
Movement, FAnatomyType::GetThumbJointLimit(bRightHanded, Joint, Movement, bMax));
}
float FSGAnatomyImpl::ClampJointAngle(
const float Value, const int32 Finger, const bool bRightHand, const int32 Joint, const int32 Movement)
{
return FAnatomyType::ClampJointAngle(Value, Finger, bRightHand, Joint, Movement);
}
float FSGAnatomyImpl::NormalizeFingerFlexion(const float FlexionInDegrees)
{
return FSGAngles::TransformToUnreal(
@@ -188,9 +188,9 @@ FString FSGBetaDeviceImpl::GetLastCommand() const
return MoveTemp(Command);
}
bool FSGBetaDeviceImpl::SendHaptics(const FString& Command) const
bool FSGBetaDeviceImpl::SendHaptics(const FString& Command, const int32 Channel) const
{
return ToBetaDevicePtrChecked()->SendHaptics(TCHAR_TO_UTF8(*Command));
return ToBetaDevicePtrChecked()->SendHaptics(TCHAR_TO_UTF8(*Command), Channel);
}
FString FSGBetaDeviceImpl::ToString() const
@@ -1,174 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGBuzzCommandImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGBuzzCommandImpl::FImpl
{
/************************
* Member variables
************************/
/************************
* Owner object
************************/
FSGBuzzCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGBuzzCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
const FSGBuzzCommandImpl& FSGBuzzCommandImpl::Off()
{
static const FSGBuzzCommandImpl Command(FBuzzCommandType::Off());
return Command;
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl()
: FSGFingerCommandImpl(MakeShared<FBuzzCommandType>()),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const TArray<int32>& BuzzLevels)
: FSGFingerCommandImpl(MakeShared<FBuzzCommandType>(FSGArrayUtils::ToStdVector<int32>(BuzzLevels))),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const int32 Thumb, const int32 Index, const int32 Middle, const int32 Ring,
const int32 Pinky)
: FSGFingerCommandImpl(MakeShared<FBuzzCommandType>(Thumb, Index, Middle, Ring, Pinky)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const ESGFinger Finger, const int32 BuzzLevel)
: FSGFingerCommandImpl(MakeShared<FBuzzCommandType>(FSGCoreEnumCast::ToEFinger(Finger), BuzzLevel)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const FBuzzCommandType& BuzzCommand)
: FSGFingerCommandImpl(MakeShared<FBuzzCommandType>(BuzzCommand)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const TSharedRef<FBuzzCommandType> BuzzCommand)
: FSGFingerCommandImpl(BuzzCommand),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(const FSGBuzzCommandImpl& Rhs)
: FSGFingerCommandImpl(Rhs),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGBuzzCommandImpl::FSGBuzzCommandImpl(FSGBuzzCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGBuzzCommandImpl::~FSGBuzzCommandImpl() = default;
FSGBuzzCommandImpl& FSGBuzzCommandImpl::operator=(const FSGBuzzCommandImpl& Rhs)
{
FSGFingerCommandImpl::operator=(Rhs);
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGBuzzCommandImpl& FSGBuzzCommandImpl::operator=(FSGBuzzCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGBuzzCommandImpl::FBuzzCommandType& FSGBuzzCommandImpl::ToBuzzCommand() const
{
return *StaticCastSharedRef<FBuzzCommandType>(ToFingerCommandRef());
}
TSharedRef<FSGBuzzCommandImpl::FBuzzCommandType> FSGBuzzCommandImpl::ToBuzzCommandRef() const
{
return StaticCastSharedRef<FBuzzCommandType>(ToFingerCommandRef());
}
FSGBuzzCommandImpl::FBuzzCommandType& FSGBuzzCommandImpl::ToBuzzCommand()
{
return *StaticCastSharedRef<FBuzzCommandType>(ToFingerCommandRef());
}
TSharedRef<FSGBuzzCommandImpl::FBuzzCommandType> FSGBuzzCommandImpl::ToBuzzCommandRef()
{
return StaticCastSharedRef<FBuzzCommandType>(ToFingerCommandRef());
}
FSGBuzzCommandImpl FSGBuzzCommandImpl::Copy() const
{
return FSGBuzzCommandImpl(ToBuzzCommandRef()->Copy());
}
FSGBuzzCommandImpl FSGBuzzCommandImpl::Merge(const FSGBuzzCommandImpl& Command) const
{
return FSGBuzzCommandImpl(ToBuzzCommandRef()->Merge(Command.ToBuzzCommand()));
}
FSGBuzzCommandImpl::FImpl::FImpl(FSGBuzzCommandImpl* InOwner)
: Owner(InOwner)
{
}
FSGBuzzCommandImpl::FImpl::~FImpl() = default;
void FSGBuzzCommandImpl::FImplDeleter::operator()(const FSGBuzzCommandImpl::FImpl* P) const
{
delete P;
}
@@ -1,157 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGCalibrationDataPointImpl.h"
#include <string>
#include <vector>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_CalibrationDataPoint.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGCalibrationDataPointImpl::FImpl
{
/************************
* Member variables
************************/
FCalibrationDataPointType CalibrationDataPoint;
/************************
* Owner object
************************/
FSGCalibrationDataPointImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGCalibrationDataPointImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGCalibrationDataPointImpl::FSGCalibrationDataPointImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGCalibrationDataPointImpl::FSGCalibrationDataPointImpl(const int32 CurrentStage,
const TArray<FVector>& CalibrationValues)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<FSGVect3DImpl::FVect3DType> Values(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
CalibrationValues));
Pimpl->CalibrationDataPoint = FCalibrationDataPointType(CurrentStage, MoveTemp(Values));
}
FSGCalibrationDataPointImpl::FSGCalibrationDataPointImpl(const FCalibrationDataPointType& CalibrationDataPoint)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->CalibrationDataPoint = CalibrationDataPoint;
}
FSGCalibrationDataPointImpl::FSGCalibrationDataPointImpl(const FSGCalibrationDataPointImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGCalibrationDataPointImpl::FSGCalibrationDataPointImpl(FSGCalibrationDataPointImpl&& Rhs) SG_NOEXCEPT = default;
FSGCalibrationDataPointImpl::~FSGCalibrationDataPointImpl() = default;
FSGCalibrationDataPointImpl& FSGCalibrationDataPointImpl::operator=(const FSGCalibrationDataPointImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGCalibrationDataPointImpl& FSGCalibrationDataPointImpl::operator=(FSGCalibrationDataPointImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGCalibrationDataPointImpl::FCalibrationDataPointType&
FSGCalibrationDataPointImpl::ToCalibrationDataPoint() const
{
return Pimpl->CalibrationDataPoint;
}
TArray<FVector> FSGCalibrationDataPointImpl::GetCalibrationValues() const
{
std::vector<FSGVect3DImpl::FVect3DType> Values(Pimpl->CalibrationDataPoint.GetCalibrationValues());
TArray<FVector> CalibrationValues{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
MoveTemp(Values))
};
return CalibrationValues;
}
int32 FSGCalibrationDataPointImpl::GetStage() const
{
return Pimpl->CalibrationDataPoint.GetStage();
}
FString FSGCalibrationDataPointImpl::ToLogData(const FString& Delimiter) const
{
std::string DelimiterString(TCHAR_TO_UTF8(*Delimiter));
FString LogData(UTF8_TO_TCHAR(Pimpl->CalibrationDataPoint.ToLogData(MoveTemp(DelimiterString)).c_str()));
return LogData;
}
FSGCalibrationDataPointImpl::FImpl::FImpl(FSGCalibrationDataPointImpl* InOwner)
: Owner(InOwner)
{
}
FSGCalibrationDataPointImpl::FImpl::~FImpl() = default;
void FSGCalibrationDataPointImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -66,47 +66,6 @@ ESGBackendType FSGCoreEnumCast::ToESGBackendType(const FEBackendType Enum)
return ESGBackendType::None;
}
FSGCoreEnumCast::FECalibrationStageType FSGCoreEnumCast::ToECalibrationStage(const ESGCalibrationStage Enum)
{
switch (Enum)
{
case ESGCalibrationStage::MoveFingers:
return FECalibrationStageType::MoveFingers;
case ESGCalibrationStage::CalibrationNeeded:
return FECalibrationStageType::CalibrationNeeded;
case ESGCalibrationStage::Calibrating:
return FECalibrationStageType::Calibrating;
case ESGCalibrationStage::Done:
return FECalibrationStageType::Done;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FECalibrationStageType::MoveFingers;
}
ESGCalibrationStage FSGCoreEnumCast::ToESGCalibrationStage(const FECalibrationStageType Enum)
{
switch (Enum)
{
case FECalibrationStageType::MoveFingers:
return ESGCalibrationStage::MoveFingers;
case FECalibrationStageType::CalibrationNeeded:
return ESGCalibrationStage::CalibrationNeeded;
case FECalibrationStageType::Calibrating:
return ESGCalibrationStage::Calibrating;
case FECalibrationStageType::Done:
return ESGCalibrationStage::Done;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGCalibrationStage::None;
}
FSGCoreEnumCast::FEConnectionType FSGCoreEnumCast::ToEConnectionType(const ESGConnectionType Enum)
{
switch (Enum)
@@ -160,6 +119,8 @@ FSGCoreEnumCast::FEDeviceType FSGCoreEnumCast::ToEDeviceType(const ESGDeviceType
return FEDeviceType::SenseGlove;
case ESGDeviceType::Nova:
return FEDeviceType::Nova;
case ESGDeviceType::Nova2:
return FEDeviceType::Nova2;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
@@ -181,6 +142,8 @@ ESGDeviceType FSGCoreEnumCast::ToESGDeviceType(const FEDeviceType Enum)
return ESGDeviceType::SenseGlove;
case FEDeviceType::Nova:
return ESGDeviceType::Nova;
case FEDeviceType::Nova2:
return ESGDeviceType::Nova2;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
@@ -234,35 +197,6 @@ ESGFinger FSGCoreEnumCast::ToESGFinger(const FSGCoreEnumCast::FEFingerType Enum)
return ESGFinger::None;
}
FSGCoreEnumCast::FEFingerSolverType FSGCoreEnumCast::ToEFingerSolver(const ESGFingerSolver Enum)
{
switch (Enum)
{
case ESGFingerSolver::Interpolation:
return FEFingerSolverType::Interpolation;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEFingerSolverType::Interpolation;
}
ESGFingerSolver FSGCoreEnumCast::ToESGFingerSolver(const FEFingerSolverType Enum)
{
switch (Enum)
{
case FEFingerSolverType::Interpolation:
return ESGFingerSolver::Interpolation;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGFingerSolver::None;
}
FSGCoreEnumCast::FEFingerMovementType FSGCoreEnumCast::ToEFingerMovement(const ESGFingerMovement Enum)
{
switch (Enum)
@@ -304,43 +238,222 @@ ESGFingerMovement FSGCoreEnumCast::ToESGFingerMovement(const FEFingerMovementTyp
return ESGFingerMovement::None;
}
FSGCoreEnumCast::FEPositionalTrackingHardware FSGCoreEnumCast::ToEPositionalTrackingHardware(
const ESGPositionalTrackingHardware Enum)
FSGCoreEnumCast::FEHapticChannelType FSGCoreEnumCast::ToEHapticChannelType(const ESGHapticChannelType Enum)
{
switch (Enum)
{
case ESGPositionalTrackingHardware::Custom:
return FEPositionalTrackingHardware::Custom;
case ESGPositionalTrackingHardware::ViveTracker:
return FEPositionalTrackingHardware::ViveTracker;
case ESGPositionalTrackingHardware::Quest2Controller:
return FEPositionalTrackingHardware::Quest2Controller;
case ESGPositionalTrackingHardware::ViveFocus3WristTracker:
return FEPositionalTrackingHardware::ViveFocus3WristTracker;
case ESGPositionalTrackingHardware::QuestProController:
return FEPositionalTrackingHardware::QuestProController;
case ESGHapticChannelType::StreamingChannel:
return FEHapticChannelType::StreamingChannel;
case ESGHapticChannelType::FireAndForgetChannel:
return FEHapticChannelType::FireAndForgetChannel;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEPositionalTrackingHardware::Custom;
return FEHapticChannelType::StreamingChannel;
}
ESGPositionalTrackingHardware FSGCoreEnumCast::ToESGPositionalTrackingHardware(const FEPositionalTrackingHardware Enum)
ESGHapticChannelType FSGCoreEnumCast::ToESGHapticChannelType(const FEHapticChannelType Enum)
{
switch (Enum)
{
case FEPositionalTrackingHardware::Custom:
case FEHapticChannelType::StreamingChannel:
return ESGHapticChannelType::StreamingChannel;
case FEHapticChannelType::FireAndForgetChannel:
return ESGHapticChannelType::FireAndForgetChannel;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGHapticChannelType::None;
}
FSGCoreEnumCast::FEHapticGloveCalibrationStateType FSGCoreEnumCast::ToEHapticGloveCalibrationState(
const ESGHapticGloveCalibrationState Enum)
{
switch (Enum)
{
case ESGHapticGloveCalibrationState::Unknown:
return FEHapticGloveCalibrationStateType::Unknown;
case ESGHapticGloveCalibrationState::MoveFingers:
return FEHapticGloveCalibrationStateType::MoveFingers;
case ESGHapticGloveCalibrationState::AllSensorsMoved:
return FEHapticGloveCalibrationStateType::AllSensorsMoved;
case ESGHapticGloveCalibrationState::CalibrationLocked:
return FEHapticGloveCalibrationStateType::CalibrationLocked;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEHapticGloveCalibrationStateType::Unknown;
}
ESGHapticGloveCalibrationState FSGCoreEnumCast::ToESGHapticGloveCalibrationState(
const FEHapticGloveCalibrationStateType Enum)
{
switch (Enum)
{
case FEHapticGloveCalibrationStateType::Unknown:
return ESGHapticGloveCalibrationState::Unknown;
case FEHapticGloveCalibrationStateType::MoveFingers:
return ESGHapticGloveCalibrationState::MoveFingers;
case FEHapticGloveCalibrationStateType::AllSensorsMoved:
return ESGHapticGloveCalibrationState::AllSensorsMoved;
case FEHapticGloveCalibrationStateType::CalibrationLocked:
return ESGHapticGloveCalibrationState::CalibrationLocked;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGHapticGloveCalibrationState::None;
}
FSGCoreEnumCast::FEHapticLocationType FSGCoreEnumCast::ToEHapticLocation(const ESGHapticLocation Enum)
{
switch (Enum)
{
case ESGHapticLocation::Unknown:
return FEHapticLocationType::Unknown;
case ESGHapticLocation::ThumbTip:
return FEHapticLocationType::IndexTip;
case ESGHapticLocation::MiddleTip:
return FEHapticLocationType::MiddleTip;
case ESGHapticLocation::RingTip:
return FEHapticLocationType::RingTip;
case ESGHapticLocation::PinkyTip:
return FEHapticLocationType::PinkyTip;
case ESGHapticLocation::PalmIndexSide:
return FEHapticLocationType::PalmIndexSide;
case ESGHapticLocation::PalmPinkySide:
return FEHapticLocationType::PalmPinkySide;
case ESGHapticLocation::WholeHand:
return FEHapticLocationType::WholeHand;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEHapticLocationType::Unknown;
}
ESGHapticLocation FSGCoreEnumCast::ToESGHapticLocation(const FEHapticLocationType Enum)
{
switch (Enum)
{
case FEHapticLocationType::Unknown:
return ESGHapticLocation::Unknown;
case FEHapticLocationType::ThumbTip:
return ESGHapticLocation::IndexTip;
case FEHapticLocationType::MiddleTip:
return ESGHapticLocation::MiddleTip;
case FEHapticLocationType::RingTip:
return ESGHapticLocation::RingTip;
case FEHapticLocationType::PinkyTip:
return ESGHapticLocation::PinkyTip;
case FEHapticLocationType::PalmIndexSide:
return ESGHapticLocation::PalmIndexSide;
case FEHapticLocationType::PalmPinkySide:
return ESGHapticLocation::PalmPinkySide;
case FEHapticLocationType::WholeHand:
return ESGHapticLocation::WholeHand;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGHapticLocation::None;
}
FSGCoreEnumCast::FENormalizationStateType FSGCoreEnumCast::ToENormalizationState(const ESGNormalizationState Enum)
{
switch (Enum)
{
case ESGNormalizationState::Unknown:
return FENormalizationStateType::Unknown;
case ESGNormalizationState::SendingRawData:
return FENormalizationStateType::SendingRawData;
case ESGNormalizationState::Normalizing_MoveFingers:
return FENormalizationStateType::Normalizing_MoveFingers;
case ESGNormalizationState::Normalizing_AwaitConfirm:
return FENormalizationStateType::Normalizing_AwaitConfirm;
case ESGNormalizationState::NormalizationFinished:
return FENormalizationStateType::NormalizationFinished;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FENormalizationStateType::Unknown;
}
ESGNormalizationState FSGCoreEnumCast::ToESGNormalizationState(const FENormalizationStateType Enum)
{
switch (Enum)
{
case FENormalizationStateType::Unknown:
return ESGNormalizationState::Unknown;
case FENormalizationStateType::SendingRawData:
return ESGNormalizationState::SendingRawData;
case FENormalizationStateType::Normalizing_MoveFingers:
return ESGNormalizationState::Normalizing_MoveFingers;
case FENormalizationStateType::Normalizing_AwaitConfirm:
return ESGNormalizationState::Normalizing_AwaitConfirm;
case FENormalizationStateType::NormalizationFinished:
return ESGNormalizationState::NormalizationFinished;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGNormalizationState::None;
}
FSGCoreEnumCast::FEPositionalTrackingHardwareType FSGCoreEnumCast::ToEPositionalTrackingHardware(
const ESGPositionalTrackingHardware Enum)
{
switch (Enum)
{
case ESGPositionalTrackingHardware::Custom:
return FEPositionalTrackingHardwareType::Custom;
case ESGPositionalTrackingHardware::ViveTracker:
return FEPositionalTrackingHardwareType::ViveTracker;
case ESGPositionalTrackingHardware::Quest2Controller:
return FEPositionalTrackingHardwareType::Quest2Controller;
case ESGPositionalTrackingHardware::ViveFocus3WristTracker:
return FEPositionalTrackingHardwareType::ViveFocus3WristTracker;
case ESGPositionalTrackingHardware::QuestProController:
return FEPositionalTrackingHardwareType::QuestProController;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEPositionalTrackingHardwareType::Custom;
}
ESGPositionalTrackingHardware FSGCoreEnumCast::ToESGPositionalTrackingHardware(
const FEPositionalTrackingHardwareType Enum)
{
switch (Enum)
{
case FEPositionalTrackingHardwareType::Custom:
return ESGPositionalTrackingHardware::Custom;
case FEPositionalTrackingHardware::ViveTracker:
case FEPositionalTrackingHardwareType::ViveTracker:
return ESGPositionalTrackingHardware::ViveTracker;
case FEPositionalTrackingHardware::Quest2Controller:
case FEPositionalTrackingHardwareType::Quest2Controller:
return ESGPositionalTrackingHardware::Quest2Controller;
case FEPositionalTrackingHardware::ViveFocus3WristTracker:
case FEPositionalTrackingHardwareType::ViveFocus3WristTracker:
return ESGPositionalTrackingHardware::ViveFocus3WristTracker;
case FEPositionalTrackingHardware::QuestProController:
case FEPositionalTrackingHardwareType::QuestProController:
return ESGPositionalTrackingHardware::QuestProController;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
@@ -365,18 +478,21 @@ FSGCoreEnumCast::FESenseGloveThumperCommandType FSGCoreEnumCast::ToESenseGloveTh
return FESenseGloveThumperCommandType::ButtonDouble100;
case ESGSenseGloveThumperCommand::ButtonDouble60:
return FESenseGloveThumperCommandType::ButtonDouble60;
case ESGSenseGloveThumperCommand::ImpactThump100:
return FESenseGloveThumperCommandType::ImpactThump100;
case ESGSenseGloveThumperCommand::ImpactThump30:
return FESenseGloveThumperCommandType::ImpactThump30;
case ESGSenseGloveThumperCommand::ImpactThump10:
return FESenseGloveThumperCommandType::ImpactThump10;
case ESGSenseGloveThumperCommand::ImpactThump100:
return FESenseGloveThumperCommandType::ImpactThump100;
case ESGSenseGloveThumperCommand::ObjectGrasp100:
return FESenseGloveThumperCommandType::ObjectGrasp100;
case ESGSenseGloveThumperCommand::ObjectGrasp60:
return FESenseGloveThumperCommandType::ObjectGrasp60;
case ESGSenseGloveThumperCommand::ObjectGrasp30:
return FESenseGloveThumperCommandType::ObjectGrasp30;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
@@ -397,23 +513,96 @@ ESGSenseGloveThumperCommand FSGCoreEnumCast::ToESGSenseGloveThumperCommand(const
return ESGSenseGloveThumperCommand::ButtonDouble100;
case FESenseGloveThumperCommandType::ButtonDouble60:
return ESGSenseGloveThumperCommand::ButtonDouble60;
case FESenseGloveThumperCommandType::ImpactThump100:
return ESGSenseGloveThumperCommand::ImpactThump100;
case FESenseGloveThumperCommandType::ImpactThump30:
return ESGSenseGloveThumperCommand::ImpactThump30;
case FESenseGloveThumperCommandType::ImpactThump10:
return ESGSenseGloveThumperCommand::ImpactThump10;
case FESenseGloveThumperCommandType::ImpactThump100:
return ESGSenseGloveThumperCommand::ImpactThump100;
case FESenseGloveThumperCommandType::ObjectGrasp100:
return ESGSenseGloveThumperCommand::ObjectGrasp100;
case FESenseGloveThumperCommandType::ObjectGrasp60:
return ESGSenseGloveThumperCommand::ObjectGrasp60;
case FESenseGloveThumperCommandType::ObjectGrasp30:
return ESGSenseGloveThumperCommand::ObjectGrasp30;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGSenseGloveThumperCommand::None;
}
FSGCoreEnumCast::FENova2SensorLocationType FSGCoreEnumCast::ToESensorLocation(const ESGNova2SensorLocation Enum)
{
switch (Enum)
{
case ESGNova2SensorLocation::Abduction:
return FENova2SensorLocationType::Abduction;
case ESGNova2SensorLocation::FlexionProximal:
return FENova2SensorLocationType::FlexionProximal;
case ESGNova2SensorLocation::FlexionDistal:
return FENova2SensorLocationType::FlexionDistal;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FENova2SensorLocationType::Abduction;
}
ESGNova2SensorLocation FSGCoreEnumCast::ToESGNova2SensorLocation(const FENova2SensorLocationType Enum)
{
switch (Enum)
{
case FENova2SensorLocationType::Abduction:
return ESGNova2SensorLocation::Abduction;
case FENova2SensorLocationType::FlexionProximal:
return ESGNova2SensorLocation::FlexionProximal;
case FENova2SensorLocationType::FlexionDistal:
return ESGNova2SensorLocation::FlexionDistal;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGNova2SensorLocation::None;
}
FSGCoreEnumCast::FENovaSensorLocationType FSGCoreEnumCast::ToESensorLocation(const ESGNovaSensorLocation Enum)
{
switch (Enum)
{
case ESGNovaSensorLocation::Abduction:
return FENovaSensorLocationType::Abduction;
case ESGNovaSensorLocation::Flexion:
return FENovaSensorLocationType::Flexion;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FENovaSensorLocationType::Abduction;
}
ESGNovaSensorLocation FSGCoreEnumCast::ToESGNovaSensorLocation(const FENovaSensorLocationType Enum)
{
switch (Enum)
{
case FENovaSensorLocationType::Abduction:
return ESGNovaSensorLocation::Abduction;
case FENovaSensorLocationType::Flexion:
return ESGNovaSensorLocation::Flexion;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGNovaSensorLocation::None;
}
FSGCoreEnumCast::FEThumbMovementType FSGCoreEnumCast::ToEThumbMovement(const ESGThumbMovement Enum)
{
switch (Enum)
@@ -459,31 +648,141 @@ ESGThumbMovement FSGCoreEnumCast::ToESGThumbMovement(const FEThumbMovementType E
return ESGThumbMovement::None;
}
FSGCoreEnumCast::FEThumbSolverType FSGCoreEnumCast::ToEThumbSolver(const ESGThumbSolver Enum)
FSGCoreEnumCast::FENova2VibroMotorType FSGCoreEnumCast::ToENova2VibroMotor(const ESGNova2VibroMotor Enum)
{
switch (Enum)
{
case ESGThumbSolver::Interpolation:
return FEThumbSolverType::Interpolation;
case ESGNova2VibroMotor::Unknown:
return FENova2VibroMotorType::Unknown;
case ESGNova2VibroMotor::ThumbFingertip:
return FENova2VibroMotorType::ThumbFingertip;
case ESGNova2VibroMotor::IndexFingertip:
return FENova2VibroMotorType::IndexFingertip;
case ESGNova2VibroMotor::PalmIndexSide:
return FENova2VibroMotorType::PalmIndexSide;
case ESGNova2VibroMotor::PalmPinkySide:
return FENova2VibroMotorType::PalmPinkySide;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEThumbSolverType::Interpolation;
return FENova2VibroMotorType::Unknown;
}
ESGThumbSolver FSGCoreEnumCast::ToESGThumbSolver(const FEThumbSolverType Enum)
ESGNova2VibroMotor FSGCoreEnumCast::ToESGNova2VibroMotor(const FENova2VibroMotorType Enum)
{
switch (Enum)
{
case FEThumbSolverType::Interpolation:
return ESGThumbSolver::Interpolation;
case FENova2VibroMotorType::Unknown:
return ESGNova2VibroMotor::Unknown;
case FENova2VibroMotorType::ThumbFingertip:
return ESGNova2VibroMotor::ThumbFingertip;
case FENova2VibroMotorType::IndexFingertip:
return ESGNova2VibroMotor::IndexFingertip;
case FENova2VibroMotorType::PalmIndexSide:
return ESGNova2VibroMotor::PalmIndexSide;
case FENova2VibroMotorType::PalmPinkySide:
return ESGNova2VibroMotor::PalmPinkySide;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGThumbSolver::None;
return ESGNova2VibroMotor::None;
}
FSGCoreEnumCast::FENovaVibroMotorType FSGCoreEnumCast::ToENovaVibroMotor(const ESGNovaVibroMotor Enum)
{
switch (Enum)
{
case ESGNovaVibroMotor::Unknown:
return FENovaVibroMotorType::Unknown;
case ESGNovaVibroMotor::BackOfHand:
return FENovaVibroMotorType::BackOfHand;
case ESGNovaVibroMotor::ThumbTip:
return FENovaVibroMotorType::ThumbTip;
case ESGNovaVibroMotor::IndexFingertip:
return FENovaVibroMotorType::IndexFingertip;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FENovaVibroMotorType::Unknown;
}
ESGNovaVibroMotor FSGCoreEnumCast::ToESGNovaVibroMotor(const FENovaVibroMotorType Enum)
{
switch (Enum)
{
case FENovaVibroMotorType::Unknown:
return ESGNovaVibroMotor::Unknown;
case FENovaVibroMotorType::BackOfHand:
return ESGNovaVibroMotor::BackOfHand;
case FENovaVibroMotorType::ThumbTip:
return ESGNovaVibroMotor::ThumbTip;
case FENovaVibroMotorType::IndexFingertip:
return ESGNovaVibroMotor::IndexFingertip;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGNovaVibroMotor::None;
}
FSGCoreEnumCast::FEWaveformType FSGCoreEnumCast::ToEWaveformType(const ESGWaveformType Enum)
{
switch (Enum)
{
case ESGWaveformType::Unknown:
return FEWaveformType::Unknown;
case ESGWaveformType::Sine:
return FEWaveformType::Sine;
case ESGWaveformType::Square:
return FEWaveformType::Square;
case ESGWaveformType::SawDown:
return FEWaveformType::SawUp;
case ESGWaveformType::SawUp:
return FEWaveformType::SawDown;
case ESGWaveformType::Triangle:
return FEWaveformType::Triangle;
case ESGWaveformType::Noise:
return FEWaveformType::Noise;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
// Keep the compiler satisfied!
return FEWaveformType::Unknown;
}
ESGWaveformType FSGCoreEnumCast::ToESGWaveformType(const FEWaveformType Enum)
{
switch (Enum)
{
case FEWaveformType::Unknown:
return ESGWaveformType::Unknown;
case FEWaveformType::Sine:
return ESGWaveformType::Sine;
case FEWaveformType::Square:
return ESGWaveformType::Square;
case FEWaveformType::SawUp:
return ESGWaveformType::SawDown;
case FEWaveformType::SawDown:
return ESGWaveformType::SawUp;
case FEWaveformType::Triangle:
return ESGWaveformType::Triangle;
case FEWaveformType::Noise:
return ESGWaveformType::Noise;
default:
ensureAlwaysMsgf(false, TEXT("Unhandled enum cast item!"));
break;
}
return ESGWaveformType::None;
}
@@ -35,40 +35,48 @@
#pragma once
#include <SenseGlove/Core/Fingers.hpp>
#include <SenseGlove/Core/SenseGloveThumperCommand.hpp>
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGBuildHacks/SGInclude_Core_Fingers.h"
#include "SGBuildHacks/SGInclude_Core_HapticGloveCalibrationCheck.h"
#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h"
#include "SGBuildHacks/SGInclude_Core_HapticGlove.h"
#include "SGBuildHacks/SGInclude_Core_Library.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveHandProfile.h"
#include "SGBuildHacks/SGInclude_Core_NormalizationState.h"
#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h"
#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_NovaGlove.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveThumperCommand.h"
#include "SGBuildHacks/SGInclude_Core_SGDevice.h"
#include "SGBuildHacks/SGInclude_Core_Tracking.h"
#include "SGCoreImpl/SGHapticGloveCommandBufferImpl.h"
#include "SGCoreImpl/SGNova2GloveImpl.h"
#include "SGTypes/SGCoreTypes.h"
class SENSEGLOVECOREIMPL_API FSGCoreEnumCast
{
public:
typedef SGCore::EBackendType FEBackendType;
typedef SGCore::ECalibrationStage FECalibrationStageType;
typedef SGCore::SGDevice::EConnectionType FEConnectionType;
typedef SGCore::EDeviceType FEDeviceType;
typedef SGCore::EFinger FEFingerType;
typedef SGCore::EHapticChannelType FEHapticChannelType;
typedef SGCore::EHapticGloveCalibrationState FEHapticGloveCalibrationStateType;
typedef SGCore::EHapticLocation FEHapticLocationType;
typedef SGCore::Kinematics::EFingerMovement FEFingerMovementType;
typedef SGCore::SG::EFingerSolver FEFingerSolverType;
typedef SGCore::EPositionalTrackingHardware FEPositionalTrackingHardware;
typedef SGCore::Nova::ENormalizationState FENormalizationStateType;
typedef SGCore::Nova::Nova2GloveSensorData::ESensorLocation FENova2SensorLocationType;
typedef SGCore::Nova::NovaGloveSensorData::ESensorLocation FENovaSensorLocationType;
typedef SGCore::EPositionalTrackingHardware FEPositionalTrackingHardwareType;
typedef SGCore::Haptics::ESenseGloveThumperCommand FESenseGloveThumperCommandType;
typedef SGCore::Kinematics::EThumbMovement FEThumbMovementType;
typedef SGCore::SG::EThumbSolver FEThumbSolverType;
typedef SGCore::Nova::ENova2VibroMotor FENova2VibroMotorType;
typedef SGCore::Nova::ENovaVibroMotor FENovaVibroMotorType;
typedef SGCore::EWaveformType FEWaveformType;
public:
static FEBackendType ToEBackendType(ESGBackendType Enum);
static ESGBackendType ToESGBackendType(FEBackendType Enum);
static FECalibrationStageType ToECalibrationStage(ESGCalibrationStage Enum);
static ESGCalibrationStage ToESGCalibrationStage(FECalibrationStageType Enum);
static FEConnectionType ToEConnectionType(ESGConnectionType Enum);
static ESGConnectionType ToESGConnectionType(FEConnectionType Enum);
@@ -81,18 +89,39 @@ public:
static FEFingerMovementType ToEFingerMovement(ESGFingerMovement Enum);
static ESGFingerMovement ToESGFingerMovement(FEFingerMovementType Enum);
static FEFingerSolverType ToEFingerSolver(ESGFingerSolver Enum);
static ESGFingerSolver ToESGFingerSolver(FEFingerSolverType Enum);
static FEHapticChannelType ToEHapticChannelType(ESGHapticChannelType Enum);
static ESGHapticChannelType ToESGHapticChannelType(FEHapticChannelType Enum);
static FEPositionalTrackingHardware ToEPositionalTrackingHardware(ESGPositionalTrackingHardware Enum);
static ESGPositionalTrackingHardware ToESGPositionalTrackingHardware(FEPositionalTrackingHardware Enum);
static FEHapticGloveCalibrationStateType ToEHapticGloveCalibrationState(ESGHapticGloveCalibrationState Enum);
static ESGHapticGloveCalibrationState ToESGHapticGloveCalibrationState(FEHapticGloveCalibrationStateType Enum);
static FEHapticLocationType ToEHapticLocation(ESGHapticLocation Enum);
static ESGHapticLocation ToESGHapticLocation(FEHapticLocationType Enum);
static FENormalizationStateType ToENormalizationState(ESGNormalizationState Enum);
static ESGNormalizationState ToESGNormalizationState(FENormalizationStateType Enum);
static FEPositionalTrackingHardwareType ToEPositionalTrackingHardware(ESGPositionalTrackingHardware Enum);
static ESGPositionalTrackingHardware ToESGPositionalTrackingHardware(FEPositionalTrackingHardwareType Enum);
static FESenseGloveThumperCommandType ToESenseGloveThumperCommand(ESGSenseGloveThumperCommand Enum);
static ESGSenseGloveThumperCommand ToESGSenseGloveThumperCommand(FESenseGloveThumperCommandType Enum);
static FENova2SensorLocationType ToESensorLocation(ESGNova2SensorLocation Enum);
static ESGNova2SensorLocation ToESGNova2SensorLocation(FENova2SensorLocationType Enum);
static FENovaSensorLocationType ToESensorLocation(ESGNovaSensorLocation Enum);
static ESGNovaSensorLocation ToESGNovaSensorLocation(FENovaSensorLocationType Enum);
static FEThumbMovementType ToEThumbMovement(ESGThumbMovement Enum);
static ESGThumbMovement ToESGThumbMovement(FEThumbMovementType Enum);
static FEThumbSolverType ToEThumbSolver(ESGThumbSolver Enum);
static ESGThumbSolver ToESGThumbSolver(FEThumbSolverType Enum);
static FENova2VibroMotorType ToENova2VibroMotor(ESGNova2VibroMotor Enum);
static ESGNova2VibroMotor ToESGNova2VibroMotor(FENova2VibroMotorType Enum);
static FENovaVibroMotorType ToENovaVibroMotor(ESGNovaVibroMotor Enum);
static ESGNovaVibroMotor ToESGNovaVibroMotor(FENovaVibroMotorType Enum);
static FEWaveformType ToEWaveformType(ESGWaveformType Enum);
static ESGWaveformType ToESGWaveformType(FEWaveformType Enum);
};
@@ -0,0 +1,276 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGCustomWaveformImpl.h"
#include "Containers/StringConv.h"
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
struct FSGCustomWaveformImpl::FImpl
{
/************************
* Member variables
************************/
FCustomWaveformType CustomWaveform;
/************************
* Owner object
************************/
FSGCustomWaveformImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGCustomWaveformImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FString FSGCustomWaveformImpl::ToString(const ESGWaveformType Type)
{
FString String{FCustomWaveformType::ToString(FSGCoreEnumCast::ToEWaveformType(Type)).c_str()};
return MoveTemp(String);
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl(const float Amplitude, const float Duration)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->CustomWaveform = FCustomWaveformType{Amplitude, Duration};
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl(const float Amplitude, const float Duration, const float Frequency)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->CustomWaveform = FCustomWaveformType{Amplitude, Duration, Frequency};
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl(const FCustomWaveformType& CustomWaveform)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->CustomWaveform = CustomWaveform;
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl(const FSGCustomWaveformImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGCustomWaveformImpl::FSGCustomWaveformImpl(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT = default;
FSGCustomWaveformImpl::~FSGCustomWaveformImpl() = default;
FSGCustomWaveformImpl& FSGCustomWaveformImpl::operator=(const FSGCustomWaveformImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGCustomWaveformImpl& FSGCustomWaveformImpl::operator=(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT = default;
const FSGCustomWaveformImpl::FCustomWaveformType& FSGCustomWaveformImpl::ToCustomWaveform() const
{
return Pimpl->CustomWaveform;
}
FSGCustomWaveformImpl::FCustomWaveformType& FSGCustomWaveformImpl::ToCustomWaveform()
{
return Pimpl->CustomWaveform;
}
float FSGCustomWaveformImpl::GetAmplitude() const
{
return Pimpl->CustomWaveform.GetAmplitude();
}
void FSGCustomWaveformImpl::SetAmplitude(const float Amplitude)
{
Pimpl->CustomWaveform.SetAmplitude(Amplitude);
}
ESGWaveformType FSGCustomWaveformImpl::GetWaveType() const
{
return FSGCoreEnumCast::ToESGWaveformType(Pimpl->CustomWaveform.GetWaveType());
}
void FSGCustomWaveformImpl::SetWaveType(const ESGWaveformType Type)
{
Pimpl->CustomWaveform.SetWaveType(FSGCoreEnumCast::ToEWaveformType(Type));
}
bool FSGCustomWaveformImpl::IsInfinite() const
{
return Pimpl->CustomWaveform.IsInfinite();
}
void FSGCustomWaveformImpl::SetInfinite(const bool bInfinite)
{
return Pimpl->CustomWaveform.SetInfinite(bInfinite);
}
int32 FSGCustomWaveformImpl::GetRepeatAmount() const
{
return Pimpl->CustomWaveform.GetRepeatAmount();
}
void FSGCustomWaveformImpl::SetRepeatAmount(const int32 Amount)
{
Pimpl->CustomWaveform.SetRepeatAmount(Amount);
}
float FSGCustomWaveformImpl::GetAttackTime() const
{
return Pimpl->CustomWaveform.GetAttackTime();
}
void FSGCustomWaveformImpl::SetAttackTime(const float Time)
{
Pimpl->CustomWaveform.SetAttackTime(Time);
}
float FSGCustomWaveformImpl::GetSustainTime() const
{
return Pimpl->CustomWaveform.GetSustainTime();
}
void FSGCustomWaveformImpl::SetSustainTime(const float Time)
{
Pimpl->CustomWaveform.SetSustainTime(Time);
}
float FSGCustomWaveformImpl::GetDecayTime() const
{
return Pimpl->CustomWaveform.GetDecayTime();
}
void FSGCustomWaveformImpl::SetDecayTime(const float Time)
{
Pimpl->CustomWaveform.SetDecayTime(Time);
}
float FSGCustomWaveformImpl::GetFrequencyStart() const
{
return Pimpl->CustomWaveform.GetFrequencyStart();
}
void FSGCustomWaveformImpl::SetFrequencyStart(const float Frequency)
{
Pimpl->CustomWaveform.SetFrequencyStart(Frequency);
}
float FSGCustomWaveformImpl::GetFrequencyEnd() const
{
return Pimpl->CustomWaveform.GetFrequencyEnd();
}
void FSGCustomWaveformImpl::SetFrequencyEnd(const float Frequency)
{
Pimpl->CustomWaveform.SetFrequencyEnd(Frequency);
}
float FSGCustomWaveformImpl::GetFrequencySwitchTime() const
{
return Pimpl->CustomWaveform.GetFrequencySwitchTime();
}
void FSGCustomWaveformImpl::SetFrequencySwitchTime(const float Time)
{
Pimpl->CustomWaveform.SetFrequencySwitchTime(Time);
}
float FSGCustomWaveformImpl::GetFrequencySwitchFactor() const
{
return Pimpl->CustomWaveform.GetFrequencySwitchFactor();
}
void FSGCustomWaveformImpl::SetFrequencySwitchFactor(const float Factor)
{
Pimpl->CustomWaveform.SetFrequencySwitchFactor(Factor);
}
float FSGCustomWaveformImpl::GetEffectTime() const
{
return Pimpl->CustomWaveform.GetEffectTime();
}
float FSGCustomWaveformImpl::GetTotalEffectTime() const
{
return Pimpl->CustomWaveform.GetTotalEffectTime();
}
bool FSGCustomWaveformImpl::FrequencyJumps() const
{
return Pimpl->CustomWaveform.FrequencyJumps();
}
bool FSGCustomWaveformImpl::Equals(const FSGCustomWaveformImpl& CustomWaveformImpl) const
{
return Pimpl->CustomWaveform.Equals(CustomWaveformImpl.ToCustomWaveform());
}
FString FSGCustomWaveformImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(Pimpl->CustomWaveform.ToString().c_str())};
return MoveTemp(String);
}
FSGCustomWaveformImpl::FImpl::FImpl(FSGCustomWaveformImpl* InOwner)
: Owner(InOwner)
{
}
FSGCustomWaveformImpl::FImpl::~FImpl() = default;
void FSGCustomWaveformImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -43,7 +43,9 @@
#include "SGBuildHacks/SGInclude_Core_SGDevice.h"
#include "SGCoreImpl/SGBetaDeviceImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGHapticChannelInfoImpl.h"
#include "SGCoreImpl/SGHapticGloveImpl.h"
#include "SGCoreImpl/SGNova2GloveImpl.h"
#include "SGCoreImpl/SGNovaGloveImpl.h"
#include "SGCoreImpl/SGSenseGloveImpl.h"
#include "Templates/Casts.h"
@@ -82,7 +84,19 @@ void FSGDeviceImpl::ParseFirmware(const FString& RawFirmware, int32& OutMainVers
FSGDeviceType::ParseFirmware(TCHAR_TO_UTF8(*RawFirmware), OutMainVersion, OutSubVersion);
}
FString FSGDeviceImpl::ToString(ESGDeviceType DeviceType)
bool FSGDeviceImpl::FirmwareNewerThan(const int32 MyFirmwareMain, const int32 MyFirmwareSub,
const int32 ReferenceMain, const int32 ReferenceSub, const bool bInclusive)
{
return FSGDeviceType::FirmwareNewerThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive);
}
bool FSGDeviceImpl::FirmwareOlderThan(const int32 MyFirmwareMain, const int32 MyFirmwareSub,
const int32 ReferenceMain, const int32 ReferenceSub, const bool bInclusive)
{
return FSGDeviceType::FirmwareOlderThan(MyFirmwareMain, MyFirmwareSub, ReferenceMain, ReferenceSub, bInclusive);
}
FString FSGDeviceImpl::ToString(const ESGDeviceType DeviceType)
{
FString String{UTF8_TO_TCHAR(FSGDeviceType::ToString(FSGCoreEnumCast::ToEDeviceType(DeviceType)).c_str())};
return MoveTemp(String);
@@ -149,6 +163,13 @@ TSharedRef<FSGHapticGloveImpl> FSGDeviceImpl::ToHapticGloveImplRef()
return SharedThis(HapticGlove);
}
TSharedRef<FSGNova2GloveImpl> FSGDeviceImpl::ToNova2GloveImplRef()
{
FSGNova2GloveImpl* Nova2Glove(dynamic_cast<FSGNova2GloveImpl*>(this));
ensureAlwaysMsgf(Nova2Glove, TEXT("Invalid Nova2Glove!"));
return SharedThis(Nova2Glove);
}
TSharedRef<FSGNovaGloveImpl> FSGDeviceImpl::ToNovaGloveImplRef()
{
FSGNovaGloveImpl* NovaGlove(dynamic_cast<FSGNovaGloveImpl*>(this));
@@ -196,6 +217,16 @@ FString FSGDeviceImpl::GetFirmwareString() const
return MoveTemp(String);
}
bool FSGDeviceImpl::FirmwareNewerThan(const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const
{
return ToSGDevicePtrChecked()->FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive);
}
bool FSGDeviceImpl::FirmwareOlderThan(const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const
{
return ToSGDevicePtrChecked()->FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive);
}
FString FSGDeviceImpl::GetAddress() const
{
FString String(UTF8_TO_TCHAR(ToSGDevicePtrChecked()->GetAddress().c_str()));
@@ -252,6 +283,21 @@ bool FSGDeviceImpl::GetBatteryLevel(float& OutLevel)
return ToSGDevicePtrChecked()->GetBatteryLevel(OutLevel);
}
void FSGDeviceImpl::SetHapticChannels(const FSGHapticChannelInfoImpl& Channels)
{
ToSGDevicePtrChecked()->SetHapticChannels(Channels.ToHapticChannelInfo());
}
int32 FSGDeviceImpl::GetHapticChannelCount() const
{
return ToSGDevicePtrChecked()->GetHapticChannelCount();
}
int32 FSGDeviceImpl::GetHapticChannelCount(const ESGHapticChannelType ChannelType) const
{
return ToSGDevicePtrChecked()->GetHapticChannelCount(FSGCoreEnumCast::ToEHapticChannelType(ChannelType));
}
FString FSGDeviceImpl::ToString() const
{
FString String(UTF8_TO_TCHAR(ToSGDevicePtrChecked()->ToString().c_str()));
@@ -147,11 +147,12 @@ bool FSGDeviceListImpl::GetSensorDataString(const int32 IpcIndex, const FString&
return bReturn;
}
bool FSGDeviceListImpl::SendHaptics(const int32 IpcIndex, const FString& IpcAddress, const FString& Commands)
bool FSGDeviceListImpl::SendHaptics(
const int32 IpcIndex, const FString& IpcAddress, const int32 ChannelIndex, const FString& Commands)
{
std::string IpcAddressString(TCHAR_TO_UTF8(*IpcAddress));
std::string CommandsString(TCHAR_TO_UTF8(*Commands));
return FDeviceListType::SendHaptics(IpcIndex, MoveTemp(IpcAddressString), MoveTemp(CommandsString));
return FDeviceListType::SendHaptics(IpcIndex, MoveTemp(IpcAddressString), ChannelIndex, MoveTemp(CommandsString));
}
FString FSGDeviceListImpl::GetDeviceStringAt(const int32 IpcIndex, const FString& IpcAddress, const int32 Index)
@@ -162,6 +162,18 @@ int32 FSGDeviceModelImpl::GetSubFirmwareVersion() const
return Pimpl->DeviceModel.GetSubFirmwareVersion();
}
bool FSGDeviceModelImpl::FirmwareNewerThan(
const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const
{
return Pimpl->DeviceModel.FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive);
}
bool FSGDeviceModelImpl::FirmwareOlderThan(
const int32 FirmwareMain, const int32 FirmwareSub, const bool bInclusive) const
{
return Pimpl->DeviceModel.FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive);
}
FSGDeviceModelImpl::FImpl::FImpl(FSGDeviceModelImpl* InOwner)
: Owner(InOwner)
{
File diff suppressed because it is too large Load Diff
@@ -1,258 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGFingerCommandImpl.h"
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_FingerCommand.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGBuildHacks/SGInclude_Core_TimedBuzzCommand.h"
#include "SGCoreImpl/SGForceFeedbackCommandImpl.h"
#include "SGCoreImpl/SGTimedBuzzCommandImpl.h"
#include "SGUtils/SGArrayUtils.h"
#include "Templates/Casts.h"
struct FSGFingerCommandImpl::FImpl
{
/************************
* Static methods
************************/
static TSharedPtr<FFingerCommandType> MakeNewFingerCommand(TSharedPtr<FFingerCommandType> Ptr);
/************************
* Member variables
************************/
TSharedPtr<FFingerCommandType> FingerCommand;
/************************
* Owner object
************************/
FSGFingerCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGFingerCommandImpl* InOwner);
~FImpl();
/************************
* The copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs);
FImpl& operator=(const FImpl& Rhs);
};
FSGFingerCommandImpl::FSGFingerCommandImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGFingerCommandImpl::FSGFingerCommandImpl(const TArray<int32>& Levels)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<int32> LevelsVector{
FSGArrayUtils::ToStdVector<int32>(Levels)
};
Pimpl->FingerCommand = MakeShared<FFingerCommandType>(MoveTemp(LevelsVector));
}
FSGFingerCommandImpl::FSGFingerCommandImpl(const FFingerCommandType& FingerCommand)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->FingerCommand = MakeShared<FFingerCommandType>(FingerCommand);
}
FSGFingerCommandImpl::FSGFingerCommandImpl(const TSharedRef<FFingerCommandType> FingerCommand)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->FingerCommand = FImpl::MakeNewFingerCommand(FingerCommand);
}
FSGFingerCommandImpl::FSGFingerCommandImpl(const FSGFingerCommandImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
Pimpl->FingerCommand = FImpl::MakeNewFingerCommand(Rhs.Pimpl->FingerCommand);
}
FSGFingerCommandImpl::FSGFingerCommandImpl(FSGFingerCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGFingerCommandImpl::~FSGFingerCommandImpl() = default;
FSGFingerCommandImpl& FSGFingerCommandImpl::operator=(const FSGFingerCommandImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGFingerCommandImpl& FSGFingerCommandImpl::operator=(FSGFingerCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGFingerCommandImpl::FFingerCommandType& FSGFingerCommandImpl::ToFingerCommand() const
{
return *Pimpl->FingerCommand;
}
TSharedRef<FSGFingerCommandImpl::FFingerCommandType> FSGFingerCommandImpl::ToFingerCommandRef() const
{
return Pimpl->FingerCommand.ToSharedRef();
}
FSGFingerCommandImpl::FFingerCommandType& FSGFingerCommandImpl::ToFingerCommand()
{
return *Pimpl->FingerCommand;
}
TSharedRef<FSGFingerCommandImpl::FFingerCommandType> FSGFingerCommandImpl::ToFingerCommandRef()
{
return Pimpl->FingerCommand.ToSharedRef();
}
TSharedRef<FSGFingerCommandImpl> FSGFingerCommandImpl::ToFingerCommandImplRef()
{
return SharedThis(this);
}
TSharedRef<FSGBuzzCommandImpl> FSGFingerCommandImpl::ToBuzzCommandImplRef()
{
FSGBuzzCommandImpl* BuzzCommandImpl{dynamic_cast<FSGBuzzCommandImpl*>(this)};
ensureAlwaysMsgf(BuzzCommandImpl, TEXT("Invalid BuzzCommandImpl!"));
return SharedThis(BuzzCommandImpl);
}
TSharedRef<FSGForceFeedbackCommandImpl> FSGFingerCommandImpl::ToForceFeedbackCommandImplRef()
{
FSGForceFeedbackCommandImpl* ForceFeedbackCommandImpl{
dynamic_cast<FSGForceFeedbackCommandImpl*>(this)};
ensureAlwaysMsgf(ForceFeedbackCommandImpl, TEXT("Invalid ForceFeedbackCommandImpl!"));
return SharedThis(ForceFeedbackCommandImpl);
}
TSharedRef<FSGTimedBuzzCommandImpl> FSGFingerCommandImpl::ToTimedBuzzCommandImplRef()
{
FSGTimedBuzzCommandImpl* TimedBuzzCommandImpl{dynamic_cast<FSGTimedBuzzCommandImpl*>(this)};
ensureAlwaysMsgf(TimedBuzzCommandImpl, TEXT("Invalid TimedBuzzCommandImpl!"));
return SharedThis(TimedBuzzCommandImpl);
}
TArray<int32> FSGFingerCommandImpl::GetLevels() const
{
return FSGArrayUtils::FromStdVector<int32>(Pimpl->FingerCommand->GetLevels());
}
int32 FSGFingerCommandImpl::GetLevel(const int32 Finger) const
{
return Pimpl->FingerCommand->GetLevel(Finger);
}
void FSGFingerCommandImpl::SetLevel(const int32 Finger, const int32 Value)
{
return Pimpl->FingerCommand->SetLevel(Finger, Value);
}
bool FSGFingerCommandImpl::Equals(const FSGFingerCommandImpl& FingerCommandImpl) const
{
return Pimpl->FingerCommand->Equals(FingerCommandImpl.ToFingerCommand());
}
FString FSGFingerCommandImpl::ToString() const
{
return UTF8_TO_TCHAR(Pimpl->FingerCommand->ToString().c_str());
}
TSharedPtr<FSGFingerCommandImpl::FFingerCommandType> FSGFingerCommandImpl::FImpl::MakeNewFingerCommand(
const TSharedPtr<FFingerCommandType> Ptr)
{
{
FSGTimedBuzzCommandImpl::FTimedBuzzCommandType* TimedBuzzCommand{dynamic_cast<
FSGTimedBuzzCommandImpl::FTimedBuzzCommandType*>(Ptr.Get())};
if (TimedBuzzCommand)
{
return MakeShared<FSGTimedBuzzCommandImpl::FTimedBuzzCommandType>(*TimedBuzzCommand);
}
}
{
FSGBuzzCommandImpl::FBuzzCommandType* BuzzCommand{dynamic_cast<
FSGBuzzCommandImpl::FBuzzCommandType*>(Ptr.Get())};
if (BuzzCommand)
{
return MakeShared<FSGBuzzCommandImpl::FBuzzCommandType>(*BuzzCommand);
}
}
{
FSGForceFeedbackCommandImpl::FForceFeedbackCommandType* ForceFeedbackCommand{dynamic_cast<
FSGForceFeedbackCommandImpl::FForceFeedbackCommandType*>(Ptr.Get())};
if (ForceFeedbackCommand)
{
return MakeShared<FSGForceFeedbackCommandImpl::FForceFeedbackCommandType>(*ForceFeedbackCommand);
}
}
return MakeShared<FFingerCommandType>(*Ptr);
}
FSGFingerCommandImpl::FImpl::FImpl(FSGFingerCommandImpl* InOwner)
: FingerCommand(MakeShared<FFingerCommandType>()),
Owner(InOwner)
{
}
FSGFingerCommandImpl::FImpl::~FImpl() = default;
FSGFingerCommandImpl::FImpl::FImpl(const FImpl& Rhs)
: FingerCommand(MakeNewFingerCommand(Rhs.FingerCommand))
{
}
FSGFingerCommandImpl::FImpl& FSGFingerCommandImpl::FImpl::operator=(const FImpl& Rhs)
{
FingerCommand = MakeNewFingerCommand(Rhs.FingerCommand);
return *this;
}
void FSGFingerCommandImpl::FImplDeleter::operator()(const FSGFingerCommandImpl::FImpl* P) const
{
delete P;
}
@@ -1,169 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGForceFeedbackCommandImpl.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGForceFeedbackCommandImpl::FImpl
{
/************************
* Member variables
************************/
/************************
* Owner object
************************/
FSGForceFeedbackCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGForceFeedbackCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
const FSGForceFeedbackCommandImpl& FSGForceFeedbackCommandImpl::Off()
{
static const FSGForceFeedbackCommandImpl Command(FForceFeedbackCommandType::Off());
return Command;
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl()
: FSGFingerCommandImpl(MakeShared<FForceFeedbackCommandType>()),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(const TArray<int32>& ForceFeedbackLevels)
: FSGFingerCommandImpl(MakeShared<FForceFeedbackCommandType>(
FSGArrayUtils::ToStdVector<int32>(ForceFeedbackLevels))),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(const int32 Thumb, const int32 Index, const int32 Middle,
const int32 Ring, const int32 Pinky)
: FSGFingerCommandImpl(MakeShared<FForceFeedbackCommandType>(Thumb, Index, Middle, Ring, Pinky)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(const ESGFinger Finger, const int32 BuzzLevel)
: FSGFingerCommandImpl(MakeShared<FForceFeedbackCommandType>(FSGCoreEnumCast::ToEFinger(Finger), BuzzLevel)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(const FForceFeedbackCommandType& ForceFeedbackCommand)
: FSGFingerCommandImpl(MakeShared<FForceFeedbackCommandType>(ForceFeedbackCommand)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(
const TSharedRef<FForceFeedbackCommandType> ForceFeedbackCommand)
: FSGFingerCommandImpl(ForceFeedbackCommand),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(const FSGForceFeedbackCommandImpl& Rhs)
: FSGFingerCommandImpl(Rhs),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGForceFeedbackCommandImpl::FSGForceFeedbackCommandImpl(FSGForceFeedbackCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGForceFeedbackCommandImpl::~FSGForceFeedbackCommandImpl() = default;
FSGForceFeedbackCommandImpl& FSGForceFeedbackCommandImpl::operator=(const FSGForceFeedbackCommandImpl& Rhs)
{
FSGFingerCommandImpl::operator=(Rhs);
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGForceFeedbackCommandImpl& FSGForceFeedbackCommandImpl::operator=(FSGForceFeedbackCommandImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGForceFeedbackCommandImpl::FForceFeedbackCommandType&
FSGForceFeedbackCommandImpl::ToForceFeedbackCommand() const
{
return *StaticCastSharedRef<FForceFeedbackCommandType>(ToFingerCommandRef());
}
TSharedRef<FSGForceFeedbackCommandImpl::FForceFeedbackCommandType>
FSGForceFeedbackCommandImpl::ToForceFeedbackCommandRef() const
{
return StaticCastSharedRef<FForceFeedbackCommandType>(ToFingerCommandRef());
}
FSGForceFeedbackCommandImpl FSGForceFeedbackCommandImpl::Copy() const
{
return FSGForceFeedbackCommandImpl(ToForceFeedbackCommand().Copy());
}
FSGForceFeedbackCommandImpl FSGForceFeedbackCommandImpl::Merge(const FSGForceFeedbackCommandImpl& Command) const
{
return FSGForceFeedbackCommandImpl(ToForceFeedbackCommand().Merge(Command.ToForceFeedbackCommand()));
}
FSGForceFeedbackCommandImpl::FImpl::FImpl(FSGForceFeedbackCommandImpl* InOwner)
: Owner(InOwner)
{
}
FSGForceFeedbackCommandImpl::FImpl::~FImpl() = default;
void FSGForceFeedbackCommandImpl::FImplDeleter::operator()(const FSGForceFeedbackCommandImpl::FImpl* P) const
{
delete P;
}
@@ -81,82 +81,21 @@ struct FSGHandInterpolatorImpl::FImpl
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGHandInterpolatorImpl FSGHandInterpolatorImpl::Default(const bool bRightHanded)
{
FSGHandInterpolatorImpl HandInterpolatorImpl(FHandInterpolatorType::Default(bRightHanded));
return MoveTemp(HandInterpolatorImpl);
}
FSGHandInterpolatorImpl FSGHandInterpolatorImpl::Deserialize(const FString& SerializedString)
FSGHandInterpolatorImpl FSGHandInterpolatorImpl::Deserialize(const FString& SerializedString, const bool bRightHanded)
{
std::string Serialized(TCHAR_TO_UTF8(*SerializedString));
FSGHandInterpolatorImpl GlovePose(FHandInterpolatorType::Deserialize(MoveTemp(Serialized)));
FSGHandInterpolatorImpl GlovePose(FHandInterpolatorType::Deserialize(MoveTemp(Serialized), bRightHanded));
return MoveTemp(GlovePose);
}
TArray<FVector> FSGHandInterpolatorImpl::InterpolateFingerAngles(
const ESGFinger Finger, const FSGHandInterpolatorImpl& Interpolator, const FVector& TotalGloveAngles)
{
TArray<FVector> Angles{
FSGArrayUtils::FromSenseGloveAngles<FSGVect3DImpl::FVect3DType>(
FHandInterpolatorType::InterpolateFingerAngles(
FSGCoreEnumCast::ToEFinger(Finger), Interpolator.ToHandInterpolator(),
FSGAngles::TransformToSenseGlove<FSGVect3DImpl::FVect3DType>(TotalGloveAngles)))
};
return MoveTemp(Angles);
}
TArray<FVector> FSGHandInterpolatorImpl::InterpolateThumbAngles(const FSGHandInterpolatorImpl& Interpolator,
const FVector& TotalGloveAngles)
{
TArray<FVector> Angles{
FSGArrayUtils::FromSenseGloveAngles<FSGVect3DImpl::FVect3DType>(
FHandInterpolatorType::InterpolateThumbAngles(
Interpolator.ToHandInterpolator(),
FSGAngles::TransformToSenseGlove<FSGVect3DImpl::FVect3DType>(TotalGloveAngles)))
};
return MoveTemp(Angles);
}
TArray<TArray<FVector>> FSGHandInterpolatorImpl::InterpolateHandAngles(const FSGHandInterpolatorImpl& Interpolator,
const TArray<FVector>& TotalAngles)
{
std::vector<FSGVect3DImpl::FVect3DType> TotalAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(TotalAngles)
};
TArray<TArray<FVector>> Angles{
FSGArrayUtils::FromSenseGloveAngles<FSGVect3DImpl::FVect3DType>(
FHandInterpolatorType::InterpolateHandAngles(
Interpolator.ToHandInterpolator(), MoveTemp(TotalAnglesVector)))
};
return MoveTemp(Angles);
}
FSGHandInterpolatorImpl::FSGHandInterpolatorImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const TArray<TArray<FSGInterpolationSetImpl>>& JointInterpolations)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const bool bRightHanded)
{
std::vector<std::vector<FSGInterpolationSetImpl::FInterpolationSetType>> JointInterpolationsVector{
FSGArrayUtils::ToStdVector<FSGInterpolationSetImpl, FSGInterpolationSetImpl::FInterpolationSetType,
&FSGInterpolationSetImpl::ToInterpolationSet>(JointInterpolations)
};
Pimpl->HandInterpolator = FHandInterpolatorType(JointInterpolationsVector);
}
FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const TArray<TArray<FSGInterpolationSetImpl>>& JointInterpolations,
const FQuat& CmcStartRotation)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<std::vector<FSGInterpolationSetImpl::FInterpolationSetType>> JointInterpolationsVector{
FSGArrayUtils::ToStdVector<FSGInterpolationSetImpl, FSGInterpolationSetImpl::FInterpolationSetType,
&FSGInterpolationSetImpl::ToInterpolationSet>(JointInterpolations)
};
Pimpl->HandInterpolator = FHandInterpolatorType(JointInterpolationsVector,
FSGQuatImpl(CmcStartRotation).ToQuat());
Pimpl->HandInterpolator = FHandInterpolatorType(bRightHanded);
}
FSGHandInterpolatorImpl::FSGHandInterpolatorImpl(const FHandInterpolatorType& HandInterpolator)
@@ -190,75 +129,37 @@ const FSGHandInterpolatorImpl::FHandInterpolatorType& FSGHandInterpolatorImpl::T
return Pimpl->HandInterpolator;
}
TArray<TArray<FSGInterpolationSetImpl>> FSGHandInterpolatorImpl::GetJointInterpolations() const
float FSGHandInterpolatorImpl::CalculateAngle(
const ESGFingerMovement Movement, const float Value, const bool bApplyLimits) const
{
const TArray<TArray<FSGInterpolationSetImpl>> JointInterpolations{
FSGArrayUtils::FromStdVector<FSGInterpolationSetImpl::FInterpolationSetType, FSGInterpolationSetImpl>(
Pimpl->HandInterpolator.GetJointInterpolations())
return FSGAngles::TransformToUnreal(
Movement, Pimpl->HandInterpolator.CalculateAngle(
FSGCoreEnumCast::ToEFingerMovement(Movement), Value, bApplyLimits));
}
float FSGHandInterpolatorImpl::CalculateAngle(
const ESGThumbMovement Movement, const float Value, const bool bApplyLimits) const
{
return FSGAngles::TransformToUnreal(
Movement, Pimpl->HandInterpolator.CalculateAngle(
FSGCoreEnumCast::ToEThumbMovement(Movement), Value, bApplyLimits));
}
TArray<TArray<FVector>> FSGHandInterpolatorImpl::InterpolateHandAngles(
const TArray<TArray<float>>& Flexions, const TArray<float>& Abductions, const float CmcTwist)
{
std::vector<std::vector<float>> FlexionsVector{
FSGArrayUtils::ToSenseGloveAngles(Flexions)
};
return JointInterpolations;
}
FQuat FSGHandInterpolatorImpl::GetCmcStartRotation() const
{
return FSGQuatImpl(Pimpl->HandInterpolator.GetCmcStartRotation()).ToFQuat();
}
float FSGHandInterpolatorImpl::CalculateAngle(const ESGFinger Finger, const int32 Movement, const float Value) const
{
return FSGAngles::TransformToUnreal(
Movement, Pimpl->HandInterpolator.CalculateAngle(FSGCoreEnumCast::ToEFinger(Finger), Movement, Value));
}
float FSGHandInterpolatorImpl::CalculateAngle(const ESGFinger Finger, const ESGFingerMovement Movement,
const float Value) const
{
return FSGAngles::TransformToUnreal(
Movement, Pimpl->HandInterpolator.CalculateAngle(FSGCoreEnumCast::ToEFinger(Finger),
FSGCoreEnumCast::ToEFingerMovement(Movement), Value));
}
float FSGHandInterpolatorImpl::CalculateAngle(const ESGFinger Finger, const ESGThumbMovement Movement,
const float Value) const
{
return FSGAngles::TransformToUnreal(
Movement, Pimpl->HandInterpolator.CalculateAngle(FSGCoreEnumCast::ToEFinger(Finger),
FSGCoreEnumCast::ToEThumbMovement(Movement), Value));
}
void FSGHandInterpolatorImpl::SetInterpolation(
const int32 Finger, const int32 Movement,
const float InputAt0, const float InputAt1, const float AngleAt0, const float AngleAt1)
{
Pimpl->HandInterpolator.SetInterpolation(Finger, Movement, InputAt0, InputAt1,
FSGAngles::TransformToUnreal(Movement, AngleAt0),
FSGAngles::TransformToUnreal(Movement, AngleAt1));
}
void FSGHandInterpolatorImpl::SetInterpolation(
const ESGFinger Finger, const ESGFingerMovement Movement,
const float InputAt0, const float InputAt1, const float AngleAt0, const float AngleAt1)
{
Pimpl->HandInterpolator.SetInterpolation(
FSGCoreEnumCast::ToEFinger(Finger), FSGCoreEnumCast::ToEFingerMovement(Movement),
InputAt0, InputAt1,
FSGAngles::TransformToUnreal(Movement, AngleAt0),
FSGAngles::TransformToUnreal(Movement, AngleAt1));
}
void FSGHandInterpolatorImpl::SetInterpolation(
const ESGThumbMovement Movement,
const float InputAt0, const float InputAt1, const float AngleAt0, const float AngleAt1)
{
Pimpl->HandInterpolator.SetInterpolation(FSGCoreEnumCast::ToEThumbMovement(Movement),
InputAt0, InputAt1,
FSGAngles::TransformToUnreal(Movement, AngleAt0),
FSGAngles::TransformToUnreal(Movement, AngleAt1));
}
FSGInterpolationSetImpl FSGHandInterpolatorImpl::GetInterpolation(const int32 Finger, const int32 Movement) const
{
return FSGInterpolationSetImpl(Pimpl->HandInterpolator.GetInterpolation(Finger, Movement));
std::vector<float> AbductionsVector{
FSGArrayUtils::ToSenseGloveAngles(Abductions)
};
TArray<TArray<FVector>> Angles{
FSGArrayUtils::FromSenseGloveAngles<FSGVect3DImpl::FVect3DType>(
Pimpl->HandInterpolator.InterpolateHandAngles(
MoveTemp(FlexionsVector), MoveTemp(AbductionsVector), CmcTwist))
};
return MoveTemp(Angles);
}
bool FSGHandInterpolatorImpl::Equals(const FSGHandInterpolatorImpl& HandInterpolatorImpl) const
@@ -0,0 +1,214 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGHandLayerImpl.h"
#include <vector>
#include "Containers/StringConv.h"
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGBuildHacks/SGInclude_Core_HandLayer.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGCustomWaveformImpl.h"
#include "SGCoreImpl/SGCustomWaveformImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGHapticGloveImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
bool FSGHandLayerImpl::DeviceConnected(const bool bRightHanded)
{
return FHandLayerType::DeviceConnected(bRightHanded);
}
ESGDeviceType FSGHandLayerImpl::GetDeviceType(const bool bRightHanded)
{
return FSGCoreEnumCast::ToESGDeviceType(FHandLayerType::GetDeviceType(bRightHanded));
}
bool FSGHandLayerImpl::GetFirstGloveHandedness()
{
return FHandLayerType::GetFirstGloveHandedness();
}
int32 FSGHandLayerImpl::GlovesConnected()
{
return FHandLayerType::GlovesConnected();
}
bool FSGHandLayerImpl::GetGloveInstance(const bool bRightHanded, TSharedPtr<FSGHapticGloveImpl>& OutGlove)
{
FSGHapticGloveImpl::FHapticGlovePtrType Glove;
const bool bResult = FHandLayerType::GetGloveInstance(bRightHanded, Glove);
if (bResult)
{
OutGlove = MakeShared<FSGHapticGloveImpl>(MoveTemp(Glove));
}
return bResult;
}
ESGHapticGloveCalibrationState FSGHandLayerImpl::GetCalibrationState(const bool bRightHanded)
{
return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(FHandLayerType::GetCalibrationState(bRightHanded));
}
FString FSGHandLayerImpl::GetCalibrationInstructions(const bool bRightHanded)
{
FString Instructions{UTF8_TO_TCHAR(FHandLayerType::GetCalibrationInstructions(bRightHanded).c_str())};
return MoveTemp(Instructions);
}
void FSGHandLayerImpl::ResetCalibration(const bool bRightHanded)
{
FHandLayerType::ResetCalibration(bRightHanded);
}
void FSGHandLayerImpl::EndCalibration(const bool bRightHanded)
{
FHandLayerType::EndCalibration(bRightHanded);
}
bool FSGHandLayerImpl::GetHandPose(const bool bRightHanded, FSGHandPoseImpl& OutHandPose)
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = FHandLayerType::GetHandPose(bRightHanded, HandPose);
OutHandPose = FSGHandPoseImpl{HandPose};
return bResult;
}
void FSGHandLayerImpl::GetWristLocation(
const bool bRightHanded, const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
FVector& OutWristPosition,
FQuat& OutWristRotation)
{
FSGVect3DImpl::FVect3DType WristPosition;
FSGQuatImpl::FQuatType WristRotation;
FHandLayerType::GetWristLocation(
bRightHanded,
FSGVect3DImpl{ReferencePosition}.ToVect3D(), FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware),
WristPosition, WristRotation);
OutWristPosition = FSGVect3DImpl{WristPosition}.ToFVector();
OutWristRotation = FSGQuatImpl{WristRotation}.ToFQuat();
}
bool FSGHandLayerImpl::SendHaptics(const bool bRightHanded)
{
return FHandLayerType::SendHaptics(bRightHanded);
}
void FSGHandLayerImpl::StopAllHaptics(const bool bRightHanded)
{
FHandLayerType::StopAllHaptics(bRightHanded);
}
bool FSGHandLayerImpl::QueueCommand_ForceFeedbackLevel(
const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate)
{
return FHandLayerType::QueueCommand_ForceFeedbackLevel(bRightHanded, Finger, Level01, bSendImmediate);
}
bool FSGHandLayerImpl::QueueCommand_ForceFeedbackLevels(
const bool bRightHanded, const TArray<float>& Levels01, const bool bSendImmediate)
{
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)};
return FHandLayerType::QueueCommand_ForceFeedbackLevels(bRightHanded, MoveTemp(Levels01Vector), bSendImmediate);
}
bool FSGHandLayerImpl::QueueCommand_SetVibroLevel(
const bool bRightHanded, const int32 Finger, const float Level01, const bool bSendImmediate)
{
return FHandLayerType::QueueCommand_SetVibroLevel(bRightHanded, Finger, Level01, bSendImmediate);
}
bool FSGHandLayerImpl::QueueCommand_SetVibroLevels(
const bool bRightHanded, const TArray<float>& Levels01, const bool bSendImmediate)
{
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)};
return FHandLayerType::QueueCommand_SetVibroLevels(bRightHanded, MoveTemp(Levels01Vector), bSendImmediate);
}
bool FSGHandLayerImpl::SupportsCustomWaveform(const bool bRightHanded, const ESGHapticLocation AtLocation)
{
return FHandLayerType::SupportsCustomWaveform(bRightHanded, FSGCoreEnumCast::ToEHapticLocation(AtLocation));
}
bool FSGHandLayerImpl::SendCustomWaveform(
const bool bRightHanded, FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location)
{
const bool bResult = FHandLayerType::SendCustomWaveform(
bRightHanded, OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToEHapticLocation(Location));
return bResult;
}
bool FSGHandLayerImpl::SupportsWristSqueeze(const bool bRightHanded)
{
return FHandLayerType::SupportsWristSqueeze(bRightHanded);
}
bool FSGHandLayerImpl::QueueCommand_WristSqueeze(
const bool bRightHanded, const float SqueezeLevel01, const bool bSendImmediate)
{
return FHandLayerType::QueueCommand_WristSqueeze(bRightHanded, SqueezeLevel01, bSendImmediate);
}
bool FSGHandLayerImpl::SupportsFlexionLocks(const bool bRightHanded)
{
return FHandLayerType::SupportsFlexionLocks(bRightHanded);
}
bool FSGHandLayerImpl::QueueCommand_FlexionLock(
const bool bRightHanded, const int32 Finger, const float Flexion01, const bool bSendImmediate)
{
return FHandLayerType::QueueCommand_FlexionLock(bRightHanded, Finger, Flexion01, bSendImmediate);
}
bool FSGHandLayerImpl::QueueCommand_ClearFlexionLock(
const bool bRightHanded, const int32 Finger, const bool bSendImmediate)
{
return FHandLayerType::QueueCommand_ClearFlexionLock(bRightHanded, Finger, bSendImmediate);
}
@@ -1,229 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGHandProfileImpl.h"
#include <string>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_HandProfile.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveHandProfile.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveHandProfile.h"
#include "SGCoreImpl/SGNovaGloveHandProfileImpl.h"
#include "SGCoreImpl/SGSenseGloveHandProfileImpl.h"
struct FSGHandProfileImpl::FImpl
{
/************************
* Member variables
************************/
FHandProfileType HandProfile;
/************************
* Owner object
************************/
FSGHandProfileImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGHandProfileImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGHandProfileImpl FSGHandProfileImpl::Default(const bool bRightHanded)
{
return FSGHandProfileImpl(FHandProfileType::Default(bRightHanded));
}
FSGHandProfileImpl FSGHandProfileImpl::Deserialize(const FString& SerializedString)
{
std::string Serialized(TCHAR_TO_UTF8(*SerializedString));
const FSGHandProfileImpl HandProfile(FHandProfileType::Deserialize(MoveTemp(Serialized)));
return HandProfile;
}
const FString& FSGHandProfileImpl::GetProfileDirectory()
{
static const FString Directory(UTF8_TO_TCHAR(FHandProfileType::GetProfileDirectory().c_str()));
return Directory;
}
const FString& FSGHandProfileImpl::GetLeftHandFileName()
{
static const FString FileName(UTF8_TO_TCHAR(FHandProfileType::GetLeftHandFileName().c_str()));
return FileName;
}
const FString& FSGHandProfileImpl::GetRightHandFileName()
{
static const FString FileName(UTF8_TO_TCHAR(FHandProfileType::GetRightHandFileName().c_str()));
return FileName;
}
const FString& FSGHandProfileImpl::GetProfileFileName(const bool bRightHanded)
{
static const FString FileName(UTF8_TO_TCHAR(FHandProfileType::GetProfileFileName(bRightHanded).c_str()));
return FileName;
}
bool FSGHandProfileImpl::GetLatestProfile(const bool bRightHanded, FSGHandProfileImpl& OutLatestProfile)
{
FHandProfileType LatestProfile;
const bool bResult = FHandProfileType::GetLatestProfile(bRightHanded, LatestProfile);
OutLatestProfile = FSGHandProfileImpl(OutLatestProfile);
return bResult;
}
bool FSGHandProfileImpl::StoreProfile(const FSGHandProfileImpl& ProfileToStore)
{
return FHandProfileType::StoreProfile(ProfileToStore.ToHandProfile());
}
bool FSGHandProfileImpl::ResetCalibration(const bool bRightHanded, const bool bOnDisk)
{
return FHandProfileType::ResetCalibration(bRightHanded, bOnDisk);
}
void FSGHandProfileImpl::ResetCalibration(const bool bOnDisk)
{
/// NOTE
/// Due to overload method with a default parameter value, the compiler will get confused and stops with the error:
/// "call to 'ResetCalibration' is ambiguous"
/// So:
void (*RC)(bool) = &FHandProfileType::ResetCalibration;
RC(bOnDisk);
}
FSGHandProfileImpl::FSGHandProfileImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHandProfileImpl::FSGHandProfileImpl(const bool bRightHanded,
const FSGSenseGloveHandProfileImpl& SenseGloveHandProfile,
const FSGNovaGloveHandProfileImpl& NovaGloveHandProfile)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HandProfile = FHandProfileType(
bRightHanded, SenseGloveHandProfile.ToSenseGloveHandProfile(), NovaGloveHandProfile.ToNovaGloveHandProfile());
}
FSGHandProfileImpl::FSGHandProfileImpl(const FHandProfileType& SenseGloveHandProfile)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HandProfile = SenseGloveHandProfile;
}
FSGHandProfileImpl::FSGHandProfileImpl(const FSGHandProfileImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGHandProfileImpl::FSGHandProfileImpl(FSGHandProfileImpl&& Rhs) SG_NOEXCEPT = default;
FSGHandProfileImpl::~FSGHandProfileImpl() = default;
FSGHandProfileImpl& FSGHandProfileImpl::operator=(const FSGHandProfileImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGHandProfileImpl& FSGHandProfileImpl::operator=(FSGHandProfileImpl&& Rhs) SG_NOEXCEPT = default;
const FSGHandProfileImpl::FHandProfileType& FSGHandProfileImpl::ToHandProfile(
) const
{
return Pimpl->HandProfile;
}
bool FSGHandProfileImpl::IsRight() const
{
return Pimpl->HandProfile.IsRight();
}
FSGSenseGloveHandProfileImpl FSGHandProfileImpl::GetSenseGloveHandProfile() const
{
return FSGSenseGloveHandProfileImpl(Pimpl->HandProfile.GetSenseGloveHandProfile());
}
FSGNovaGloveHandProfileImpl FSGHandProfileImpl::GetNovaGloveHandProfile() const
{
return FSGNovaGloveHandProfileImpl(Pimpl->HandProfile.GetNovaGloveHandProfile());
}
bool FSGHandProfileImpl::Equals(const FSGHandProfileImpl& HandProfileImpl) const
{
return Pimpl->HandProfile.Equals(HandProfileImpl.ToHandProfile());
}
void FSGHandProfileImpl::Reset()
{
Pimpl->HandProfile.Reset();
}
FString FSGHandProfileImpl::Serialize() const
{
const FString Serialized(UTF8_TO_TCHAR(Pimpl->HandProfile.Serialize().c_str()));
return Serialized;
}
FSGHandProfileImpl::FImpl::FImpl(FSGHandProfileImpl* InOwner)
: Owner(InOwner)
{
}
FSGHandProfileImpl::FImpl::~FImpl() = default;
void FSGHandProfileImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,206 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 SenseChannelInfo
*
* 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/SGHapticChannelInfoImpl.h"
#include "Containers/StringConv.h"
#include "SGBuildHacks/SGInclude_Core_HapticChannelInfo.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGHapticChannelInfoImpl::FImpl
{
/************************
* Member variables
************************/
FHapticChannelInfoType HapticChannelInfo;
/************************
* Owner object
************************/
FSGHapticChannelInfoImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGHapticChannelInfoImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FString FSGHapticChannelInfoImpl::GenerateAddress(const int32 DeviceIndex, const int32 ChannelIndex)
{
FString Address{UTF8_TO_TCHAR(FHapticChannelInfoType::GenerateAddress(DeviceIndex, ChannelIndex).c_str())};
return MoveTemp(Address);
}
FSGHapticChannelInfoImpl FSGHapticChannelInfoImpl::Parse(const FString& IpcString)
{
std::string IpcStdString{TCHAR_TO_UTF8(*IpcString)};
FHapticChannelInfoType HapticChannelInfo{FHapticChannelInfoType::Parse(MoveTemp(IpcStdString))};
FSGHapticChannelInfoImpl HapticChannelInfoImpl{MoveTemp(HapticChannelInfo)};
return MoveTemp(HapticChannelInfoImpl);
}
int32 FSGHapticChannelInfoImpl::GetStreamingType()
{
return FHapticChannelInfoType::GetStreamingType();
}
int32 FSGHapticChannelInfoImpl::GetFireAndForgetType()
{
return FHapticChannelInfoType::GetFireAndForgetType();
}
FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(
const TArray<int32>& StreamIndex, const TArray<int32>& FireAndForgetIndex)
{
std::vector<int32> StreamIndexVector{
FSGArrayUtils::ToStdVector(StreamIndex)
};
std::vector<int32> FireAndForgetIndexVector{
FSGArrayUtils::ToStdVector<int32>(FireAndForgetIndex)
};
Pimpl->HapticChannelInfo = FHapticChannelInfoType{
MoveTemp(StreamIndexVector),
MoveTemp(FireAndForgetIndexVector)
};
}
FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(const FHapticChannelInfoType& HapticChannelInfo)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticChannelInfo = HapticChannelInfo;
}
FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGHapticChannelInfoImpl::FSGHapticChannelInfoImpl(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT = default;
FSGHapticChannelInfoImpl::~FSGHapticChannelInfoImpl() = default;
FSGHapticChannelInfoImpl& FSGHapticChannelInfoImpl::operator=(const FSGHapticChannelInfoImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGHapticChannelInfoImpl& FSGHapticChannelInfoImpl::operator=(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT = default;
const FSGHapticChannelInfoImpl::FHapticChannelInfoType& FSGHapticChannelInfoImpl::ToHapticChannelInfo() const
{
return Pimpl->HapticChannelInfo;
}
int32 FSGHapticChannelInfoImpl::GetStreamChannelCount() const
{
return Pimpl->HapticChannelInfo.GetStreamChannelCount();
}
int32 FSGHapticChannelInfoImpl::GetFireAndForgetChannelCount() const
{
return Pimpl->HapticChannelInfo.GetFireAndForgetChannelCount();
}
int32 FSGHapticChannelInfoImpl::GetTotalChannelCount() const
{
return Pimpl->HapticChannelInfo.GetTotalChannelCount();
}
FString FSGHapticChannelInfoImpl::GetAddress_Unguarded(const ESGHapticChannelType Type, const int32 TypeIndex) const
{
FString Address{
UTF8_TO_TCHAR(
Pimpl->HapticChannelInfo.GetAddress_Unguarded(
FSGCoreEnumCast::ToEHapticChannelType(Type), TypeIndex).c_str(
))
};
return MoveTemp(Address);
}
void FSGHapticChannelInfoImpl::GetIpcParams_Unguarded(
const ESGHapticChannelType Type, const int32 TypeIndex, int32& OutIndex, FString& OutAddressString) const
{
std::string OutAddressStdString;
Pimpl->HapticChannelInfo.GetIpcParams_Unguarded(
FSGCoreEnumCast::ToEHapticChannelType(Type), TypeIndex, OutIndex, OutAddressStdString);
OutAddressString = FString{UTF8_TO_TCHAR(OutAddressStdString.c_str())};
}
void FSGHapticChannelInfoImpl::RegenerateAddresses(const int32 ForDeviceIndex)
{
Pimpl->HapticChannelInfo.RegenerateAddresses(ForDeviceIndex);
}
TArray<FString> FSGHapticChannelInfoImpl::GetAllAddresses() const
{
TArray<FString> AddressesArray{
FSGArrayUtils::FromStdVector(Pimpl->HapticChannelInfo.GetAllAddresses())
};
return MoveTemp(AddressesArray);
}
FSGHapticChannelInfoImpl::FImpl::FImpl(FSGHapticChannelInfoImpl* InOwner)
: Owner(InOwner)
{
}
FSGHapticChannelInfoImpl::FImpl::~FImpl() = default;
void FSGHapticChannelInfoImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -1,243 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/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<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()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(const FSGSensorRangeImpl& LastCalibrationRange)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCalibrationCheck = FHapticGloveCalibrationCheckType(LastCalibrationRange.ToSensorRange());
}
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(
const FHapticGloveCalibrationCheckType& HapticGloveCalibrationCheck)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCalibrationCheck = HapticGloveCalibrationCheck;
}
FSGHapticGloveCalibrationCheckImpl::FSGHapticGloveCalibrationCheckImpl(
const FSGHapticGloveCalibrationCheckImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(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<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;
}
@@ -1,353 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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 <string>
#include <vector>
#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<FHapticGloveCalibrationSequenceType> MakeNewHapticGloveCalibrationSequence(
TSharedPtr<FHapticGloveCalibrationSequenceType> Ptr);
/************************
* Member variables
************************/
TSharedPtr<FHapticGloveCalibrationSequenceType> 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<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl(
const TSharedRef<FSGHapticGloveImpl> LinkedGlove)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCalibrationSequence = MakeShared<FHapticGloveCalibrationSequenceType>(
LinkedGlove->ToHapticGlovePtrChecked());
}
FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl(
const FHapticGloveCalibrationSequenceType& HapticGloveCalibrationSequence)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCalibrationSequence = MakeShared<FHapticGloveCalibrationSequenceType>(
HapticGloveCalibrationSequence);
}
FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl(
TSharedRef<FHapticGloveCalibrationSequenceType> HapticGloveCalibrationSequence)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCalibrationSequence =
Pimpl->MakeNewHapticGloveCalibrationSequence(HapticGloveCalibrationSequence);
}
FSGHapticGloveCalibrationSequenceImpl::FSGHapticGloveCalibrationSequenceImpl(
const FSGHapticGloveCalibrationSequenceImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(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::FHapticGloveCalibrationSequenceType>
FSGHapticGloveCalibrationSequenceImpl::ToHapticGloveCalibrationSequenceRef() const
{
return Pimpl->HapticGloveCalibrationSequence.ToSharedRef();
}
TSharedRef<FSGHapticGloveCalibrationSequenceImpl> FSGHapticGloveCalibrationSequenceImpl::
ToHapticGloveCalibrationSequenceImplRef()
{
return SharedThis(this);
}
TSharedRef<FSGHapticGloveQuickCalibrationImpl> FSGHapticGloveCalibrationSequenceImpl::
ToHapticGloveQuickCalibrationImplRef()
{
FSGHapticGloveQuickCalibrationImpl* HapticGloveQuickCalibration{
dynamic_cast<FSGHapticGloveQuickCalibrationImpl*>(this)};
ensureAlwaysMsgf(HapticGloveQuickCalibration, TEXT("Invalid HapticGloveQuickCalibration!"));
return SharedThis(HapticGloveQuickCalibration);
}
TSharedRef<FSGHapticGloveImpl> FSGHapticGloveCalibrationSequenceImpl::GetLinkedGlove() const
{
FSGHapticGloveImpl::FHapticGlovePtrType Glove{Pimpl->HapticGloveCalibrationSequence->GetLinkedGlove()};
return MakeShared<FSGHapticGloveImpl>(MoveTemp(Glove));
}
void FSGHapticGloveCalibrationSequenceImpl::SetLinkedGlove(const TSharedRef<FSGHapticGloveImpl> LinkedGlove)
{
Pimpl->HapticGloveCalibrationSequence->SetLinkedGlove(LinkedGlove->ToHapticGlovePtrChecked());
}
TArray<FSGCalibrationDataPointImpl> FSGHapticGloveCalibrationSequenceImpl::GetCalibrationPoints() const
{
const TArray<FSGCalibrationDataPointImpl> CalibrationPoints{
FSGArrayUtils::FromStdVector<FSGCalibrationDataPointImpl::FCalibrationDataPointType,
FSGCalibrationDataPointImpl>(
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<FVector>& CalibrationData)
{
std::vector<FSGVect3DImpl::FVect3DType> CalibrationDataVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
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::FHapticGloveCalibrationSequenceType>
FSGHapticGloveCalibrationSequenceImpl::FImpl::MakeNewHapticGloveCalibrationSequence(
const TSharedPtr<FHapticGloveCalibrationSequenceType> Ptr)
{
{
FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType* HapticGloveQuickCalibration{
dynamic_cast<FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType*>(
Ptr.Get())
};
if (HapticGloveQuickCalibration)
{
return MakeShared<FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType>(
*HapticGloveQuickCalibration);
}
}
return MakeShared<FHapticGloveCalibrationSequenceType>(*Ptr);
}
FSGHapticGloveCalibrationSequenceImpl::FImpl::FImpl(FSGHapticGloveCalibrationSequenceImpl* InOwner)
: HapticGloveCalibrationSequence(MakeShared<FHapticGloveCalibrationSequenceType>()),
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;
}
@@ -1,284 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGHapticGloveCommandBufferImpl.h"
#include <vector>
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGBuildHacks/SGInclude_Core_HapticGloveCommandBuffer.h"
#include "SGBuildHacks/SGInclude_Core_ThumperCommand.h"
#include "SGBuildHacks/SGInclude_Core_TimedBuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_TimedThumpCommand.h"
#include "SGCoreImpl/SGBuzzCommandImpl.h"
#include "SGCoreImpl/SGForceFeedbackCommandImpl.h"
#include "SGCoreImpl/SGThumperCommandImpl.h"
#include "SGCoreImpl/SGTimedBuzzCommandImpl.h"
#include "SGCoreImpl/SGTimedThumpCommandImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGHapticGloveCommandBufferImpl::FImpl
{
/************************
* Member variables
************************/
FHapticGloveCommandBufferType HapticGloveCommandBuffer;
/************************
* Owner object
************************/
FSGHapticGloveCommandBufferImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGHapticGloveCommandBufferImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
int32 FSGHapticGloveCommandBufferImpl::GetMaxForceFeedbackCommands()
{
return FHapticGloveCommandBufferType::GetMaxForceFeedbackCommands();
}
int32 FSGHapticGloveCommandBufferImpl::GetMaxBuzzCommands()
{
return FHapticGloveCommandBufferType::GetMaxBuzzCommands();
}
int32 FSGHapticGloveCommandBufferImpl::GetMaxThumpCommands()
{
return FHapticGloveCommandBufferType::GetMaxThumpCommands();
}
FSGHapticGloveCommandBufferImpl::FSGHapticGloveCommandBufferImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveCommandBufferImpl::FSGHapticGloveCommandBufferImpl(
const FHapticGloveCommandBufferType& HapticGloveCommandBuffer)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->HapticGloveCommandBuffer = HapticGloveCommandBuffer;
}
FSGHapticGloveCommandBufferImpl::FSGHapticGloveCommandBufferImpl(
const FSGHapticGloveCommandBufferImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGHapticGloveCommandBufferImpl::FSGHapticGloveCommandBufferImpl(
FSGHapticGloveCommandBufferImpl&& Rhs) SG_NOEXCEPT = default;
FSGHapticGloveCommandBufferImpl::~FSGHapticGloveCommandBufferImpl() = default;
FSGHapticGloveCommandBufferImpl& FSGHapticGloveCommandBufferImpl::operator=(
const FSGHapticGloveCommandBufferImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGHapticGloveCommandBufferImpl& FSGHapticGloveCommandBufferImpl::operator=(
FSGHapticGloveCommandBufferImpl&& Rhs) SG_NOEXCEPT = default;
const FSGHapticGloveCommandBufferImpl::FHapticGloveCommandBufferType&
FSGHapticGloveCommandBufferImpl::ToHapticGloveCommandBuffer() const
{
return Pimpl->HapticGloveCommandBuffer;
}
TArray<FSGForceFeedbackCommandImpl> FSGHapticGloveCommandBufferImpl::GetForceFeedbackCommandsQueue() const
{
TArray<FSGForceFeedbackCommandImpl> ForceFeedbackCommandQueue{
FSGArrayUtils::FromStdVector<FSGForceFeedbackCommandImpl::FForceFeedbackCommandType,
FSGForceFeedbackCommandImpl>(
Pimpl->HapticGloveCommandBuffer.GetForceFeedbackCommandsQueue())
};
return MoveTemp(ForceFeedbackCommandQueue);
}
TArray<FSGTimedBuzzCommandImpl> FSGHapticGloveCommandBufferImpl::GetBuzzCommandsQueue() const
{
TArray<FSGTimedBuzzCommandImpl> TimedBuzzCommandQueue{
FSGArrayUtils::FromStdVector<FSGTimedBuzzCommandImpl::FTimedBuzzCommandType, FSGTimedBuzzCommandImpl>(
Pimpl->HapticGloveCommandBuffer.GetBuzzCommandsQueue())
};
return MoveTemp(TimedBuzzCommandQueue);
}
TArray<FSGTimedThumpCommandImpl> FSGHapticGloveCommandBufferImpl::GetThumperCommandsQueue() const
{
TArray<FSGTimedThumpCommandImpl> ThumperCommandQueue{
FSGArrayUtils::FromStdVector<FSGTimedThumpCommandImpl::FTimedThumpCommandType, FSGTimedThumpCommandImpl>(
Pimpl->HapticGloveCommandBuffer.GetThumperCommandsQueue())
};
return MoveTemp(ThumperCommandQueue);
}
void FSGHapticGloveCommandBufferImpl::ClearForceFeedbackCommandsQueue()
{
Pimpl->HapticGloveCommandBuffer.ClearForceFeedbackCommandsQueue();
}
void FSGHapticGloveCommandBufferImpl::ClearVibrations()
{
Pimpl->HapticGloveCommandBuffer.ClearVibrations();
}
void FSGHapticGloveCommandBufferImpl::Clear()
{
Pimpl->HapticGloveCommandBuffer.Clear();
}
void FSGHapticGloveCommandBufferImpl::AddCommand(const FSGForceFeedbackCommandImpl& ForceFeedbackCommandImpl)
{
Pimpl->HapticGloveCommandBuffer.AddCommand(ForceFeedbackCommandImpl.ToForceFeedbackCommand());
}
void FSGHapticGloveCommandBufferImpl::AddCommand(const FSGTimedBuzzCommandImpl& BuzzCommandImpl)
{
Pimpl->HapticGloveCommandBuffer.AddCommand(BuzzCommandImpl.ToTimedBuzzCommand());
}
void FSGHapticGloveCommandBufferImpl::AddCommand(const FSGTimedThumpCommandImpl& ThumpCommand)
{
Pimpl->HapticGloveCommandBuffer.AddCommand(ThumpCommand.ToTimedThumpCommand());
}
void FSGHapticGloveCommandBufferImpl::UpdateTimedCommands(const float DeltaSeconds)
{
Pimpl->HapticGloveCommandBuffer.UpdateTimedCommands(DeltaSeconds);
}
FSGForceFeedbackCommandImpl FSGHapticGloveCommandBufferImpl::GetTotalForceFeedbackLevels(
const FSGForceFeedbackCommandImpl& LastForceFeedbackCommand) const
{
FSGForceFeedbackCommandImpl TotalForceFeedbackLevels{
Pimpl->HapticGloveCommandBuffer.GetTotalForceFeedbackLevels(
LastForceFeedbackCommand.ToForceFeedbackCommand())};
return MoveTemp(TotalForceFeedbackLevels);
}
FSGForceFeedbackCommandImpl FSGHapticGloveCommandBufferImpl::GetTotalForceFeedbackLevels() const
{
FSGForceFeedbackCommandImpl TotalForceFeedbackLevels{
Pimpl->HapticGloveCommandBuffer.GetTotalForceFeedbackLevels()};
return MoveTemp(TotalForceFeedbackLevels);
}
FSGBuzzCommandImpl FSGHapticGloveCommandBufferImpl::GetTotalBuzzLevels() const
{
FSGBuzzCommandImpl TotalBuzzLevels{Pimpl->HapticGloveCommandBuffer.GetTotalBuzzLevels()};
return MoveTemp(TotalBuzzLevels);
}
FSGThumperCommandImpl FSGHapticGloveCommandBufferImpl::GetTotalThumperLevels() const
{
FSGThumperCommandImpl TotalThumperLevels{Pimpl->HapticGloveCommandBuffer.GetTotalThumperLevels()};
return MoveTemp(TotalThumperLevels);
}
void FSGHapticGloveCommandBufferImpl::FlushHaptics(const FSGForceFeedbackCommandImpl& LastBrakeLevel,
FSGForceFeedbackCommandImpl& OutForceFeedbackCommand,
FSGBuzzCommandImpl& OutBuzzCommand,
FSGThumperCommandImpl& OutThumperCommand,
const bool bClearForceFeedbackQueue)
{
FSGForceFeedbackCommandImpl::FForceFeedbackCommandType ForceFeedbackCommand;
FSGBuzzCommandImpl::FBuzzCommandType BuzzCommand;
FSGThumperCommandImpl::FThumperCommandType ThumperCommand;
Pimpl->HapticGloveCommandBuffer.FlushHaptics(LastBrakeLevel.ToForceFeedbackCommand(),
ForceFeedbackCommand,
BuzzCommand,
ThumperCommand,
bClearForceFeedbackQueue);
OutForceFeedbackCommand = FSGForceFeedbackCommandImpl{ForceFeedbackCommand};
OutBuzzCommand = FSGBuzzCommandImpl{BuzzCommand};
OutThumperCommand = FSGThumperCommandImpl{ThumperCommand};
}
void FSGHapticGloveCommandBufferImpl::FlushHaptics(const float DeltaSeconds,
const FSGForceFeedbackCommandImpl& LastBrakeLevel,
FSGForceFeedbackCommandImpl& OutForceFeedbackCommand,
FSGBuzzCommandImpl& OutBuzzCommand,
FSGThumperCommandImpl& OutThumperCommand)
{
FSGForceFeedbackCommandImpl::FForceFeedbackCommandType ForceFeedbackCommand;
FSGBuzzCommandImpl::FBuzzCommandType BuzzCommand;
FSGThumperCommandImpl::FThumperCommandType ThumperCommand;
Pimpl->HapticGloveCommandBuffer.FlushHaptics(DeltaSeconds,
LastBrakeLevel.ToForceFeedbackCommand(),
ForceFeedbackCommand,
BuzzCommand,
ThumperCommand);
OutForceFeedbackCommand = FSGForceFeedbackCommandImpl{ForceFeedbackCommand};
OutBuzzCommand = FSGBuzzCommandImpl{BuzzCommand};
OutThumperCommand = FSGThumperCommandImpl{ThumperCommand};
}
FSGHapticGloveCommandBufferImpl::FImpl::FImpl(FSGHapticGloveCommandBufferImpl* InOwner)
: HapticGloveCommandBuffer(),
Owner(InOwner)
{
}
FSGHapticGloveCommandBufferImpl::FImpl::~FImpl() = default;
void FSGHapticGloveCommandBufferImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -1,130 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGHapticGloveHandProfilesImpl.h"
#include "Containers/StringConv.h"
#include "SGBuildHacks/SGInclude_Core_HandProfile.h"
#include "SGBuildHacks/SGInclude_Core_HapticGloveHandProfiles.h"
#include "SGBuildHacks/SGInclude_Core_SensorRange.h"
#include "SGCoreImpl/SGHandProfileImpl.h"
#include "SGCoreImpl/SGHapticGloveImpl.h"
#include "SGCoreImpl/SGSenseGloveImpl.h"
#include "SGCoreImpl/SGSensorRangeImpl.h"
const FString& FSGHapticGloveHandProfilesImpl::GetProfileDirectory()
{
static const FString Directory(UTF8_TO_TCHAR(FHapticGloveHandProfilesType::GetProfileDirectory().c_str()));
return Directory;
}
void FSGHapticGloveHandProfilesImpl::SetProfileDirectory(const FString& Directory)
{
std::string DirectoryString(TCHAR_TO_UTF8(*Directory));
FHapticGloveHandProfilesType::SetProfileDirectory(MoveTemp(DirectoryString));
}
void FSGHapticGloveHandProfilesImpl::GetLeftHandProfile(FSGHandProfileImpl& OutHandProfileImpl)
{
FSGHandProfileImpl::FHandProfileType HandProfile;
FHapticGloveHandProfilesType::GetRightHandProfile(HandProfile);
OutHandProfileImpl = FSGHandProfileImpl(MoveTemp(HandProfile));
}
void FSGHapticGloveHandProfilesImpl::SetLeftHandProfile(const FSGHandProfileImpl& HandProfileImpl)
{
FHapticGloveHandProfilesType::SetLeftHandProfile(HandProfileImpl.ToHandProfile());
}
void FSGHapticGloveHandProfilesImpl::GetRightHandProfile(FSGHandProfileImpl& OutHandProfileImpl)
{
FSGHandProfileImpl::FHandProfileType HandProfile;
FHapticGloveHandProfilesType::GetRightHandProfile(HandProfile);
OutHandProfileImpl = FSGHandProfileImpl(MoveTemp(HandProfile));
}
void FSGHapticGloveHandProfilesImpl::SetRightHandProfile(const FSGHandProfileImpl& HandProfileImpl)
{
FHapticGloveHandProfilesType::SetRightHandProfile(HandProfileImpl.ToHandProfile());
}
void FSGHapticGloveHandProfilesImpl::GetProfile(const bool bRightHanded, FSGHandProfileImpl& OutHandProfileImpl)
{
FSGHandProfileImpl::FHandProfileType HandProfile;
FHapticGloveHandProfilesType::GetProfile(bRightHanded, HandProfile);
OutHandProfileImpl = FSGHandProfileImpl(MoveTemp(HandProfile));
}
void FSGHapticGloveHandProfilesImpl::SetProfile(const FSGHandProfileImpl& HandProfileImpl)
{
FHapticGloveHandProfilesType::SetProfile(HandProfileImpl.ToHandProfile());
}
void FSGHapticGloveHandProfilesImpl::SetProfile(const FSGHandProfileImpl& HandProfileImpl, const bool bRightHanded)
{
FHapticGloveHandProfilesType::SetProfile(HandProfileImpl.ToHandProfile(), bRightHanded);
}
void FSGHapticGloveHandProfilesImpl::RestoreDefaults()
{
FHapticGloveHandProfilesType::RestoreDefaults();
}
void FSGHapticGloveHandProfilesImpl::RestoreDefaults(const bool bRightHanded)
{
FHapticGloveHandProfilesType::RestoreDefaults(bRightHanded);
}
void FSGHapticGloveHandProfilesImpl::TryLoadingFromDisk()
{
FHapticGloveHandProfilesType::TryLoadingFromDisk();
}
bool FSGHapticGloveHandProfilesImpl::SaveLastRange(const FSGSensorRangeImpl& CurrentRange,
const TSharedRef<FSGHapticGloveImpl> ForGlove)
{
return FHapticGloveHandProfilesType::SaveLastRange(CurrentRange.ToSensorRange(),
ForGlove->ToHapticGlovePtrChecked());
}
bool FSGHapticGloveHandProfilesImpl::LoadLastRange(const TSharedRef<FSGHapticGloveImpl> ForGlove,
FSGSensorRangeImpl& OutLastRange)
{
FSGSensorRangeImpl::FSensorRangeType LastRange;
const bool bResult = FHapticGloveHandProfilesType::LoadLastRange(ForGlove->ToHapticGlovePtrChecked(), LastRange);
OutLastRange = FSGSensorRangeImpl{LastRange};
return bResult;
}
@@ -42,22 +42,16 @@
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_HandProfile.h"
#include "SGBuildHacks/SGInclude_Core_HapticGlove.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_ThumperCommand.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGBasicHandModelImpl.h"
#include "SGCoreImpl/SGBuzzCommandImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGForceFeedbackCommandImpl.h"
#include "SGCoreImpl/SGCustomWaveformImpl.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGHandProfileImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGThumperCommandImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
@@ -84,9 +78,9 @@ struct FSGHapticGloveImpl::FImpl
FImpl& operator=(const FImpl& Rhs) = default;
};
TArray<TSharedRef<FSGHapticGloveImpl>> FSGHapticGloveImpl::GetHapticGloves()
TArray<TSharedRef<FSGHapticGloveImpl>> FSGHapticGloveImpl::GetHapticGloves(const bool bConnectedOnly)
{
const FHapticGlovePtrVectorType HapticGloves{FHapticGloveType::GetHapticGloves()};
const FHapticGlovePtrVectorType HapticGloves{FHapticGloveType::GetHapticGloves(bConnectedOnly)};
TArray<TSharedRef<FSGHapticGloveImpl>> HapticGloveImpls;
for (FHapticGlovePtrType HapticGlove: HapticGloves)
@@ -124,6 +118,22 @@ bool FSGHapticGloveImpl::GetGlove(const bool bRightHanded, TSharedPtr<FSGHapticG
return bReturn;
}
FString FSGHapticGloveImpl::ToString(ESGHapticGloveCalibrationState State)
{
FString String{
UTF8_TO_TCHAR(FHapticGloveType::ToString(FSGCoreEnumCast::ToEHapticGloveCalibrationState(State)).c_str())
};
return MoveTemp(String);
}
FString FSGHapticGloveImpl::ToString(ESGHapticLocation Location)
{
FString String{
UTF8_TO_TCHAR(FHapticGloveType::ToString(FSGCoreEnumCast::ToEHapticLocation(Location)).c_str())
};
return MoveTemp(String);
}
FSGHapticGloveImpl::FSGHapticGloveImpl()
: FSGDeviceImpl(),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
@@ -176,14 +186,14 @@ ESGDeviceType FSGHapticGloveImpl::GetDeviceType() const
FString FSGHapticGloveImpl::GetDeviceId() const
{
const FString Id{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetDeviceId().c_str())};
return Id;
FString Id{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetDeviceId().c_str())};
return MoveTemp(Id);
}
FString FSGHapticGloveImpl::GetHardwareVersion() const
{
const FString Version{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetHardwareVersion().c_str())};
return Version;
FString Version{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetHardwareVersion().c_str())};
return MoveTemp(Version);
}
int32 FSGHapticGloveImpl::GetFirmwareVersion() const
@@ -209,25 +219,7 @@ bool FSGHapticGloveImpl::GetImuRotation(FQuat& OutImu)
return bResult;
}
bool FSGHapticGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose)
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(),
HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
}
bool FSGHapticGloveImpl::GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose)
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
}
bool FSGHapticGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose)
bool FSGHapticGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose);
@@ -243,15 +235,48 @@ bool FSGHapticGloveImpl::GetHandPose(FSGHandPoseImpl& OutHandPose)
return bResult;
}
#if PLATFORM_ANDROID
bool FSGHapticGloveImpl::GetHandPose(const float DeltaTime, FSGHandPoseImpl& OutHandPose)
bool FSGHapticGloveImpl::GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToHapticGlovePtrChecked()->GetHandPose(DeltaTime, HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> HandAngles;
const bool bResult = ToHapticGlovePtrChecked()->GetHandAngles(HandAngles);
OutHandAngles = FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(HandAngles);
return bResult;
}
#endif /* PLATFORM_ANDROID */
FSGBasicHandModelImpl FSGHapticGloveImpl::GetHandGeometry() const
{
FSGBasicHandModelImpl::FBasicHandModelType Geometry{ToHapticGlovePtrChecked()->GetHandGeometry()};
return FSGBasicHandModelImpl{MoveTemp(Geometry)};
}
void FSGHapticGloveImpl::SetHandGeometry(const FSGBasicHandModelImpl& HandGeometry)
{
ToHapticGlovePtrChecked()->SetHandGeometry(HandGeometry.ToBasicHandModel());
}
ESGHapticGloveCalibrationState FSGHapticGloveImpl::GetCalibrationState() const
{
return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToHapticGlovePtrChecked()->GetCalibrationState());
}
void FSGHapticGloveImpl::EndCalibration()
{
ToHapticGlovePtrChecked()->EndCalibration();
}
void FSGHapticGloveImpl::ResetCalibration()
{
ToHapticGlovePtrChecked()->ResetCalibration();
}
FString FSGHapticGloveImpl::GetCalibrationInstruction() const
{
FString Instruction{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->GetCalibrationInstruction().c_str())};
return MoveTemp(Instruction);
}
void FSGHapticGloveImpl::StopHaptics()
{
@@ -263,89 +288,31 @@ void FSGHapticGloveImpl::StopVibrations()
ToHapticGlovePtrChecked()->StopVibrations();
}
void FSGHapticGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand)
bool FSGHapticGloveImpl::SendHaptics()
{
ToHapticGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand());
return ToHapticGlovePtrChecked()->SendHaptics();
}
void FSGHapticGloveImpl::SendHaptics(const FSGBuzzCommandImpl& BuzzCommand)
bool FSGHapticGloveImpl::QueueForceFeedbackLevels(const TArray<float>& Levels01)
{
ToHapticGlovePtrChecked()->SendHaptics(BuzzCommand.ToBuzzCommand());
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector<float>(Levels01)};
return ToHapticGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector));
}
void FSGHapticGloveImpl::SendHaptics(const FSGThumperCommandImpl& ThumperCommand)
bool FSGHapticGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01)
{
ToHapticGlovePtrChecked()->SendHaptics(ThumperCommand.ToThumperCommand());
return ToHapticGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01);
}
void FSGHapticGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand)
bool FSGHapticGloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const
{
ToHapticGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand(),
BuzzCommand.ToBuzzCommand());
return ToHapticGlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation));
}
void FSGHapticGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand, const FSGThumperCommandImpl& ThumperCommand)
bool FSGHapticGloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location)
{
ToHapticGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand(),
BuzzCommand.ToBuzzCommand(),
ThumperCommand.ToThumperCommand());
}
bool FSGHapticGloveImpl::GetCalibrationValues(TArray<FVector>& OutValues)
{
std::vector<FSGVect3DImpl::FVect3DType> Values;
const bool bResult = ToHapticGlovePtrChecked()->GetCalibrationValues(Values);
OutValues = FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector,
FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(Values));
return bResult;
}
void FSGHapticGloveImpl::ResetCalibrationRange()
{
ToHapticGlovePtrChecked()->ResetCalibrationRange();
}
void FSGHapticGloveImpl::UpdateCalibrationRange()
{
ToHapticGlovePtrChecked()->UpdateCalibrationRange();
}
void FSGHapticGloveImpl::UpdateCalibrationRange(const TArray<FVector>& CalibrationValues)
{
std::vector<FSGVect3DImpl::FVect3DType> CalibrationValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
CalibrationValues)
};
ToHapticGlovePtrChecked()->UpdateCalibrationRange(MoveTemp(CalibrationValuesVector));
}
void FSGHapticGloveImpl::GetCalibrationRange(TArray<FVector>& OutMinValues, TArray<FVector>& OutMaxValues)
{
std::vector<FSGVect3DImpl::FVect3DType> MinValues;
std::vector<FSGVect3DImpl::FVect3DType> MaxValues;
ToHapticGlovePtrChecked()->GetCalibrationRange(MinValues, MaxValues);
OutMinValues = FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector,
FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(MinValues));
OutMaxValues = FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector,
FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(MaxValues));
}
void FSGHapticGloveImpl::UpdateCalibration(FSGHandProfileImpl& OutProfile)
{
FSGHandProfileImpl::FHandProfileType Profile;
ToHapticGlovePtrChecked()->UpdateCalibration(Profile);
OutProfile = FSGHandProfileImpl(MoveTemp(Profile));
}
void FSGHapticGloveImpl::ApplyCalibration(FSGHandProfileImpl& OutProfile) const
{
FSGHandProfileImpl::FHandProfileType Profile;
ToHapticGlovePtrChecked()->ApplyCalibration(Profile);
OutProfile = FSGHandProfileImpl(MoveTemp(Profile));
return ToHapticGlovePtrChecked()->SendCustomWaveform(
OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToEHapticLocation(Location));
}
void FSGHapticGloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -367,8 +334,8 @@ void FSGHapticGloveImpl::GetWristLocation(const FVector& ReferencePosition, cons
}
void FSGHapticGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware, FVector& OutGlovePosition,
FQuat& OutGloveRotation) const
const ESGPositionalTrackingHardware TrackingHardware,
FVector& OutGlovePosition, FQuat& OutGloveRotation) const
{
FSGVect3DImpl::FVect3DType GlovePosition;
FSGQuatImpl::FQuatType GloveRotation;
@@ -384,6 +351,12 @@ void FSGHapticGloveImpl::GetGloveLocation(const FVector& ReferencePosition, cons
OutGloveRotation = FSGQuatImpl(MoveTemp(GloveRotation)).ToFQuat();
}
FString FSGHapticGloveImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(ToHapticGlovePtrChecked()->ToString().c_str())};
return MoveTemp(String);
}
FSGHapticGloveImpl::FImpl::FImpl(FSGHapticGloveImpl* InOwner)
: Owner(InOwner)
{
@@ -1,234 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGHapticGloveQuickCalibrationImpl.h"
#include <string>
#include <vector>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_HapticGloveQuickCalibration.h"
#include "SGBuildHacks/SGInclude_Core_SensorRange.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGHandProfileImpl.h"
#include "SGCoreImpl/SGHapticGloveImpl.h"
#include "SGCoreImpl/SGSensorRangeImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGHapticGloveQuickCalibrationImpl::FImpl
{
/************************
* Member variables
************************/
/************************
* Owner object
************************/
FSGHapticGloveQuickCalibrationImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGHapticGloveQuickCalibrationImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
float FSGHapticGloveQuickCalibrationImpl::GetDefaultAutoEndTimeout()
{
static const float AutoEndTimeout = FHapticGloveQuickCalibrationType::GetDefaultAutoEndTimeout();
return AutoEndTimeout;
}
FSGHapticGloveQuickCalibrationImpl::FSGHapticGloveQuickCalibrationImpl()
: FSGHapticGloveCalibrationSequenceImpl(),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveQuickCalibrationImpl::FSGHapticGloveQuickCalibrationImpl(
const TSharedRef<FSGHapticGloveImpl> GloveToCalibrate, const float AutoEndTimeout)
: FSGHapticGloveCalibrationSequenceImpl(
MakeShared<FHapticGloveQuickCalibrationType>(GloveToCalibrate->ToHapticGlovePtr(), AutoEndTimeout)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveQuickCalibrationImpl::FSGHapticGloveQuickCalibrationImpl(
const FHapticGloveQuickCalibrationType& HapticGloveQuickCalibration)
: FSGHapticGloveCalibrationSequenceImpl(MakeShared<FHapticGloveQuickCalibrationType>(HapticGloveQuickCalibration)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGHapticGloveQuickCalibrationImpl::FSGHapticGloveQuickCalibrationImpl(const FSGHapticGloveQuickCalibrationImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGHapticGloveQuickCalibrationImpl::FSGHapticGloveQuickCalibrationImpl(
FSGHapticGloveQuickCalibrationImpl&& Rhs) SG_NOEXCEPT = default;
FSGHapticGloveQuickCalibrationImpl::~FSGHapticGloveQuickCalibrationImpl() = default;
FSGHapticGloveQuickCalibrationImpl& FSGHapticGloveQuickCalibrationImpl::operator=(
const FSGHapticGloveQuickCalibrationImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGHapticGloveQuickCalibrationImpl& FSGHapticGloveQuickCalibrationImpl::operator=(
FSGHapticGloveQuickCalibrationImpl&& Rhs) SG_NOEXCEPT = default;
const FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType&
FSGHapticGloveQuickCalibrationImpl::ToHapticGloveQuickCalibration() const
{
return *StaticCastSharedRef<FHapticGloveQuickCalibrationType>(ToHapticGloveCalibrationSequenceRef());
}
TSharedRef<FSGHapticGloveQuickCalibrationImpl::FHapticGloveQuickCalibrationType> FSGHapticGloveQuickCalibrationImpl::
ToHapticGloveQuickCalibrationRef() const
{
return StaticCastSharedRef<FHapticGloveQuickCalibrationType>(ToHapticGloveCalibrationSequenceRef());
}
float FSGHapticGloveQuickCalibrationImpl::GetAutoEndTimeout() const
{
return ToHapticGloveQuickCalibrationRef()->GetAutoEndTimeout();
}
int32 FSGHapticGloveQuickCalibrationImpl::GetSmoothingSamples() const
{
return ToHapticGloveQuickCalibrationRef()->GetSmoothingSamples();
}
FSGSensorRangeImpl FSGHapticGloveQuickCalibrationImpl::GetSensorRange() const
{
const FSGSensorRangeImpl SensorRange{ToHapticGloveQuickCalibrationRef()->GetSensorRange()};
return SensorRange;
}
FSGHandProfileImpl FSGHapticGloveQuickCalibrationImpl::GetTemporaryProfile() const
{
const FSGHandProfileImpl TemporaryProfile{ToHapticGloveQuickCalibrationRef()->GetTemporaryProfile()};
return TemporaryProfile;
}
bool FSGHapticGloveQuickCalibrationImpl::CanAnimate() const
{
return ToHapticGloveQuickCalibrationRef()->CanAnimate();
}
bool FSGHapticGloveQuickCalibrationImpl::AutoCompleted() const
{
return ToHapticGloveQuickCalibrationRef()->AutoCompleted();
}
void FSGHapticGloveQuickCalibrationImpl::Reset()
{
ToHapticGloveQuickCalibrationRef()->Reset();
}
void FSGHapticGloveQuickCalibrationImpl::Update(const float DeltaSeconds)
{
return ToHapticGloveQuickCalibrationRef()->Update(DeltaSeconds);
}
void FSGHapticGloveQuickCalibrationImpl::AddDataPoint(const TArray<FVector>& CalibrationData)
{
std::vector<FSGVect3DImpl::FVect3DType> CalibrationDataVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
CalibrationData)
};
ToHapticGloveQuickCalibrationRef()->AddDataPoint(MoveTemp(CalibrationDataVector));
}
void FSGHapticGloveQuickCalibrationImpl::ConfirmCurrentStep()
{
ToHapticGloveQuickCalibrationRef()->ConfirmCurrentStep();
}
bool FSGHapticGloveQuickCalibrationImpl::CompileRange(FSGSensorRangeImpl& OutSensorRange) const
{
FSGSensorRangeImpl::FSensorRangeType SensorRange;
const bool bResult = ToHapticGloveQuickCalibrationRef()->CompileRange(SensorRange);
OutSensorRange = FSGSensorRangeImpl{SensorRange};
return bResult;
}
bool FSGHapticGloveQuickCalibrationImpl::GetHandPose(const bool bRightHanded, FSGHandPoseImpl& OutCurrentHandPose) const
{
FSGHandPoseImpl::FHandPoseType CurrentHandPose;
const bool bResult = ToHapticGloveQuickCalibrationRef()->GetHandPose(bRightHanded, CurrentHandPose);
OutCurrentHandPose = FSGHandPoseImpl{CurrentHandPose};
return bResult;
}
FString FSGHapticGloveQuickCalibrationImpl::GetCurrentInstruction(const FString& NextStepKey) const
{
std::string NextStepKeyString{TCHAR_TO_UTF8(*NextStepKey)};
const FString CurrentInstruction{TCHAR_TO_UTF8(ToHapticGloveQuickCalibrationRef()->GetCurrentInstruction(
MoveTemp(NextStepKeyString)).c_str())};
return CurrentInstruction;
}
FSGHapticGloveQuickCalibrationImpl::FImpl::FImpl(FSGHapticGloveQuickCalibrationImpl* InOwner)
: Owner(InOwner)
{
}
FSGHapticGloveQuickCalibrationImpl::FImpl::~FImpl() = default;
void FSGHapticGloveQuickCalibrationImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,539 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGNova2GloveImpl.h"
#include <memory>
#include <vector>
#include "Containers/StringConv.h"
#include "Misc/AssertionMacros.h"
#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h"
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_HapticGlove.h"
#include "SGBuildHacks/SGInclude_Core_Nova2Glove.h"
#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGBasicHandModelImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGCustomWaveformImpl.h"
#include "SGCoreImpl/SGHandInterpolatorImpl.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGNova2GloveSensorDataImpl.h"
#include "SGCoreImpl/SGNovaGloveInfoImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGSensorNormalizationImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGNova2GloveImpl::FImpl
{
/************************
* Owner object
************************/
FSGNova2GloveImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGNova2GloveImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
TSharedRef<FSGDeviceImpl> FSGNova2GloveImpl::Parse(const FString& ConstantsString)
{
std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)};
FSGDevicePtrType SGDevicePtr{FNova2GloveType::Parse(MoveTemp(ConstantsStdString))};
ensureAlwaysMsgf(SGDevicePtr, TEXT("Invalid SGDevice!"));
TSharedRef<FSGNova2GloveImpl> Nova2GloveImpl{MakeShared<FSGNova2GloveImpl>(
std::dynamic_pointer_cast<FNova2GloveType>(MoveTemp(SGDevicePtr)))};
return MoveTemp(Nova2GloveImpl);
}
TArray<FSGNova2GloveImpl> FSGNova2GloveImpl::GetNova2Gloves()
{
FNova2GloveVectorType Vector{FNova2GloveType::GetNova2Gloves()};
TArray<FSGNova2GloveImpl> Array{
FSGArrayUtils::FromStdVector<FNova2GloveType, FSGNova2GloveImpl>(MoveTemp(Vector))
};
return MoveTemp(Array);
}
bool FSGNova2GloveImpl::GetNova2Glove(FSGNova2GloveImpl& OutGlove)
{
FNova2GloveType Glove;
const bool bResult = FNova2GloveType::GetNova2Glove(Glove);
OutGlove = FSGNova2GloveImpl{MoveTemp(Glove)};
return bResult;
}
bool FSGNova2GloveImpl::GetNova2Glove(const bool bRightHanded, FSGNova2GloveImpl& OutGlove)
{
FNova2GloveType Glove;
const bool bResult = FNova2GloveType::GetNova2Glove(bRightHanded, Glove);
OutGlove = FSGNova2GloveImpl{MoveTemp(Glove)};
return bResult;
}
void FSGNova2GloveImpl::CalculateGloveLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion,
FVector& OutGlovePosition, FQuat& OutGloveRotation)
{
FSGVect3DImpl::FVect3DType GlovePosition;
FSGQuatImpl::FQuatType GloveRotation;
FNova2GloveType::CalculateGloveLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, TCHAR_TO_UTF8(*HardwareVersion),
GlovePosition, GloveRotation);
OutGlovePosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(GlovePosition));;
OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat();
}
void FSGNova2GloveImpl::CalculateWristLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded, const FString& HardwareVersion,
FVector& OutWristPosition, FQuat& OutWristRotation)
{
FSGVect3DImpl::FVect3DType WristPosition;
FSGQuatImpl::FQuatType WristRotation;
FNova2GloveType::CalculateWristLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded, TCHAR_TO_UTF8(*HardwareVersion),
WristPosition, WristRotation);
OutWristPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(WristPosition));
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
ANSICHAR FSGNova2GloveImpl::GetStreamByte()
{
static const ANSICHAR Byte = FNova2GloveType::GetStreamByte();
return Byte;
}
const TArray<float>& FSGNova2GloveImpl::GetNova2SensorRanges()
{
static const TArray<float> Ranges{FSGArrayUtils::FromStdVector(FNova2GloveType::GetNova2SensorRanges())};
return Ranges;
}
TArray<float> FSGNova2GloveImpl::ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData)
{
TArray<float> NormalizedValues{
FSGArrayUtils::FromStdVector(
FNova2GloveType::ToNormalizedValues(SensorData.ToNova2GloveSensorData()))
};
return MoveTemp(NormalizedValues);
}
TArray<TArray<FVector>> FSGNova2GloveImpl::CalculateHandAngles(
const TArray<float>& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator, const bool bInfluenceIndex)
{
std::vector<float> NormalizedValuesVector{FSGArrayUtils::ToStdVector(NormalizedValues)};
TArray<TArray<FVector>> Angles{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
FNova2GloveType::CalculateHandAngles(MoveTemp(NormalizedValuesVector), Interpolator.ToHandInterpolator(),
bInfluenceIndex))
};
return MoveTemp(Angles);
}
TArray<TArray<FVector>> FSGNova2GloveImpl::ToNormalizedAngles(
const TArray<float>& NormalizedData, const FSGNovaGloveInfoImpl& GloveInfo)
{
std::vector<float> NormalizedDataVector{FSGArrayUtils::ToStdVector(NormalizedData)};
TArray<TArray<FVector>> Angles{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
FNova2GloveType::ToNormalizedAngles(MoveTemp(NormalizedDataVector), GloveInfo.ToNovaGloveInfo()))
};
return MoveTemp(Angles);
}
TArray<float> FSGNova2GloveImpl::ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData,
FSGSensorNormalizationImpl& OutSensorNormalizer)
{
TArray<float> NormalizedValues{
FSGArrayUtils::FromStdVector(
FNova2GloveType::ToNormalizedValues(SensorData.ToNova2GloveSensorData(),
OutSensorNormalizer.ToSensorNormalization()))
};
return MoveTemp(NormalizedValues);
}
FSGNova2GloveImpl::FSGNova2GloveImpl()
: FSGHapticGloveImpl(),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNova2GloveImpl::FSGNova2GloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo)
: FSGHapticGloveImpl(FSGNova2GloveImpl(std::make_shared<FNova2GloveType>((DeviceInfo.ToNovaGloveInfo())))),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNova2GloveImpl::FSGNova2GloveImpl(const FNova2GloveType Nova2Glove)
: FSGHapticGloveImpl(std::make_shared<FNova2GloveType>(Nova2Glove)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNova2GloveImpl::FSGNova2GloveImpl(const FNova2GlovePtrType Nova2Glove)
: FSGHapticGloveImpl(Nova2Glove),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNova2GloveImpl::FSGNova2GloveImpl(const FSGNova2GloveImpl& Rhs)
: FSGHapticGloveImpl(Rhs),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGNova2GloveImpl::FSGNova2GloveImpl(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT = default;
FSGNova2GloveImpl::~FSGNova2GloveImpl() = default;
FSGNova2GloveImpl& FSGNova2GloveImpl::operator=(const FSGNova2GloveImpl& Rhs)
{
FSGHapticGloveImpl::operator=(Rhs);
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGNova2GloveImpl& FSGNova2GloveImpl::operator=(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT = default;
const FSGNova2GloveImpl::FNova2GloveType& FSGNova2GloveImpl::ToNova2Glove() const
{
return *ToNova2GlovePtrChecked();
}
FSGNova2GloveImpl::FNova2GlovePtrType FSGNova2GloveImpl::ToNova2GlovePtr() const
{
return std::dynamic_pointer_cast<FNova2GloveType>(ToSGDevicePtr());
}
FSGNova2GloveImpl::FNova2GlovePtrType FSGNova2GloveImpl::ToNova2GlovePtrChecked() const
{
FNova2GlovePtrType Nova2Glove = std::dynamic_pointer_cast<FNova2GloveType>(ToSGDevicePtr());
ensureAlwaysMsgf(Nova2Glove.get(), TEXT("Invalid Nova2Glove"));
return Nova2Glove;
}
ESGDeviceType FSGNova2GloveImpl::GetDeviceType() const
{
return FSGCoreEnumCast::ToESGDeviceType(ToNova2GlovePtrChecked()->GetDeviceType());
}
FString FSGNova2GloveImpl::GetDeviceId() const
{
const FString Id{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->GetDeviceId().c_str())};
return Id;
}
FString FSGNova2GloveImpl::GetHardwareVersion() const
{
const FString Version{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->GetHardwareVersion().c_str())};
return Version;
}
int32 FSGNova2GloveImpl::GetFirmwareVersion() const
{
return ToNova2GlovePtrChecked()->GetFirmwareVersion();
}
int32 FSGNova2GloveImpl::GetSubFirmwareVersion() const
{
return ToNova2GlovePtrChecked()->GetSubFirmwareVersion();
}
bool FSGNova2GloveImpl::HasBattery() const
{
return ToNova2GlovePtrChecked()->HasBattery();
}
bool FSGNova2GloveImpl::IsCharging()
{
return ToNova2GlovePtrChecked()->IsCharging();
}
bool FSGNova2GloveImpl::GetBatteryLevel(float& OutBatteryLevel)
{
return ToNova2GlovePtrChecked()->GetBatteryLevel(OutBatteryLevel);
}
bool FSGNova2GloveImpl::IsRight() const
{
return ToNova2GlovePtrChecked()->IsRight();
}
bool FSGNova2GloveImpl::GetImuRotation(FQuat& OutImu)
{
FSGQuatImpl::FQuatType Imu;
const bool bResult = ToNova2GlovePtrChecked()->GetImuRotation(Imu);
OutImu = FSGQuatImpl{MoveTemp(Imu)}.ToFQuat();
return bResult;
}
bool FSGNova2GloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToNova2GlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
}
bool FSGNova2GloveImpl::GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const
{
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> HandAngles;
const bool bResult = ToNova2GlovePtrChecked()->GetHandAngles(HandAngles);
OutHandAngles = FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(HandAngles));
return bResult;
}
ESGHapticGloveCalibrationState FSGNova2GloveImpl::GetCalibrationState() const
{
return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToNova2GlovePtrChecked()->GetCalibrationState());
}
void FSGNova2GloveImpl::EndCalibration()
{
ToNova2GlovePtrChecked()->EndCalibration();
}
void FSGNova2GloveImpl::ResetCalibration()
{
ToNova2GlovePtrChecked()->ResetCalibration();
}
void FSGNova2GloveImpl::StopHaptics()
{
ToNova2GlovePtrChecked()->StopHaptics();
}
void FSGNova2GloveImpl::StopVibrations()
{
ToNova2GlovePtrChecked()->StopVibrations();
}
bool FSGNova2GloveImpl::SendHaptics()
{
return ToNova2GlovePtrChecked()->SendHaptics();
}
bool FSGNova2GloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const
{
return ToNova2GlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation));
}
bool FSGNova2GloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGHapticLocation Location)
{
return ToNova2GlovePtrChecked()->SendCustomWaveform(OutWaveform.ToCustomWaveform(),
FSGCoreEnumCast::ToEHapticLocation(Location));
}
bool FSGNova2GloveImpl::QueueForceFeedbackLevels(const TArray<float>& Levels01)
{
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)};
return ToNova2GlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector));
}
bool FSGNova2GloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01)
{
return ToNova2GlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01);
}
bool FSGNova2GloveImpl::QueueSqueezeLevel(const float SqueezeLevel01)
{
return ToNova2GlovePtrChecked()->QueueSqueezeLevel(SqueezeLevel01);
}
void FSGNova2GloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
FVector& OutGlovePosition, FQuat& OutGloveRotation) const
{
FSGVect3DImpl::FVect3DType GlovePosition;
FSGQuatImpl::FQuatType GloveRotation;
ToNova2GlovePtrChecked()->GetGloveLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware),
GlovePosition, GloveRotation);
OutGlovePosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(GlovePosition));
OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat();
}
void FSGNova2GloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
FVector& OutWristPosition, FQuat& OutWristRotation) const
{
FSGVect3DImpl::FVect3DType WristPosition;
FSGQuatImpl::FQuatType WristRotation;
ToNova2GlovePtrChecked()->GetWristLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware),
WristPosition, WristRotation);
OutWristPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(WristPosition));
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
FSGNovaGloveInfoImpl FSGNova2GloveImpl::GetGloveInfo() const
{
FSGNovaGloveInfoImpl GloveInfo{ToNova2GlovePtrChecked()->GetGloveInfo()};
return MoveTemp(GloveInfo);
}
bool FSGNova2GloveImpl::DoesIndexInfluenceOthers() const
{
return ToNova2GlovePtrChecked()->DoesIndexInfluenceOthers();
}
void FSGNova2GloveImpl::SetIndexInfluencesOthers(const bool bInfluenceOthers)
{
ToNova2GlovePtrChecked()->SetIndexInfluencesOthers(bInfluenceOthers);
}
bool FSGNova2GloveImpl::SupportsOnBoardNormalization() const
{
return ToNova2GlovePtrChecked()->SupportsOnBoardNormalization();
}
bool FSGNova2GloveImpl::GetSensorData(FSGNova2GloveSensorDataImpl& OutSensorData) const
{
FSGNova2GloveSensorDataImpl::FNova2GloveSensorDataType SensorData;
const bool bResult = ToNova2GlovePtrChecked()->GetSensorData(SensorData);
OutSensorData = FSGNova2GloveSensorDataImpl{MoveTemp(SensorData)};
return bResult;
}
bool FSGNova2GloveImpl::GetNormalizedInput(TArray<float>& OutNormalizedValues) const
{
std::vector<float> NormalizedValues;
const bool bResult = ToNova2GlovePtrChecked()->GetNormalizedInput(NormalizedValues);
OutNormalizedValues = FSGArrayUtils::FromStdVector(MoveTemp(NormalizedValues));
return bResult;
}
bool FSGNova2GloveImpl::SendRawData()
{
return ToNova2GlovePtrChecked()->SendRawData();
}
bool FSGNova2GloveImpl::SendNormalizedData()
{
return ToNova2GlovePtrChecked()->SendNormalizedData();
}
ESGNova2VibroMotor FSGNova2GloveImpl::ToNovaMotor(const ESGHapticLocation Location) const
{
return FSGCoreEnumCast::ToESGNova2VibroMotor(
ToNova2GlovePtrChecked()->ToNova2Motor(FSGCoreEnumCast::ToEHapticLocation(Location)));
}
int32 FSGNova2GloveImpl::ChannelIndex(const ESGNova2VibroMotor Motor) const
{
return ToNova2GlovePtrChecked()->ChannelIndex(FSGCoreEnumCast::ToENova2VibroMotor(Motor));
}
void FSGNova2GloveImpl::ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGNova2VibroMotor Motor) const
{
return ToNova2GlovePtrChecked()->ValidateWaveform(OutWaveform.ToCustomWaveform(),
FSGCoreEnumCast::ToENova2VibroMotor(Motor));
}
bool FSGNova2GloveImpl::SendCustomWaveform_Nova2(FSGCustomWaveformImpl& OutWaveform,
const ESGNova2VibroMotor Motor, const bool bValidateWaveform)
{
return ToNova2GlovePtrChecked()->SendCustomWaveform_Nova2(
OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToENova2VibroMotor(Motor), bValidateWaveform);
}
FString FSGNova2GloveImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(ToNova2GlovePtrChecked()->ToString().c_str())};
return MoveTemp(String);
}
FSGNova2GloveImpl::FImpl::FImpl(FSGNova2GloveImpl* InOwner)
: Owner(InOwner)
{
}
FSGNova2GloveImpl::FImpl::~FImpl() = default;
void FSGNova2GloveImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,211 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGNova2GloveSensorDataImpl.h"
#include <string>
#include <vector>
#include "Containers/StringConv.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_Nova2GloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGNovaGloveInfoImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGNova2GloveSensorDataImpl::FImpl
{
/************************
* Member variables
************************/
FNova2GloveSensorDataType Nova2GloveSensorData;
/************************
* Owner object
************************/
FSGNova2GloveSensorDataImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGNova2GloveSensorDataImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGNova2GloveSensorDataImpl FSGNova2GloveSensorDataImpl::Parse(const FString& RawData,
const FSGNovaGloveInfoImpl& GloveInfo)
{
std::string RawDataString(TCHAR_TO_UTF8(*RawData));
FSGNova2GloveSensorDataImpl SensorData{
FNova2GloveSensorDataType::Parse(
MoveTemp(RawDataString), GloveInfo.ToNovaGloveInfo())
};
return MoveTemp(SensorData);
}
FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const ESGNormalizationState NormalizationState,
const TArray<TArray<FVector>>& Values, const int32 ParsedValues,
const FQuat& ImuRotation, const bool bImuParsed,
const float BatteryLevel, const bool bCharging)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> ValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
Values)
};
Pimpl->Nova2GloveSensorData = FNova2GloveSensorDataType(
FSGCoreEnumCast::ToENormalizationState(NormalizationState),
MoveTemp(ValuesVector), ParsedValues, FSGQuatImpl(ImuRotation).ToQuat(), bImuParsed,
BatteryLevel, bCharging);
}
FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const FNova2GloveSensorDataType& Nova2GloveSensorData)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->Nova2GloveSensorData = Nova2GloveSensorData;
}
FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGNova2GloveSensorDataImpl::FSGNova2GloveSensorDataImpl(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT = default;
FSGNova2GloveSensorDataImpl::~FSGNova2GloveSensorDataImpl() = default;
FSGNova2GloveSensorDataImpl& FSGNova2GloveSensorDataImpl::operator=(const FSGNova2GloveSensorDataImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGNova2GloveSensorDataImpl& FSGNova2GloveSensorDataImpl::operator=(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGNova2GloveSensorDataImpl::FNova2GloveSensorDataType&
FSGNova2GloveSensorDataImpl::ToNova2GloveSensorData() const
{
return Pimpl->Nova2GloveSensorData;
}
ESGNormalizationState FSGNova2GloveSensorDataImpl::GetSensorState() const
{
return FSGCoreEnumCast::ToESGNormalizationState(Pimpl->Nova2GloveSensorData.GetSensorState());
}
TArray<TArray<FVector>> FSGNova2GloveSensorDataImpl::GetSensorValues() const
{
TArray<TArray<FVector>> SensorValues{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
Pimpl->Nova2GloveSensorData.GetSensorValues())
};
return MoveTemp(SensorValues);
}
float FSGNova2GloveSensorDataImpl::GetSensorValue(const ESGFinger Finger, const ESGNova2SensorLocation Location) const
{
return Pimpl->Nova2GloveSensorData.GetSensorValue(
FSGCoreEnumCast::ToEFinger(Finger), FSGCoreEnumCast::ToESensorLocation(Location));
}
int32 FSGNova2GloveSensorDataImpl::GetParsedValues() const
{
return Pimpl->Nova2GloveSensorData.GetParsedValues();
}
FQuat FSGNova2GloveSensorDataImpl::GetImuRotation() const
{
return FSGQuatImpl(Pimpl->Nova2GloveSensorData.GetImuRotation()).ToFQuat();
}
bool FSGNova2GloveSensorDataImpl::IsImuParsed() const
{
return Pimpl->Nova2GloveSensorData.IsImuParsed();
}
float FSGNova2GloveSensorDataImpl::GetBatteryLevel() const
{
return Pimpl->Nova2GloveSensorData.GetBatteryLevel();
}
bool FSGNova2GloveSensorDataImpl::IsCharging() const
{
return Pimpl->Nova2GloveSensorData.IsCharging();
}
bool FSGNova2GloveSensorDataImpl::Equals(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) const
{
return Pimpl->Nova2GloveSensorData.Equals(Nova2GloveSensorDataImpl.ToNova2GloveSensorData());
}
FString FSGNova2GloveSensorDataImpl::ToString() const
{
FString String(UTF8_TO_TCHAR(Pimpl->Nova2GloveSensorData.ToString().c_str()));
return MoveTemp(String);
}
FSGNova2GloveSensorDataImpl::FImpl::FImpl(FSGNova2GloveSensorDataImpl* InOwner)
: Owner(InOwner)
{
}
FSGNova2GloveSensorDataImpl::FImpl::~FImpl() = default;
void FSGNova2GloveSensorDataImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -1,91 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGNovaGloveCalibrationImpl.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveCalibration.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGNovaGloveHandProfileImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
void FSGNovaGloveCalibrationImpl::ApplyDefaultCalibrationInterpolationValues(const TArray<FVector>& RetractedValues,
const TArray<FVector>& ExtendedValues,
const FSGNovaGloveHandProfileImpl& Profile)
{
std::vector<FSGVect3DImpl::FVect3DType> RetractedValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
RetractedValues)
};
std::vector<FSGVect3DImpl::FVect3DType> ExtendedValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
ExtendedValues)
};
FNovaGloveCalibrationType::ApplyDefaultCalibrationInterpolationValues(
MoveTemp(RetractedValuesVector), MoveTemp(ExtendedValuesVector),
Profile.ToNovaGloveHandProfile());
}
void FSGNovaGloveCalibrationImpl::ApplyInterpolationValues(const TArray<FVector>& RetractedValues,
const TArray<FVector>& ExtendedValues,
const TArray<TArray<FVector>>& RetractedAngles,
const TArray<TArray<FVector>>& ExtendedAngles,
const FSGNovaGloveHandProfileImpl& Profile)
{
std::vector<FSGVect3DImpl::FVect3DType> RetractedValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
RetractedValues)
};
std::vector<FSGVect3DImpl::FVect3DType> ExtendedValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
ExtendedValues)
};
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> RetractedAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(RetractedAngles)
};
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> ExtendedAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(ExtendedAngles)
};
FNovaGloveCalibrationType::ApplyInterpolationValues(
MoveTemp(RetractedValuesVector), MoveTemp(ExtendedValuesVector),
MoveTemp(RetractedAnglesVector), MoveTemp(ExtendedAnglesVector),
Profile.ToNovaGloveHandProfile());
}
@@ -1,172 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 NovaGlove
*
* 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/SGNovaGloveHandProfileImpl.h"
#include <string>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveHandProfile.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGCoreImpl/SGHandInterpolatorImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGNovaGloveHandProfileImpl::FImpl
{
/************************
* Member variables
************************/
FNovaGloveHandProfileType NovaGloveHandProfile;
/************************
* Owner object
************************/
FSGNovaGloveHandProfileImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGNovaGloveHandProfileImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGNovaGloveHandProfileImpl FSGNovaGloveHandProfileImpl::Default(const bool bRightHanded)
{
FSGNovaGloveHandProfileImpl NovaGloveHandProfileImpl(FNovaGloveHandProfileType::Default(bRightHanded));
return NovaGloveHandProfileImpl;
}
FSGNovaGloveHandProfileImpl FSGNovaGloveHandProfileImpl::Deserialize(const FString& SerializedString)
{
std::string Serialized(TCHAR_TO_UTF8(*SerializedString));
const FSGNovaGloveHandProfileImpl HandProfile(FNovaGloveHandProfileType::Deserialize(MoveTemp(Serialized)));
return HandProfile;
}
FSGNovaGloveHandProfileImpl::FSGNovaGloveHandProfileImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGNovaGloveHandProfileImpl::FSGNovaGloveHandProfileImpl(bool bRightHanded, const FSGHandInterpolatorImpl& Interpolator)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->NovaGloveHandProfile = FNovaGloveHandProfileType(bRightHanded, Interpolator.ToHandInterpolator());
}
FSGNovaGloveHandProfileImpl::FSGNovaGloveHandProfileImpl(const FNovaGloveHandProfileType& NovaGloveHandProfile)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->NovaGloveHandProfile = NovaGloveHandProfile;
}
FSGNovaGloveHandProfileImpl::FSGNovaGloveHandProfileImpl(const FSGNovaGloveHandProfileImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGNovaGloveHandProfileImpl::FSGNovaGloveHandProfileImpl(FSGNovaGloveHandProfileImpl&& Rhs) SG_NOEXCEPT = default;
FSGNovaGloveHandProfileImpl::~FSGNovaGloveHandProfileImpl() = default;
FSGNovaGloveHandProfileImpl& FSGNovaGloveHandProfileImpl::operator=(const FSGNovaGloveHandProfileImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGNovaGloveHandProfileImpl& FSGNovaGloveHandProfileImpl::operator=(FSGNovaGloveHandProfileImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGNovaGloveHandProfileImpl::FNovaGloveHandProfileType& FSGNovaGloveHandProfileImpl::ToNovaGloveHandProfile(
) const
{
return Pimpl->NovaGloveHandProfile;
}
bool FSGNovaGloveHandProfileImpl::IsRight() const
{
return Pimpl->NovaGloveHandProfile.IsRight();
}
FSGHandInterpolatorImpl FSGNovaGloveHandProfileImpl::GetInterpolationSet() const
{
const FSGHandInterpolatorImpl HandInterpolatorImpl(
FSGHandInterpolatorImpl::FHandInterpolatorType(Pimpl->NovaGloveHandProfile.GetInterpolationSet()));
return HandInterpolatorImpl;
}
bool FSGNovaGloveHandProfileImpl::Equals(const FSGNovaGloveHandProfileImpl& NovaGloveHandProfileImpl) const
{
return Pimpl->NovaGloveHandProfile.Equals(NovaGloveHandProfileImpl.ToNovaGloveHandProfile());
}
void FSGNovaGloveHandProfileImpl::Reset()
{
Pimpl->NovaGloveHandProfile.Reset();
}
FString FSGNovaGloveHandProfileImpl::Serialize() const
{
const FString Serialized(UTF8_TO_TCHAR(Pimpl->NovaGloveHandProfile.Serialize().c_str()));
return Serialized;
}
FSGNovaGloveHandProfileImpl::FImpl::FImpl(FSGNovaGloveHandProfileImpl* InOwner)
: Owner(InOwner)
{
}
FSGNovaGloveHandProfileImpl::FImpl::~FImpl() = default;
void FSGNovaGloveHandProfileImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -40,32 +40,29 @@
#include "Containers/StringConv.h"
#include "Misc/AssertionMacros.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGBuildHacks/SGInclude_Core_CustomWaveform.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_HandProfile.h"
#include "SGBuildHacks/SGInclude_Core_HapticGlove.h"
#include "SGBuildHacks/SGInclude_Core_NovaGlove.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveHandProfile.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveInfo.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_ThumperCommand.h"
#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h"
#include "SGBuildHacks/SGInclude_Core_ThresholdCommand.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGBasicHandModelImpl.h"
#include "SGCoreImpl/SGBuzzCommandImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGForceFeedbackCommandImpl.h"
#include "SGCoreImpl/SGCustomWaveformImpl.h"
#include "SGCoreImpl/SGHandInterpolatorImpl.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGHandProfileImpl.h"
#include "SGCoreImpl/SGNovaGloveHandProfileImpl.h"
#include "SGCoreImpl/SGNovaGloveInfoImpl.h"
#include "SGCoreImpl/SGNovaGloveSensorDataImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGThumperCommandImpl.h"
#include "SGCoreImpl/SGSensorNormalizationImpl.h"
#include "SGCoreImpl/SGThresholdCommandImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
@@ -92,28 +89,6 @@ struct FSGNovaGloveImpl::FImpl
FImpl& operator=(const FImpl& Rhs) = default;
};
ANSICHAR FSGNovaGloveImpl::GetHapticsByte()
{
static const ANSICHAR Byte = FNovaGloveType::GetHapticsByte();
return Byte;
}
const FVector& FSGNovaGloveImpl::GetMinCalibrationRange()
{
static const FVector Range{FSGVect3DImpl{FNovaGloveType::GetMinCalibrationRange()}.ToFVector()};
return Range;
}
FSGHandPoseImpl FSGNovaGloveImpl::CalculateHandPose(const FSGBasicHandModelImpl& HandModel,
const FSGNovaGloveSensorDataImpl& NovaData,
const FSGNovaGloveHandProfileImpl& Profile)
{
FSGHandPoseImpl HandPose{FNovaGloveType::CalculateHandPose(
HandModel.ToBasicHandModel(), NovaData.ToNovaGloveSensorData(), Profile.ToNovaGloveHandProfile())
};
return MoveTemp(HandPose);
}
TSharedRef<FSGDeviceImpl> FSGNovaGloveImpl::Parse(const FString& ConstantsString)
{
std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)};
@@ -126,16 +101,12 @@ TSharedRef<FSGDeviceImpl> FSGNovaGloveImpl::Parse(const FString& ConstantsString
TArray<FSGNovaGloveImpl> FSGNovaGloveImpl::GetNovaGloves()
{
FNovaGloveVectorType Vector{FNovaGloveType::GetNovaGloves()};
TArray<FSGNovaGloveImpl> Array{
FSGArrayUtils::FromStdVector<FNovaGloveType, FSGNovaGloveImpl>(MoveTemp(Vector))
TArray<FSGNovaGloveImpl> Gloves{
FSGArrayUtils::FromStdVector<FNovaGloveType, FSGNovaGloveImpl>(FNovaGloveType::GetNovaGloves())
};
return MoveTemp(Array);
return MoveTemp(Gloves);
}
bool FSGNovaGloveImpl::GetNovaGlove(FSGNovaGloveImpl& OutGlove)
{
FNovaGloveType Glove;
@@ -152,36 +123,10 @@ bool FSGNovaGloveImpl::GetNovaGlove(const bool bRightHanded, FSGNovaGloveImpl& O
return bResult;
}
TArray<FVector> FSGNovaGloveImpl::GetCalibrationValues(const FSGNovaGloveSensorDataImpl& SensorData)
{
TArray<FVector> Values{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
FNovaGloveType::GetCalibrationValues(SensorData.ToNovaGloveSensorData()))
};
return MoveTemp(Values);
}
void FSGNovaGloveImpl::CalibrateInterpolation(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues,
FSGNovaGloveHandProfileImpl& OutProfile)
{
std::vector<FSGVect3DImpl::FVect3DType> MinValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MinValues)
};
std::vector<FSGVect3DImpl::FVect3DType> MaxValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MaxValues)
};
FSGNovaGloveHandProfileImpl::FNovaGloveHandProfileType Profile;
FNovaGloveType::CalibrateInterpolation(MoveTemp(MinValuesVector), MoveTemp(MaxValuesVector), Profile);
OutProfile = FSGNovaGloveHandProfileImpl{MoveTemp(Profile)};
}
void FSGNovaGloveImpl::CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
const bool bRightHanded,
FVector& OutGlovePosition, FQuat& OutGloveRotation)
void FSGNovaGloveImpl::CalculateGloveLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded,
FVector& OutGlovePosition, FQuat& OutGloveRotation)
{
FSGVect3DImpl::FVect3DType GlovePosition;
FSGQuatImpl::FQuatType GloveRotation;
@@ -189,19 +134,18 @@ void FSGNovaGloveImpl::CalculateGloveLocation(const FVector& ReferencePosition,
FNovaGloveType::CalculateGloveLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware),
bRightHanded,
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded,
GlovePosition, GloveRotation);
OutGlovePosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(GlovePosition));
MoveTemp(GlovePosition));;
OutGloveRotation = FSGQuatImpl{MoveTemp(GloveRotation)}.ToFQuat();
}
void FSGNovaGloveImpl::CalculateWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
const bool bRightHanded,
FVector& OutWristPosition, FQuat& OutWristRotation)
void FSGNovaGloveImpl::CalculateWristLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware, const bool bRightHanded,
FVector& OutWristPosition, FQuat& OutWristRotation)
{
FSGVect3DImpl::FVect3DType WristPosition;
FSGQuatImpl::FQuatType WristRotation;
@@ -209,8 +153,7 @@ void FSGNovaGloveImpl::CalculateWristLocation(const FVector& ReferencePosition,
FNovaGloveType::CalculateWristLocation(
FSGUnits::CentimetersToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(ReferencePosition),
FSGQuatImpl{ReferenceRotation}.ToQuat(),
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware),
bRightHanded,
FSGCoreEnumCast::ToEPositionalTrackingHardware(TrackingHardware), bRightHanded,
WristPosition, WristRotation);
OutWristPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
@@ -218,22 +161,79 @@ void FSGNovaGloveImpl::CalculateWristLocation(const FVector& ReferencePosition,
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
FString FSGNovaGloveImpl::ToBytes(const FSGThumperCommandImpl& ThumperCommand)
ANSICHAR FSGNovaGloveImpl::GetHapticsByte()
{
const FString Bytes{UTF8_TO_TCHAR(FNovaGloveType::ToBytes(ThumperCommand.ToThumperCommand()).c_str())};
return Bytes;
static const ANSICHAR Byte = FNovaGloveType::GetHapticsByte();
return Byte;
}
FString FSGNovaGloveImpl::ToBytes(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand)
ANSICHAR FSGNovaGloveImpl::GetThresholdsByte()
{
FString Bytes{UTF8_TO_TCHAR(FNovaGloveType::ToBytes(ForceFeedbackCommand.ToForceFeedbackCommand()).c_str())};
return MoveTemp(Bytes);
static const ANSICHAR Byte = FNovaGloveType::GetThresholdsByte();
return Byte;
}
FString FSGNovaGloveImpl::ToBytes(const FSGBuzzCommandImpl& BuzzCommand)
ANSICHAR FSGNovaGloveImpl::GetIgnoreThresholdsByte()
{
FString Bytes{UTF8_TO_TCHAR(FNovaGloveType::ToBytes(BuzzCommand.ToBuzzCommand()).c_str())};
return MoveTemp(Bytes);
static const ANSICHAR Byte = FNovaGloveType::GetIgnoreThresholdsByte();
return Byte;
}
const TArray<float>& FSGNovaGloveImpl::GetNovaSensorRanges()
{
static const TArray<float> Ranges{FSGArrayUtils::FromStdVector(FNovaGloveType::GetNovaSensorRanges())};
return Ranges;
}
TArray<float> FSGNovaGloveImpl::ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData)
{
TArray<float> NormalizedValues{
FSGArrayUtils::FromStdVector(
FNovaGloveType::ToNormalizedValues(SensorData.ToNovaGloveSensorData()))
};
return MoveTemp(NormalizedValues);
}
TArray<float> FSGNovaGloveImpl::ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData,
FSGSensorNormalizationImpl& OutSensorNormalizer)
{
TArray<float> NormalizedValues{
FSGArrayUtils::FromStdVector(
FNovaGloveType::ToNormalizedValues(SensorData.ToNovaGloveSensorData(),
OutSensorNormalizer.ToSensorNormalization()))
};
return MoveTemp(NormalizedValues);
}
TArray<TArray<FVector>> FSGNovaGloveImpl::CalculateHandAngles(
const TArray<float>& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator)
{
std::vector<float> NormalizedValuesVector{FSGArrayUtils::ToStdVector(NormalizedValues)};
TArray<TArray<FVector>> Angles{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
FNovaGloveType::CalculateHandAngles(MoveTemp(NormalizedValuesVector), Interpolator.ToHandInterpolator()))
};
return MoveTemp(Angles);
}
FString FSGNovaGloveImpl::ToNovaCommandAsFlexion(const FSGThresholdCommandImpl& Thresholds)
{
FString Flexion{
UTF8_TO_TCHAR(FNovaGloveType::ToNovaCommandAsFlexion(Thresholds.ToThresholdCommand()).c_str())
};
return MoveTemp(Flexion);
}
FString FSGNovaGloveImpl::ToNovaCommandAsRaw(
const FSGThresholdCommandImpl& Thresholds, const FSGSensorNormalizationImpl& Interpolator)
{
FString Raw{
UTF8_TO_TCHAR(FNovaGloveType::ToNovaCommandAsRaw(Thresholds.ToThresholdCommand(),
Interpolator.ToSensorNormalization()).c_str())
};
return MoveTemp(Raw);
}
FSGNovaGloveImpl::FSGNovaGloveImpl()
@@ -293,7 +293,7 @@ FSGNovaGloveImpl::FNovaGlovePtrType FSGNovaGloveImpl::ToNovaGlovePtr() const
FSGNovaGloveImpl::FNovaGlovePtrType FSGNovaGloveImpl::ToNovaGlovePtrChecked() const
{
FNovaGlovePtrType NovaGlove = std::dynamic_pointer_cast<FNovaGloveType>(ToSGDevicePtr());
FNovaGlovePtrType NovaGlove{std::dynamic_pointer_cast<FNovaGloveType>(ToSGDevicePtr())};
ensureAlwaysMsgf(NovaGlove.get(), TEXT("Invalid NovaGlove"));
return NovaGlove;
}
@@ -305,14 +305,14 @@ ESGDeviceType FSGNovaGloveImpl::GetDeviceType() const
FString FSGNovaGloveImpl::GetDeviceId() const
{
const FString Id{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetDeviceId().c_str())};
return Id;
FString Id{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetDeviceId().c_str())};
return MoveTemp(Id);
}
FString FSGNovaGloveImpl::GetHardwareVersion() const
{
const FString Version{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetHardwareVersion().c_str())};
return Version;
FString Version{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->GetHardwareVersion().c_str())};
return MoveTemp(Version);
}
int32 FSGNovaGloveImpl::GetFirmwareVersion() const
@@ -325,6 +325,11 @@ int32 FSGNovaGloveImpl::GetSubFirmwareVersion() const
return ToNovaGlovePtrChecked()->GetSubFirmwareVersion();
}
void FSGNovaGloveImpl::SetDeviceIndex(const int32 NewIndex)
{
ToNovaGlovePtrChecked()->SetDeviceIndex(NewIndex);
}
bool FSGNovaGloveImpl::HasBattery() const
{
return ToNovaGlovePtrChecked()->HasBattery();
@@ -340,12 +345,9 @@ bool FSGNovaGloveImpl::GetBatteryLevel(float& OutBatteryLevel)
return ToNovaGlovePtrChecked()->GetBatteryLevel(OutBatteryLevel);
}
bool FSGNovaGloveImpl::GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData)
bool FSGNovaGloveImpl::IsRight() const
{
FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType SensorData;
const bool bResult = ToNovaGlovePtrChecked()->GetSensorData(SensorData);
OutSensorData = FSGNovaGloveSensorDataImpl{MoveTemp(SensorData)};
return bResult;
return ToNovaGlovePtrChecked()->IsRight();
}
bool FSGNovaGloveImpl::GetImuRotation(FQuat& OutImu)
@@ -356,77 +358,73 @@ bool FSGNovaGloveImpl::GetImuRotation(FQuat& OutImu)
return bResult;
}
bool FSGNovaGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandModel, const FSGNovaGloveHandProfileImpl& Profile,
FSGHandPoseImpl& OutHandPose)
bool FSGNovaGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToNovaGlovePtrChecked()->GetHandPose(
HandModel.ToBasicHandModel(), Profile.ToNovaGloveHandProfile(), HandPose);
const bool bResult = ToNovaGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
}
bool FSGNovaGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose)
bool FSGNovaGloveImpl::GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToNovaGlovePtrChecked()->GetHandPose(
HandGeometry.ToBasicHandModel(), HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> HandAngles;
const bool bResult = ToNovaGlovePtrChecked()->GetHandAngles(HandAngles);
OutHandAngles = FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(HandAngles));
return bResult;
}
bool FSGNovaGloveImpl::GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose)
ESGHapticGloveCalibrationState FSGNovaGloveImpl::GetCalibrationState() const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToNovaGlovePtrChecked()->GetHandPose(HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToNovaGlovePtrChecked()->GetCalibrationState());
}
void FSGNovaGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand, const FSGThumperCommandImpl& ThumperCommand)
void FSGNovaGloveImpl::EndCalibration()
{
ToNovaGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand(),
BuzzCommand.ToBuzzCommand(), ThumperCommand.ToThumperCommand());
ToNovaGlovePtrChecked()->EndCalibration();
}
void FSGNovaGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand)
void FSGNovaGloveImpl::ResetCalibration()
{
ToNovaGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand());
ToNovaGlovePtrChecked()->ResetCalibration();
}
void FSGNovaGloveImpl::SendHaptics(const FSGBuzzCommandImpl& BuzzCommand)
void FSGNovaGloveImpl::StopHaptics()
{
ToNovaGlovePtrChecked()->SendHaptics(BuzzCommand.ToBuzzCommand());
ToNovaGlovePtrChecked()->StopHaptics();
}
void FSGNovaGloveImpl::SendHaptics(const FSGThumperCommandImpl& ThumperCommand)
void FSGNovaGloveImpl::StopVibrations()
{
ToNovaGlovePtrChecked()->SendHaptics(ThumperCommand.ToThumperCommand());
ToNovaGlovePtrChecked()->StopVibrations();
}
bool FSGNovaGloveImpl::GetCalibrationValues(TArray<FVector>& OutValues)
bool FSGNovaGloveImpl::SendHaptics()
{
std::vector<FSGVect3DImpl::FVect3DType> Values;
const bool bResult = ToNovaGlovePtrChecked()->GetCalibrationValues(Values);
OutValues = FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector,
FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(Values));
return bResult;
return ToNovaGlovePtrChecked()->SendHaptics();
}
void FSGNovaGloveImpl::ApplyCalibration(FSGHandProfileImpl& OutProfile) const
bool FSGNovaGloveImpl::SupportsCustomWaveform(const ESGHapticLocation AtLocation) const
{
FSGHandProfileImpl::FHandProfileType Profile;
ToNovaGlovePtrChecked()->ApplyCalibration(Profile);
OutProfile = FSGHandProfileImpl{MoveTemp(Profile)};
return ToNovaGlovePtrChecked()->SupportsCustomWaveform(FSGCoreEnumCast::ToEHapticLocation(AtLocation));
}
void FSGNovaGloveImpl::ApplyCalibration(FSGNovaGloveHandProfileImpl& OutProfile) const
bool FSGNovaGloveImpl::SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location)
{
FSGNovaGloveHandProfileImpl::FNovaGloveHandProfileType Profile;
ToNovaGlovePtrChecked()->ApplyCalibration(Profile);
OutProfile = FSGNovaGloveHandProfileImpl{MoveTemp(Profile)};
return ToNovaGlovePtrChecked()->SendCustomWaveform(OutWaveform.ToCustomWaveform(),
FSGCoreEnumCast::ToEHapticLocation(Location));
}
bool FSGNovaGloveImpl::QueueForceFeedbackLevels(const TArray<float>& Levels01)
{
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)};
return ToNovaGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector));
}
bool FSGNovaGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01)
{
return ToNovaGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01);
}
void FSGNovaGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -465,13 +463,109 @@ void FSGNovaGloveImpl::GetWristLocation(const FVector& ReferencePosition, const
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
FSGNovaGloveInfoImpl FSGNovaGloveImpl::GetGloveInfo() const
{
FSGNovaGloveInfoImpl GloveInfo{ToNovaGlovePtrChecked()->GetGloveInfo()};
return MoveTemp(GloveInfo);
}
bool FSGNovaGloveImpl::SupportsThresholds() const
{
return ToNovaGlovePtrChecked()->SupportsThresholds();
}
bool FSGNovaGloveImpl::SupportsCustomWaveforms() const
{
return ToNovaGlovePtrChecked()->SupportsCustomWaveforms();
}
bool FSGNovaGloveImpl::SupportsOnBoardNormalization() const
{
return ToNovaGlovePtrChecked()->SupportsOnBoardNormalization();
}
bool FSGNovaGloveImpl::GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData) const
{
FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType SensorData;
const bool bResult = ToNovaGlovePtrChecked()->GetSensorData(SensorData);
OutSensorData = FSGNovaGloveSensorDataImpl{MoveTemp(SensorData)};
return bResult;
}
bool FSGNovaGloveImpl::GetNormalizedInput(TArray<float>& OutNormalizedValues) const
{
std::vector<float> NormalizedValues;
const bool bResult = ToNovaGlovePtrChecked()->GetNormalizedInput(NormalizedValues);
OutNormalizedValues = FSGArrayUtils::FromStdVector(MoveTemp(NormalizedValues));
return bResult;
}
FString FSGNovaGloveImpl::ToNovaCommand(
const TArray<float>& ForceFeedbackLevels, const TArray<float>& BuzzLevels, const float WristLevel) const
{
std::vector<float> ForceFeedbackLevelsVector{FSGArrayUtils::ToStdVector(ForceFeedbackLevels)};
std::vector<float> BuzzLevelsVector{FSGArrayUtils::ToStdVector(BuzzLevels)};
FString Command{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->ToNovaCommand(
MoveTemp(ForceFeedbackLevelsVector), MoveTemp(BuzzLevelsVector), WristLevel).c_str())};
return MoveTemp(Command);
}
bool FSGNovaGloveImpl::QueueVibroLevels(const TArray<float>& Amplitudes)
{
std::vector<float> AmplitudesVector{FSGArrayUtils::ToStdVector(Amplitudes)};
return ToNovaGlovePtrChecked()->QueueVibroLevels(MoveTemp(AmplitudesVector));
}
bool FSGNovaGloveImpl::QueueVibroLevel(const int32 Finger, const float Amplitude)
{
return ToNovaGlovePtrChecked()->QueueVibroLevel(Finger, Amplitude);
}
bool FSGNovaGloveImpl::QueueWristLevel(const float Amplitude)
{
return ToNovaGlovePtrChecked()->QueueWristLevel(Amplitude);
}
ESGNovaVibroMotor FSGNovaGloveImpl::ToNovaMotor(const ESGHapticLocation Location) const
{
return FSGCoreEnumCast::ToESGNovaVibroMotor(
ToNovaGlovePtrChecked()->ToNovaMotor(FSGCoreEnumCast::ToEHapticLocation(Location)));
}
int32 FSGNovaGloveImpl::ChannelIndex(const ESGNovaVibroMotor Motor) const
{
return ToNovaGlovePtrChecked()->ChannelIndex(FSGCoreEnumCast::ToENovaVibroMotor(Motor));
}
void FSGNovaGloveImpl::ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, const ESGNovaVibroMotor Motor) const
{
return ToNovaGlovePtrChecked()->ValidateWaveform(OutWaveform.ToCustomWaveform(),
FSGCoreEnumCast::ToENovaVibroMotor(Motor));
}
bool FSGNovaGloveImpl::SendCustomWaveform_Nova(FSGCustomWaveformImpl& OutWaveform,
const ESGNovaVibroMotor Motor, const bool bValidateWaveform)
{
return ToNovaGlovePtrChecked()->SendCustomWaveform_Nova(
OutWaveform.ToCustomWaveform(), FSGCoreEnumCast::ToENovaVibroMotor(Motor), bValidateWaveform);
}
bool FSGNovaGloveImpl::QueueThresholdCommand_Flexion(const int32 Finger, const float FlexionThreshold)
{
return ToNovaGlovePtrChecked()->QueueThresholdCommand_Flexion(Finger, FlexionThreshold);
}
bool FSGNovaGloveImpl::QueueClearThreshold(const int32 Finger)
{
return ToNovaGlovePtrChecked()->QueueClearThreshold(Finger);
}
FString FSGNovaGloveImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(ToNovaGlovePtrChecked()->ToString().c_str())};
return MoveTemp(String);
}
FSGNovaGloveImpl::FImpl::FImpl(FSGNovaGloveImpl* InOwner)
: Owner(InOwner)
{
@@ -181,6 +181,18 @@ int32 FSGNovaGloveInfoImpl::GetNumberOfSensors() const
return Pimpl->NovaGloveInfo.GetNumberOfSensors();
}
bool FSGNovaGloveInfoImpl::FirmwareNewerThan(const int32 FirmwareMain, const int32 FirmwareSub,
const bool bInclusive) const
{
return Pimpl->NovaGloveInfo.FirmwareNewerThan(FirmwareMain, FirmwareSub, bInclusive);
}
bool FSGNovaGloveInfoImpl::FirmwareOlderThan(const int32 FirmwareMain, const int32 FirmwareSub,
const bool bInclusive) const
{
return Pimpl->NovaGloveInfo.FirmwareOlderThan(FirmwareMain, FirmwareSub, bInclusive);
}
bool FSGNovaGloveInfoImpl::Equals(const FSGNovaGloveInfoImpl& SGNovaGloveInfo) const
{
return Pimpl->NovaGloveInfo.Equals(SGNovaGloveInfo.ToNovaGloveInfo());
@@ -44,6 +44,7 @@
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_NovaGloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGNovaGloveInfoImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
@@ -145,12 +146,16 @@ FSGNovaGloveSensorDataImpl& FSGNovaGloveSensorDataImpl::operator=(const FSGNovaG
FSGNovaGloveSensorDataImpl& FSGNovaGloveSensorDataImpl::operator=(FSGNovaGloveSensorDataImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType& FSGNovaGloveSensorDataImpl::ToNovaGloveSensorData(
) const
const FSGNovaGloveSensorDataImpl::FNovaGloveSensorDataType& FSGNovaGloveSensorDataImpl::ToNovaGloveSensorData() const
{
return Pimpl->NovaGloveSensorData;
}
ESGNormalizationState FSGNovaGloveSensorDataImpl::GetSensorState() const
{
return FSGCoreEnumCast::ToESGNormalizationState(Pimpl->NovaGloveSensorData.GetSensorState());
}
TArray<FVector> FSGNovaGloveSensorDataImpl::GetSensorValues() const
{
TArray<FVector> SensorValues{
@@ -160,9 +165,10 @@ TArray<FVector> FSGNovaGloveSensorDataImpl::GetSensorValues() const
return MoveTemp(SensorValues);
}
FQuat FSGNovaGloveSensorDataImpl::GetImuRotation() const
float FSGNovaGloveSensorDataImpl::GetSensorValue(const ESGFinger Finger, const ESGNovaSensorLocation Location) const
{
return FSGQuatImpl(Pimpl->NovaGloveSensorData.GetImuRotation()).ToFQuat();
return Pimpl->NovaGloveSensorData.GetSensorValue(
FSGCoreEnumCast::ToEFinger(Finger), FSGCoreEnumCast::ToESensorLocation(Location));
}
int32 FSGNovaGloveSensorDataImpl::GetParsedValues() const
@@ -170,6 +176,11 @@ int32 FSGNovaGloveSensorDataImpl::GetParsedValues() const
return Pimpl->NovaGloveSensorData.GetParsedValues();
}
FQuat FSGNovaGloveSensorDataImpl::GetImuRotation() const
{
return FSGQuatImpl(Pimpl->NovaGloveSensorData.GetImuRotation()).ToFQuat();
}
bool FSGNovaGloveSensorDataImpl::IsImuParsed() const
{
return Pimpl->NovaGloveSensorData.IsImuParsed();
@@ -1,212 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGSenseGloveHandProfileImpl.h"
#include <string>
#include <vector>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGHandInterpolatorImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGSenseGloveHandProfileImpl::FImpl
{
/************************
* Member variables
************************/
FSenseGloveHandProfileType SenseGloveHandProfile;
/************************
* Owner object
************************/
FSGSenseGloveHandProfileImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGSenseGloveHandProfileImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGSenseGloveHandProfileImpl FSGSenseGloveHandProfileImpl::Default(const bool bRightHanded)
{
FSGSenseGloveHandProfileImpl SenseGloveHandProfileImpl(FSenseGloveHandProfileType::Default(bRightHanded));
return SenseGloveHandProfileImpl;
}
FSGSenseGloveHandProfileImpl FSGSenseGloveHandProfileImpl::Deserialize(const FString& SerializedString)
{
std::string Serialized(TCHAR_TO_UTF8(*SerializedString));
const FSGSenseGloveHandProfileImpl HandProfile(FSenseGloveHandProfileType::Deserialize(MoveTemp(Serialized)));
return HandProfile;
}
const FVector& FSGSenseGloveHandProfileImpl::GetDefaultThimbleOffset()
{
static const FVector DefaultThimbleOffset(
FSGVect3DImpl(FSenseGloveHandProfileType::GetDefaultThimbleOffset()).ToFVector());
return DefaultThimbleOffset;
}
FSGSenseGloveHandProfileImpl::FSGSenseGloveHandProfileImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGSenseGloveHandProfileImpl::FSGSenseGloveHandProfileImpl(const bool bRightHanded,
const FSGHandInterpolatorImpl& Interpolator,
const ESGThumbSolver ThumbSolver,
const ESGFingerSolver FingerSolver,
const TArray<FVector>& FingerThimbleOffset)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<FSGVect3DImpl::FVect3DType> FingerThimbleOffsetVector{
FSGArrayUtils::ToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(FingerThimbleOffset)
};
Pimpl->SenseGloveHandProfile = FSenseGloveHandProfileType(
bRightHanded, Interpolator.ToHandInterpolator(),
FSGCoreEnumCast::ToEThumbSolver(ThumbSolver),
FSGCoreEnumCast::ToEFingerSolver(FingerSolver),
MoveTemp(FingerThimbleOffsetVector));
}
FSGSenseGloveHandProfileImpl::FSGSenseGloveHandProfileImpl(const FSenseGloveHandProfileType& SenseGloveHandProfile)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->SenseGloveHandProfile = SenseGloveHandProfile;
}
FSGSenseGloveHandProfileImpl::FSGSenseGloveHandProfileImpl(const FSGSenseGloveHandProfileImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGSenseGloveHandProfileImpl::FSGSenseGloveHandProfileImpl(FSGSenseGloveHandProfileImpl&& Rhs) SG_NOEXCEPT = default;
FSGSenseGloveHandProfileImpl::~FSGSenseGloveHandProfileImpl() = default;
FSGSenseGloveHandProfileImpl& FSGSenseGloveHandProfileImpl::operator=(const FSGSenseGloveHandProfileImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGSenseGloveHandProfileImpl& FSGSenseGloveHandProfileImpl::operator=(FSGSenseGloveHandProfileImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGSenseGloveHandProfileImpl::FSenseGloveHandProfileType& FSGSenseGloveHandProfileImpl::ToSenseGloveHandProfile(
) const
{
return Pimpl->SenseGloveHandProfile;
}
bool FSGSenseGloveHandProfileImpl::IsRight() const
{
return Pimpl->SenseGloveHandProfile.IsRight();
}
FSGHandInterpolatorImpl FSGSenseGloveHandProfileImpl::GetInterpolationSet() const
{
const FSGHandInterpolatorImpl HandInterpolatorImpl(
FSGHandInterpolatorImpl::FHandInterpolatorType(Pimpl->SenseGloveHandProfile.GetInterpolationSet()));
return HandInterpolatorImpl;
}
ESGThumbSolver FSGSenseGloveHandProfileImpl::GetThumbSolver() const
{
return FSGCoreEnumCast::ToESGThumbSolver(Pimpl->SenseGloveHandProfile.GetThumbSolver());
}
ESGFingerSolver FSGSenseGloveHandProfileImpl::GetFingerSolver() const
{
return FSGCoreEnumCast::ToESGFingerSolver(Pimpl->SenseGloveHandProfile.GetFingerSolver());
}
TArray<FVector> FSGSenseGloveHandProfileImpl::GetFingerThimbleOffset() const
{
const TArray<FVector> FingerThimbleOffset{
FSGArrayUtils::FromMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
Pimpl->SenseGloveHandProfile.GetFingerThimbleOffset())
};
return FingerThimbleOffset;
}
bool FSGSenseGloveHandProfileImpl::Equals(const FSGSenseGloveHandProfileImpl& SenseGloveHandProfileImpl) const
{
return Pimpl->SenseGloveHandProfile.Equals(SenseGloveHandProfileImpl.ToSenseGloveHandProfile());
}
void FSGSenseGloveHandProfileImpl::Reset()
{
Pimpl->SenseGloveHandProfile.Reset();
}
FString FSGSenseGloveHandProfileImpl::Serialize() const
{
const FString Serialized(UTF8_TO_TCHAR(Pimpl->SenseGloveHandProfile.Serialize().c_str()));
return Serialized;
}
FSGSenseGloveHandProfileImpl::FImpl::FImpl(FSGSenseGloveHandProfileImpl* InOwner)
: Owner(InOwner)
{
}
FSGSenseGloveHandProfileImpl::FImpl::~FImpl() = default;
void FSGSenseGloveHandProfileImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -43,31 +43,25 @@
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_BasicHandModel.h"
#include "SGBuildHacks/SGInclude_Core_BuzzCommand.h"
#include "SGBuildHacks/SGInclude_Core_ForceFeedbackCommand.h"
#include "SGBuildHacks/SGInclude_Core_HandInterpolator.h"
#include "SGBuildHacks/SGInclude_Core_HandPose.h"
#include "SGBuildHacks/SGInclude_Core_HandProfile.h"
#include "SGBuildHacks/SGInclude_Core_HapticGlove.h"
#include "SGBuildHacks/SGInclude_Core_Quat.h"
#include "SGBuildHacks/SGInclude_Core_SenseGlove.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveHandProfile.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveInfo.h"
#include "SGBuildHacks/SGInclude_Core_SenseGlovePose.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorData.h"
#include "SGBuildHacks/SGInclude_Core_ThumperCommand.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGBasicHandModelImpl.h"
#include "SGCoreImpl/SGBuzzCommandImpl.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGCoreImpl/SGForceFeedbackCommandImpl.h"
#include "SGCoreImpl/SGHandInterpolatorImpl.h"
#include "SGCoreImpl/SGHandPoseImpl.h"
#include "SGCoreImpl/SGHandProfileImpl.h"
#include "SGCoreImpl/SGQuatImpl.h"
#include "SGCoreImpl/SGSenseGloveHandProfileImpl.h"
#include "SGCoreImpl/SGSenseGloveInfoImpl.h"
#include "SGCoreImpl/SGSenseGlovePoseImpl.h"
#include "SGCoreImpl/SGSenseGloveSensorDataImpl.h"
#include "SGCoreImpl/SGThumperCommandImpl.h"
#include "SGCoreImpl/SGSenseGloveSensorNormalizerImpl.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
@@ -94,49 +88,6 @@ struct FSGSenseGloveImpl::FImpl
FImpl& operator=(const FImpl& Rhs) = default;
};
ANSICHAR FSGSenseGloveImpl::GetHapticsByte()
{
static const ANSICHAR Byte = FSenseGloveType::GetHapticsByte();
return Byte;
}
ANSICHAR FSGSenseGloveImpl::GetThumperByte()
{
static const ANSICHAR Byte = FSenseGloveType::GetThumperByte();
return Byte;
}
FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
const FSGSenseGloveInfoImpl& GloveModel)
{
FSGSenseGlovePoseImpl Pose{
FSenseGloveType::CalculateGlovePose(SensorData.ToSenseGloveSensorData(), GloveModel.ToSenseGloveInfo())
};
return MoveTemp(Pose);
}
FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const TArray<TArray<FVector>>& GloveAngles,
const FSGSenseGloveInfoImpl& GloveModel)
{
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> GloveAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(GloveAngles)
};
FSGSenseGlovePoseImpl Pose{
FSenseGloveType::CalculateGlovePose(MoveTemp(GloveAnglesVector), GloveModel.ToSenseGloveInfo())
};
return MoveTemp(Pose);
}
FSGHandPoseImpl FSGSenseGloveImpl::CalculateHandPose(const FSGSenseGlovePoseImpl& GlovePose,
const FSGBasicHandModelImpl& HandModel,
const FSGSenseGloveHandProfileImpl& Profile)
{
FSGHandPoseImpl HandPose{FSenseGloveType::CalculateHandPose(
GlovePose.ToSenseGlovePose(), HandModel.ToBasicHandModel(), Profile.ToSenseGloveHandProfile())
};
return MoveTemp(HandPose);
}
TSharedRef<FSGDeviceImpl> FSGSenseGloveImpl::Parse(const FString& ConstantsString)
{
std::string ConstantsStdString{TCHAR_TO_UTF8(*ConstantsString)};
@@ -158,7 +109,6 @@ TArray<FSGSenseGloveImpl> FSGSenseGloveImpl::GetSenseGloves()
return MoveTemp(Array);
}
bool FSGSenseGloveImpl::GetSenseGlove(FSGSenseGloveImpl& OutGlove)
{
FSenseGloveType Glove;
@@ -175,33 +125,6 @@ bool FSGSenseGloveImpl::GetSenseGlove(const bool bRightHanded, FSGSenseGloveImpl
return bResult;
}
TArray<FVector> FSGSenseGloveImpl::GetCalibrationValues(const FSGSenseGlovePoseImpl& GlovePose)
{
TArray<FVector> Values{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
FSenseGloveType::GetCalibrationValues(GlovePose.ToSenseGlovePose()))
};
return MoveTemp(Values);
}
void FSGSenseGloveImpl::CalibrateInterpolation(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues,
const bool bRightHanded, FSGSenseGloveHandProfileImpl& OutProfile)
{
std::vector<FSGVect3DImpl::FVect3DType> MinValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MinValues)
};
std::vector<FSGVect3DImpl::FVect3DType> MaxValuesVector{
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MaxValues)
};
FSGSenseGloveHandProfileImpl::FSenseGloveHandProfileType Profile;
FSenseGloveType::CalibrateInterpolation(MoveTemp(MinValuesVector), MoveTemp(MaxValuesVector),
bRightHanded, Profile);
OutProfile = FSGSenseGloveHandProfileImpl{MoveTemp(Profile)};
}
void FSGSenseGloveImpl::CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
const bool bRightHanded, const ESGFinger MountedOn,
@@ -246,6 +169,95 @@ void FSGSenseGloveImpl::CalculateWristLocation(const FVector& ReferencePosition,
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
ANSICHAR FSGSenseGloveImpl::GetHapticsByte()
{
static const ANSICHAR Byte = FSenseGloveType::GetHapticsByte();
return Byte;
}
ANSICHAR FSGSenseGloveImpl::GetThumperByte()
{
static const ANSICHAR Byte = FSenseGloveType::GetThumperByte();
return Byte;
}
const FVector& FSGSenseGloveImpl::GetDefaultThimbleOffset()
{
static const FVector Offset{FSGVect3DImpl{FSenseGloveType::GetDefaultThimbleOffset()}.ToFVector()};
return Offset;
}
FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
const FSGSenseGloveInfoImpl& GloveModel)
{
FSGSenseGlovePoseImpl Pose{
FSenseGloveType::CalculateGlovePose(SensorData.ToSenseGloveSensorData(), GloveModel.ToSenseGloveInfo())
};
return MoveTemp(Pose);
}
FSGSenseGlovePoseImpl FSGSenseGloveImpl::CalculateGlovePose(const TArray<TArray<FVector>>& GloveAngles,
const FSGSenseGloveInfoImpl& GloveModel)
{
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> GloveAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(GloveAngles)
};
FSGSenseGlovePoseImpl Pose{
FSenseGloveType::CalculateGlovePose(MoveTemp(GloveAnglesVector), GloveModel.ToSenseGloveInfo())
};
return MoveTemp(Pose);
}
void FSGSenseGloveImpl::NormalizeValues(
const TArray<FVector>& SumAngles, const FSGSenseGloveSensorNormalizerImpl& Normalizer,
TArray<float>& OutFlexions, TArray<float>& OutAbductions)
{
std::vector<FSGVect3DImpl::FVect3DType> SumAnglesVector{
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(SumAngles)
};
std::vector<float> Flexions;
std::vector<float> Abductions;
FSenseGloveType::NormalizeValues(MoveTemp(SumAnglesVector), Normalizer.ToSenseGloveSensorNormalizer(),
Flexions, Abductions);
OutFlexions = FSGArrayUtils::FromStdVector(MoveTemp(Flexions));
OutAbductions = FSGArrayUtils::FromStdVector(MoveTemp(Abductions));
}
void FSGSenseGloveImpl::CalculateHandAngles(
const FSGSenseGlovePoseImpl& GlovePose,
const FSGSenseGloveSensorNormalizerImpl& Normalizer, const FSGHandInterpolatorImpl& NormalizedToAngles,
TArray<TArray<FVector>>& OutHandAngles)
{
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> HandAngles;
FSenseGloveType::CalculateHandAngles(
GlovePose.ToSenseGlovePose(),
Normalizer.ToSenseGloveSensorNormalizer(), NormalizedToAngles.ToHandInterpolator(),
HandAngles);
OutHandAngles = FSGArrayUtils::FromSenseGloveAngles<FSGVect3DImpl::FVect3DType>(MoveTemp(HandAngles));
}
void FSGSenseGloveImpl::CalculateHandPose(
const FSGSenseGlovePoseImpl& GlovePose, const FSGBasicHandModelImpl& HandModel,
const FSGSenseGloveSensorNormalizerImpl& Normalizer, const FSGHandInterpolatorImpl& NormalizedToAngles,
FSGHandPoseImpl& OutHandPose)
{
FSGHandPoseImpl::FHandPoseType HandPose;
FSenseGloveType::CalculateHandPose(
GlovePose.ToSenseGlovePose(), HandModel.ToBasicHandModel(),
Normalizer.ToSenseGloveSensorNormalizer(), NormalizedToAngles.ToHandInterpolator(),
HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
}
FSGSenseGloveImpl::FSGSenseGloveImpl()
: FSGHapticGloveImpl(),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
@@ -308,16 +320,6 @@ FSGSenseGloveImpl::FSenseGlovePtrType FSGSenseGloveImpl::ToSenseGlovePtrChecked(
return SenseGlove;
}
FSGSenseGloveInfoImpl FSGSenseGloveImpl::GetGloveModel() const
{
return FSGSenseGloveInfoImpl{ToSenseGlovePtr()->GetGloveModel()};
}
bool FSGSenseGloveImpl::IsRight() const
{
return ToSenseGlovePtr()->IsRight();
}
ESGDeviceType FSGSenseGloveImpl::GetDeviceType() const
{
return FSGCoreEnumCast::ToESGDeviceType(ToSenseGlovePtrChecked()->GetDeviceType());
@@ -325,14 +327,14 @@ ESGDeviceType FSGSenseGloveImpl::GetDeviceType() const
FString FSGSenseGloveImpl::GetDeviceId() const
{
const FString Id{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetDeviceId().c_str())};
return Id;
FString Id{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetDeviceId().c_str())};
return MoveTemp(Id);
}
FString FSGSenseGloveImpl::GetHardwareVersion() const
{
const FString Version{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetHardwareVersion().c_str())};
return Version;
FString Version{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->GetHardwareVersion().c_str())};
return MoveTemp(Version);
}
int32 FSGSenseGloveImpl::GetFirmwareVersion() const
@@ -345,12 +347,9 @@ int32 FSGSenseGloveImpl::GetSubFirmwareVersion() const
return ToSenseGlovePtrChecked()->GetSubFirmwareVersion();
}
bool FSGSenseGloveImpl::GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const
bool FSGSenseGloveImpl::IsRight() const
{
FSGSenseGloveSensorDataImpl::FSenseGloveSensorDataType SensorData;
const bool bResult = ToSenseGlovePtrChecked()->GetSensorData(SensorData);
OutSensorData = FSGSenseGloveSensorDataImpl{MoveTemp(SensorData)};
return bResult;
return ToSenseGlovePtr()->IsRight();
}
bool FSGSenseGloveImpl::GetImuRotation(FQuat& OutImu)
@@ -361,108 +360,63 @@ bool FSGSenseGloveImpl::GetImuRotation(FQuat& OutImu)
return bResult;
}
bool FSGSenseGloveImpl::GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose)
{
FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose;
const bool bResult = ToSenseGlovePtr()->GetGlovePose(GlovePose);
OutGlovePose = FSGSenseGlovePoseImpl{GlovePose};
return bResult;
}
bool FSGSenseGloveImpl::GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
FSGSenseGlovePoseImpl& OutGlovePose)
{
FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose;
const bool bResult = ToSenseGlovePtr()->GetGlovePose(SensorData.ToSenseGloveSensorData(), GlovePose);
OutGlovePose = FSGSenseGlovePoseImpl{GlovePose};
return bResult;
}
bool FSGSenseGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandModel, const FSGSenseGloveHandProfileImpl& Profile,
FSGHandPoseImpl& OutHandPose)
bool FSGSenseGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToSenseGlovePtrChecked()->GetHandPose(
HandModel.ToBasicHandModel(), Profile.ToSenseGloveHandProfile(), HandPose);
const bool bResult = ToSenseGlovePtrChecked()->GetHandPose(HandGeometry.ToBasicHandModel(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
}
bool FSGSenseGloveImpl::GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose)
bool FSGSenseGloveImpl::GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToSenseGlovePtrChecked()->GetHandPose(
HandGeometry.ToBasicHandModel(), HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
std::vector<std::vector<FSGVect3DImpl::FVect3DType>> HandAngles;
const bool bResult = ToSenseGlovePtrChecked()->GetHandAngles(HandAngles);
OutHandAngles =
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
MoveTemp(HandAngles));
return bResult;
}
bool FSGSenseGloveImpl::GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose)
ESGHapticGloveCalibrationState FSGSenseGloveImpl::GetCalibrationState() const
{
FSGHandPoseImpl::FHandPoseType HandPose;
const bool bResult = ToSenseGlovePtrChecked()->GetHandPose(HandProfile.ToHandProfile(), HandPose);
OutHandPose = FSGHandPoseImpl{MoveTemp(HandPose)};
return bResult;
return FSGCoreEnumCast::ToESGHapticGloveCalibrationState(ToSenseGlovePtrChecked()->GetCalibrationState());
}
bool FSGSenseGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand,
ESGSenseGloveThumperCommand ThumperCommand)
void FSGSenseGloveImpl::EndCalibration()
{
return ToSenseGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand(),
BuzzCommand.ToBuzzCommand(),
FSGCoreEnumCast::ToESenseGloveThumperCommand(ThumperCommand));
return ToSenseGlovePtrChecked()->EndCalibration();
}
bool FSGSenseGloveImpl::SendHaptics(ESGSenseGloveThumperCommand ThumperCommand)
void FSGSenseGloveImpl::ResetCalibration()
{
return ToSenseGlovePtrChecked()->SendHaptics(FSGCoreEnumCast::ToESenseGloveThumperCommand(ThumperCommand));
return ToSenseGlovePtrChecked()->EndCalibration();
}
void FSGSenseGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand)
void FSGSenseGloveImpl::StopHaptics()
{
ToSenseGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand());
ToSenseGlovePtrChecked()->StopHaptics();
}
void FSGSenseGloveImpl::SendHaptics(const FSGBuzzCommandImpl& BuzzCommand)
void FSGSenseGloveImpl::StopVibrations()
{
ToSenseGlovePtrChecked()->SendHaptics(BuzzCommand.ToBuzzCommand());
ToSenseGlovePtrChecked()->StopVibrations();
}
void FSGSenseGloveImpl::SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand, const FSGThumperCommandImpl& ThumperCommand)
bool FSGSenseGloveImpl::SendHaptics()
{
ToSenseGlovePtrChecked()->SendHaptics(ForceFeedbackCommand.ToForceFeedbackCommand(),
BuzzCommand.ToBuzzCommand(), ThumperCommand.ToThumperCommand());
return ToSenseGlovePtrChecked()->SendHaptics();
}
bool FSGSenseGloveImpl::GetCalibrationValues(TArray<FVector>& OutValues)
bool FSGSenseGloveImpl::QueueForceFeedbackLevels(const TArray<float>& Levels01)
{
std::vector<FSGVect3DImpl::FVect3DType> Values;
const bool bResult = ToSenseGlovePtrChecked()->GetCalibrationValues(Values);
OutValues = FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector,
FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(Values));
return bResult;
std::vector<float> Levels01Vector{FSGArrayUtils::ToStdVector(Levels01)};
return ToSenseGlovePtrChecked()->QueueForceFeedbackLevels(MoveTemp(Levels01Vector));
}
void FSGSenseGloveImpl::ResetCalibrationRange()
bool FSGSenseGloveImpl::QueueForceFeedbackLevel(const int32 Finger, const float Level01)
{
ToSenseGlovePtr()->ResetCalibrationRange();
}
void FSGSenseGloveImpl::ApplyCalibration(FSGHandProfileImpl& OutProfile) const
{
FSGHandProfileImpl::FHandProfileType Profile;
ToSenseGlovePtrChecked()->ApplyCalibration(Profile);
OutProfile = FSGHandProfileImpl{MoveTemp(Profile)};
}
void FSGSenseGloveImpl::ApplyCalibration(FSGSenseGloveHandProfileImpl& OutProfile) const
{
FSGSenseGloveHandProfileImpl::FSenseGloveHandProfileType Profile;
ToSenseGlovePtrChecked()->ApplyCalibration(Profile);
OutProfile = FSGSenseGloveHandProfileImpl{MoveTemp(Profile)};
return ToSenseGlovePtrChecked()->QueueForceFeedbackLevel(Finger, Level01);
}
void FSGSenseGloveImpl::GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -521,10 +475,11 @@ void FSGSenseGloveImpl::GetWristLocation(const FVector& ReferencePosition, const
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
void FSGSenseGloveImpl::GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset,
FVector& OutWristPosition, FQuat& OutWristRotation) const
void FSGSenseGloveImpl::GetWristLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
const ESGPositionalTrackingHardware TrackingHardware,
const FVector& GloveWristPositionOffset, const FQuat& GloveWristRotationOffset,
FVector& OutWristPosition, FQuat& OutWristRotation) const
{
FSGVect3DImpl::FVect3DType WristPosition;
FSGQuatImpl::FQuatType WristRotation;
@@ -542,12 +497,77 @@ void FSGSenseGloveImpl::GetWristLocation(const FVector& ReferencePosition, const
OutWristRotation = FSGQuatImpl{MoveTemp(WristRotation)}.ToFQuat();
}
FString FSGSenseGloveImpl::ToString() const
FSGSenseGloveInfoImpl FSGSenseGloveImpl::GetGloveInfo() const
{
const FString String{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->ToString().c_str())};
return String;
FSGSenseGloveInfoImpl GloveInfo{ToSenseGlovePtr()->GetGloveInfo()};
return MoveTemp(GloveInfo);
}
TArray<FVector> FSGSenseGloveImpl::GetFingerThimbleOffsets() const
{
TArray<FVector> Offsets{
FSGArrayUtils::FromStdVector<FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(
ToSenseGlovePtrChecked()->GetFingerThimbleOffsets())
};
return MoveTemp(Offsets);
}
void FSGSenseGloveImpl::SetFingerThimbleOffset(const int32 Finger, const FVector& Offset)
{
ToSenseGlovePtrChecked()->SetFingerThimbleOffset(Finger, FSGVect3DImpl{Offset}.ToVect3D());
}
bool FSGSenseGloveImpl::SupportsWristActuator() const
{
return ToSenseGlovePtrChecked()->SupportsWristActuator();
}
bool FSGSenseGloveImpl::GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const
{
FSGSenseGloveSensorDataImpl::FSenseGloveSensorDataType SensorData;
const bool bResult = ToSenseGlovePtrChecked()->GetSensorData(SensorData);
OutSensorData = FSGSenseGloveSensorDataImpl{MoveTemp(SensorData)};
return bResult;
}
bool FSGSenseGloveImpl::GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose) const
{
FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose;
const bool bResult = ToSenseGlovePtr()->GetGlovePose(GlovePose);
OutGlovePose = FSGSenseGlovePoseImpl{GlovePose};
return bResult;
}
bool FSGSenseGloveImpl::GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
FSGSenseGlovePoseImpl& OutGlovePose) const
{
FSGSenseGlovePoseImpl::FSenseGlovePoseType GlovePose;
const bool bResult = ToSenseGlovePtr()->GetGlovePose(SensorData.ToSenseGloveSensorData(), GlovePose);
OutGlovePose = FSGSenseGlovePoseImpl{GlovePose};
return bResult;
}
bool FSGSenseGloveImpl::QueueVibroLevels(const TArray<float>& Amplitudes)
{
std::vector<float> AmplitudesVector{FSGArrayUtils::ToStdVector(Amplitudes)};
return ToSenseGlovePtrChecked()->QueueVibroLevels(MoveTemp(AmplitudesVector));
}
bool FSGSenseGloveImpl::QueueVibroLevel(const int32 Finger, const float Amplitude)
{
return ToSenseGlovePtrChecked()->QueueVibroLevel(Finger, Amplitude);
}
bool FSGSenseGloveImpl::QueueThumperCommand(const ESGSenseGloveThumperCommand Command)
{
return ToSenseGlovePtrChecked()->QueueThumperCommand(FSGCoreEnumCast::ToESenseGloveThumperCommand(Command));
}
FString FSGSenseGloveImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(ToSenseGlovePtrChecked()->ToString().c_str())};
return MoveTemp(String);
}
FSGSenseGloveImpl::FImpl::FImpl(FSGSenseGloveImpl* InOwner)
: Owner(InOwner)
@@ -44,7 +44,6 @@
#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"
@@ -112,10 +111,12 @@ FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const bool bRightHanded, const TArr
FSGArrayUtils::ToSenseGloveAngles<FSGVect3DImpl::FVect3DType>(GloveAngles)
};
Pimpl->SenseGlovePose = FSenseGlovePoseType(bRightHanded,
MoveTemp(JointPositionsVector),
MoveTemp(JointRotationsVector),
MoveTemp(GloveAnglesVector));
Pimpl->SenseGlovePose = FSenseGlovePoseType{
bRightHanded,
MoveTemp(JointPositionsVector),
MoveTemp(JointRotationsVector),
MoveTemp(GloveAnglesVector)
};
}
FSGSenseGlovePoseImpl::FSGSenseGlovePoseImpl(const FSenseGlovePoseType& SenseGlovePose)
@@ -206,26 +207,16 @@ TArray<FVector> FSGSenseGlovePoseImpl::GetTotalGloveAngles() const
return MoveTemp(TotalGloveAngles);
}
TArray<FVector> FSGSenseGlovePoseImpl::CalculateFingerTips(
const FSGSenseGloveHandProfileImpl& SenseGloveHandProfileImpl) const
{
TArray<FVector> FingerTips{
FSGArrayUtils::FromMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
Pimpl->SenseGlovePose.CalculateFingerTips(SenseGloveHandProfileImpl.ToSenseGloveHandProfile()))
};
return MoveTemp(FingerTips);
}
TArray<FVector> FSGSenseGlovePoseImpl::CalculateFingerTips(const TArray<FVector>& FingerOffsets) const
TArray<FVector> FSGSenseGlovePoseImpl::CalculateFingertips(const TArray<FVector>& FingerOffsets) const
{
std::vector<FSGVect3DImpl::FVect3DType> FingerOffsetsVector{
FSGArrayUtils::ToMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(FingerOffsets)
};
TArray<FVector> FingerTips{
TArray<FVector> Fingertips{
FSGArrayUtils::FromMillimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
Pimpl->SenseGlovePose.CalculateFingerTips(MoveTemp(FingerOffsetsVector)))
Pimpl->SenseGlovePose.CalculateFingertips(MoveTemp(FingerOffsetsVector)))
};
return MoveTemp(FingerTips);
return MoveTemp(Fingertips);
}
bool FSGSenseGlovePoseImpl::Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) const
@@ -233,7 +224,7 @@ bool FSGSenseGlovePoseImpl::Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseIm
return Pimpl->SenseGlovePose.Equals(SenseGlovePoseImpl.ToSenseGlovePose());
}
FString FSGSenseGlovePoseImpl::ToString(bool bShortFormat) const
FString FSGSenseGlovePoseImpl::ToString(const bool bShortFormat) const
{
FString String(UTF8_TO_TCHAR(Pimpl->SenseGlovePose.ToString(bShortFormat).c_str()));
return MoveTemp(String);
@@ -0,0 +1,137 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGSenseGloveSensorNormalizerImpl.h"
#include "SGBuildHacks/SGInclude_Core_SenseGloveSensorNormalizer.h"
#include "SGCoreImpl/SGSenseGloveInfoImpl.h"
struct FSGSenseGloveSensorNormalizerImpl::FImpl
{
/************************
* Member variables
************************/
FSenseGloveSensorNormalizerType SenseGloveSensorNormalizer;
/************************
* Owner object
************************/
FSGSenseGloveSensorNormalizerImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGSenseGloveSensorNormalizerImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(const bool bRightHanded)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->SenseGloveSensorNormalizer = FSenseGloveSensorNormalizerType(bRightHanded);
}
FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(
const FSenseGloveSensorNormalizerType& SenseGloveSensorNormalizer)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->SenseGloveSensorNormalizer = SenseGloveSensorNormalizer;
}
FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(const FSGSenseGloveSensorNormalizerImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGSenseGloveSensorNormalizerImpl::FSGSenseGloveSensorNormalizerImpl(
FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT = default;
FSGSenseGloveSensorNormalizerImpl::~FSGSenseGloveSensorNormalizerImpl() = default;
FSGSenseGloveSensorNormalizerImpl& FSGSenseGloveSensorNormalizerImpl::operator=(
const FSGSenseGloveSensorNormalizerImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGSenseGloveSensorNormalizerImpl& FSGSenseGloveSensorNormalizerImpl::operator=(
FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT
= default;
const FSGSenseGloveSensorNormalizerImpl::FSenseGloveSensorNormalizerType&
FSGSenseGloveSensorNormalizerImpl::ToSenseGloveSensorNormalizer() const
{
return Pimpl->SenseGloveSensorNormalizer;
}
float FSGSenseGloveSensorNormalizerImpl::NormalizeFlexion(const int32 Finger, const float SumFlexionAngles) const
{
return Pimpl->SenseGloveSensorNormalizer.NormalizeFlexion(Finger, SumFlexionAngles);
}
float FSGSenseGloveSensorNormalizerImpl::NormalizeAbduction(const int32 Finger, const float SumAbductionAngles) const
{
return Pimpl->SenseGloveSensorNormalizer.NormalizeAbduction(Finger, SumAbductionAngles);
}
FSGSenseGloveSensorNormalizerImpl::FImpl::FImpl(FSGSenseGloveSensorNormalizerImpl* InOwner)
: Owner(InOwner)
{
}
FSGSenseGloveSensorNormalizerImpl::FImpl::~FImpl() = default;
void FSGSenseGloveSensorNormalizerImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,190 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGSensorNormalizationImpl.h"
#include <vector>
#include "SGBuildHacks/SGInclude_Core_SensorNormalization.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGSensorNormalizationImpl::FImpl
{
/************************
* Member variables
************************/
FSensorNormalizationType SensorNormalization;
/************************
* Owner object
************************/
FSGSensorNormalizationImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGSensorNormalizationImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGSensorNormalizationImpl::FSGSensorNormalizationImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(const TArray<float>& MovementRanges)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<float> MovementRangesVector{FSGArrayUtils::ToStdVector(MovementRanges)};
Pimpl->SensorNormalization = FSensorNormalizationType(MoveTemp(MovementRangesVector));
}
FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(
const FSensorNormalizationType& SensorNormalization)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->SensorNormalization = SensorNormalization;
}
FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(const FSGSensorNormalizationImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGSensorNormalizationImpl::FSGSensorNormalizationImpl(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT = default;
FSGSensorNormalizationImpl::~FSGSensorNormalizationImpl() = default;
FSGSensorNormalizationImpl& FSGSensorNormalizationImpl::operator=(const FSGSensorNormalizationImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGSensorNormalizationImpl& FSGSensorNormalizationImpl::operator=(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT = default;
const FSGSensorNormalizationImpl::FSensorNormalizationType& FSGSensorNormalizationImpl::ToSensorNormalization() const
{
return Pimpl->SensorNormalization;
}
FSGSensorNormalizationImpl::FSensorNormalizationType& FSGSensorNormalizationImpl::ToSensorNormalization()
{
return Pimpl->SensorNormalization;
}
bool FSGSensorNormalizationImpl::CollectsNormalization() const
{
return Pimpl->SensorNormalization.CollectsNormalization();
}
void FSGSensorNormalizationImpl::SetCollectNormalization(const bool bCollectNormalization)
{
Pimpl->SensorNormalization.SetCollectNormalization(bCollectNormalization);
}
int32 FSGSensorNormalizationImpl::GetLength() const
{
return Pimpl->SensorNormalization.GetLength();
}
int32 FSGSensorNormalizationImpl::GetMoveCount() const
{
return Pimpl->SensorNormalization.GetMoveCount();
}
bool FSGSensorNormalizationImpl::AllSensorsMoving() const
{
return Pimpl->SensorNormalization.AllSensorsMoving();
}
void FSGSensorNormalizationImpl::ResetNormalization()
{
Pimpl->SensorNormalization.ResetNormalization();
}
void FSGSensorNormalizationImpl::UpdateNormalization(const float Value, const int32 Index)
{
Pimpl->SensorNormalization.UpdateNormalization(Value, Index);
}
float FSGSensorNormalizationImpl::NormalizeValue(const float Value, const int32 Index)
{
return Pimpl->SensorNormalization.NormalizeValue(Value, Index);
}
TArray<float> FSGSensorNormalizationImpl::NormalizeValues(const TArray<float>& Values)
{
std::vector<float> ValuesVector{FSGArrayUtils::ToStdVector(Values)};
TArray<float> NormalizedValues{
FSGArrayUtils::FromStdVector(Pimpl->SensorNormalization.NormalizeValues(MoveTemp(ValuesVector)))
};
return MoveTemp(NormalizedValues);
}
bool FSGSensorNormalizationImpl::MovedEnough(const int32 Index) const
{
return Pimpl->SensorNormalization.MovedEnough(Index);
}
float FSGSensorNormalizationImpl::Denormalize(const float Value01, const int32 Index, const float FallbackValue) const
{
return Pimpl->SensorNormalization.Denormalize(Value01, Index, FallbackValue);
}
FSGSensorNormalizationImpl::FImpl::FImpl(FSGSensorNormalizationImpl* InOwner)
: Owner(InOwner)
{
}
FSGSensorNormalizationImpl::FImpl::~FImpl() = default;
void FSGSensorNormalizationImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -1,236 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGSensorRangeImpl.h"
#include <string>
#include <vector>
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_SensorRange.h"
#include "SGBuildHacks/SGInclude_Core_Vect3D.h"
#include "SGCoreImpl/SGVect3DImpl.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGSensorRangeImpl::FImpl
{
/************************
* Member variables
************************/
FSensorRangeType SensorRange;
/************************
* Owner object
************************/
FSGSensorRangeImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGSensorRangeImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
const FSGSensorRangeImpl& FSGSensorRangeImpl::ForCalibration()
{
static const FSGSensorRangeImpl SensorRange(FSensorRangeType::ForCalibration());
return SensorRange;
}
FSGSensorRangeImpl FSGSensorRangeImpl::Deserialize(const FString& SerializedString)
{
std::string Serialized(TCHAR_TO_UTF8(*SerializedString));
const FSGSensorRangeImpl SensorRange(FSensorRangeType::Deserialize(MoveTemp(Serialized)));
return SensorRange;
}
void FSGSensorRangeImpl::CheckMax(const FVector CurrentValues, FVector& OutMaxValues)
{
FSGVect3DImpl::FVect3DType Current(FSGVect3DImpl(CurrentValues).ToVect3D());
FSGVect3DImpl::FVect3DType MaxValues;
FSensorRangeType::CheckMax(MoveTemp(Current), MaxValues);
OutMaxValues = FSGVect3DImpl(MaxValues).ToFVector();
}
void FSGSensorRangeImpl::CheckMin(const FVector& CurrentValues, FVector& OutMinValues)
{
FSGVect3DImpl::FVect3DType Current(FSGVect3DImpl(CurrentValues).ToVect3D());
FSGVect3DImpl::FVect3DType MinValues;
FSensorRangeType::CheckMax(MoveTemp(Current), MinValues);
OutMinValues = FSGVect3DImpl(MinValues).ToFVector();
}
FSGSensorRangeImpl::FSGSensorRangeImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGSensorRangeImpl::FSGSensorRangeImpl(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
std::vector<FSGVect3DImpl::FVect3DType> MinValuesVector(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MinValues));
std::vector<FSGVect3DImpl::FVect3DType> MaxValuesVector(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
MaxValues));
Pimpl->SensorRange = FSensorRangeType(MoveTemp(MinValuesVector), MoveTemp(MaxValuesVector));
}
FSGSensorRangeImpl::FSGSensorRangeImpl(const FSensorRangeType& SensorRange)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->SensorRange = SensorRange;
}
FSGSensorRangeImpl::FSGSensorRangeImpl(const FSGSensorRangeImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGSensorRangeImpl::FSGSensorRangeImpl(FSGSensorRangeImpl&& Rhs) SG_NOEXCEPT = default;
FSGSensorRangeImpl::~FSGSensorRangeImpl() = default;
FSGSensorRangeImpl& FSGSensorRangeImpl::operator=(const FSGSensorRangeImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGSensorRangeImpl& FSGSensorRangeImpl::operator=(FSGSensorRangeImpl&& Rhs) SG_NOEXCEPT = default;
const FSGSensorRangeImpl::FSensorRangeType& FSGSensorRangeImpl::ToSensorRange() const
{
return Pimpl->SensorRange;
}
TArray<FVector> FSGSensorRangeImpl::GetMinValues() const
{
std::vector<FSGVect3DImpl::FVect3DType> Values(Pimpl->SensorRange.GetMinValues());
TArray<FVector> MinValues{FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(Values))};
return MinValues;
}
void FSGSensorRangeImpl::SetMinValues(const TArray<FVector>& Values)
{
std::vector<FSGVect3DImpl::FVect3DType> MinValues(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
Values));
Pimpl->SensorRange.SetMinValues(MoveTemp(MinValues));
}
TArray<FVector> FSGSensorRangeImpl::GetMaxValues() const
{
std::vector<FSGVect3DImpl::FVect3DType> Values(Pimpl->SensorRange.GetMaxValues());
TArray<FVector> MaxValues{FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(Values))};
return MaxValues;
}
void FSGSensorRangeImpl::SetMaxValues(const TArray<FVector>& Values)
{
std::vector<FSGVect3DImpl::FVect3DType> MaxValues(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
Values));
Pimpl->SensorRange.SetMaxValues(MoveTemp(MaxValues));
}
TArray<FVector> FSGSensorRangeImpl::GetRange() const
{
std::vector<FSGVect3DImpl::FVect3DType> RangeVector(Pimpl->SensorRange.GetRange());
TArray<FVector> Range{FSGArrayUtils::FromStdVector<
FSGVect3DImpl::FVect3DType, FVector, FSGVect3DImpl, &FSGVect3DImpl::ToFVector>(MoveTemp(RangeVector))};
return Range;
}
void FSGSensorRangeImpl::UpdateRange()
{
Pimpl->SensorRange.UpdateRange();
}
void FSGSensorRangeImpl::CheckForExtremes(const TArray<FVector>& OtherValues)
{
std::vector<FSGVect3DImpl::FVect3DType> Values(
FSGArrayUtils::ToStdVector<FVector, FSGVect3DImpl::FVect3DType, FSGVect3DImpl, &FSGVect3DImpl::ToVect3D>(
OtherValues));
Pimpl->SensorRange.CheckForExtremes(MoveTemp(Values));
}
FString FSGSensorRangeImpl::RangeString(const bool bYOnly) const
{
FString String(UTF8_TO_TCHAR(Pimpl->SensorRange.RangeString(bYOnly).c_str()));
return String;
}
FString FSGSensorRangeImpl::ToString(const bool bYOnly) const
{
FString String(UTF8_TO_TCHAR(Pimpl->SensorRange.ToString(bYOnly).c_str()));
return String;
}
FString FSGSensorRangeImpl::Serialize() const
{
FString Serialized(UTF8_TO_TCHAR(Pimpl->SensorRange.Serialize().c_str()));
return Serialized;
}
FSGSensorRangeImpl::FImpl::FImpl(FSGSensorRangeImpl* InOwner)
: Owner(InOwner)
{
}
FSGSensorRangeImpl::FImpl::~FImpl() = default;
void FSGSensorRangeImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,188 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGThresholdCommandImpl.h"
#include <vector>
#include "SGBuildHacks/SGInclude_Core_ThresholdCommand.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGThresholdCommandImpl::FImpl
{
/************************
* Member variables
************************/
FThresholdCommandType ThresholdCommand;
/************************
* Owner object
************************/
FSGThresholdCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGThresholdCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGThresholdCommandImpl::FSGThresholdCommandImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGThresholdCommandImpl::FSGThresholdCommandImpl(
const TArray<bool>& AffectedFingers, const TArray<float>& ThresholdValues)
{
std::vector<bool> AffectedFingersVector{FSGArrayUtils::ToStdVector(AffectedFingers)};
std::vector<float> ThresholdValuesVector{FSGArrayUtils::ToStdVector(ThresholdValues)};
Pimpl->ThresholdCommand = FThresholdCommandType{MoveTemp(AffectedFingersVector), MoveTemp(ThresholdValuesVector)};
}
FSGThresholdCommandImpl::FSGThresholdCommandImpl(
const FThresholdCommandType& ThresholdCommand)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->ThresholdCommand = ThresholdCommand;
}
FSGThresholdCommandImpl::FSGThresholdCommandImpl(const FSGThresholdCommandImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGThresholdCommandImpl::FSGThresholdCommandImpl(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGThresholdCommandImpl::~FSGThresholdCommandImpl() = default;
FSGThresholdCommandImpl& FSGThresholdCommandImpl::operator=(const FSGThresholdCommandImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGThresholdCommandImpl& FSGThresholdCommandImpl::operator=(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGThresholdCommandImpl::FThresholdCommandType& FSGThresholdCommandImpl::ToThresholdCommand() const
{
return Pimpl->ThresholdCommand;
}
FSGThresholdCommandImpl::FThresholdCommandType& FSGThresholdCommandImpl::ToThresholdCommand()
{
return Pimpl->ThresholdCommand;
}
float FSGThresholdCommandImpl::GetThreshold(int32 Finger) const
{
return Pimpl->ThresholdCommand.GetThreshold(Finger);
}
void FSGThresholdCommandImpl::SetThreshold(const int32 Finger, const float ThresholdValue)
{
Pimpl->ThresholdCommand.SetThreshold(Finger, ThresholdValue);
}
TArray<float> FSGThresholdCommandImpl::GetThresholds() const
{
TArray<float> Thresholds{FSGArrayUtils::FromStdVector(Pimpl->ThresholdCommand.GetThresholds())};
return MoveTemp(Thresholds);
}
void FSGThresholdCommandImpl::SetThresholds(const TArray<bool>& AffectedFingers, const TArray<float>& ThresholdValues)
{
std::vector<bool> AffectedFingersVector{FSGArrayUtils::ToStdVector(AffectedFingers)};
std::vector<float> ThresholdValuesVector{FSGArrayUtils::ToStdVector(ThresholdValues)};
Pimpl->ThresholdCommand.SetThresholds(MoveTemp(AffectedFingersVector), MoveTemp(ThresholdValuesVector));
}
bool FSGThresholdCommandImpl::GetFingerActive(const int32 Finger) const
{
return Pimpl->ThresholdCommand.GetFingerActive(Finger);
}
TArray<bool> FSGThresholdCommandImpl::GetActiveFingers() const
{
TArray<bool> ActiveFingers{FSGArrayUtils::FromStdVector(Pimpl->ThresholdCommand.GetActiveFingers())};
return MoveTemp(ActiveFingers);
}
void FSGThresholdCommandImpl::ClearThreshold(const int32 Finger)
{
Pimpl->ThresholdCommand.ClearThreshold(Finger);
}
void FSGThresholdCommandImpl::ClearThresholds()
{
Pimpl->ThresholdCommand.ClearThresholds();
}
bool FSGThresholdCommandImpl::Equals(const FSGThresholdCommandImpl& ThresholdCommand) const
{
return Pimpl->ThresholdCommand.Equals(ThresholdCommand.ToThresholdCommand());
}
FString FSGThresholdCommandImpl::ToString() const
{
FString String{UTF8_TO_TCHAR(Pimpl->ThresholdCommand.ToString().c_str())};
return MoveTemp(String);
}
FSGThresholdCommandImpl::FImpl::FImpl(FSGThresholdCommandImpl* InOwner)
: Owner(InOwner)
{
}
FSGThresholdCommandImpl::FImpl::~FImpl() = default;
void FSGThresholdCommandImpl::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -1,154 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGThumperCommandImpl.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_ThumperCommand.h"
struct FSGThumperCommandImpl::FImpl
{
/************************
* Member variables
************************/
FThumperCommandType ThumperCommand;
/************************
* Owner object
************************/
FSGThumperCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGThumperCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
const FSGThumperCommandImpl& FSGThumperCommandImpl::Off()
{
static const FSGThumperCommandImpl OffCmd(0);
return OffCmd;
}
FSGThumperCommandImpl::FSGThumperCommandImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGThumperCommandImpl::FSGThumperCommandImpl(const int32 Magnitude)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->ThumperCommand = FThumperCommandType(Magnitude);
}
FSGThumperCommandImpl::FSGThumperCommandImpl(const FThumperCommandType& ThumperCommand)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->ThumperCommand = ThumperCommand;
}
FSGThumperCommandImpl::FSGThumperCommandImpl(const FSGThumperCommandImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGThumperCommandImpl::FSGThumperCommandImpl(FSGThumperCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGThumperCommandImpl::~FSGThumperCommandImpl() = default;
FSGThumperCommandImpl& FSGThumperCommandImpl::operator=(const FSGThumperCommandImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGThumperCommandImpl& FSGThumperCommandImpl::operator=(FSGThumperCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGThumperCommandImpl::FThumperCommandType& FSGThumperCommandImpl::ToThumperCommand() const
{
return Pimpl->ThumperCommand;
}
int32 FSGThumperCommandImpl::GetMagnitude() const
{
return Pimpl->ThumperCommand.GetMagnitude();
}
void FSGThumperCommandImpl::SetMagnitude(const int32 Magnitude)
{
Pimpl->ThumperCommand.SetMagnitude(Magnitude);
}
FSGThumperCommandImpl FSGThumperCommandImpl::Copy() const
{
return FSGThumperCommandImpl(Pimpl->ThumperCommand.Copy());
}
FSGThumperCommandImpl FSGThumperCommandImpl::Merge(const FSGThumperCommandImpl& ThumperCommandImpl) const
{
return FSGThumperCommandImpl(Pimpl->ThumperCommand.Merge(ThumperCommandImpl.ToThumperCommand()));
}
bool FSGThumperCommandImpl::Equals(const FSGThumperCommandImpl& ThumperCommandImpl) const
{
return Pimpl->ThumperCommand.Equals(ThumperCommandImpl.ToThumperCommand());
}
FSGThumperCommandImpl::FImpl::FImpl(FSGThumperCommandImpl* InOwner)
: ThumperCommand(0),
Owner(InOwner)
{
}
FSGThumperCommandImpl::FImpl::~FImpl() = default;
void FSGThumperCommandImpl::FImplDeleter::operator()(const FSGThumperCommandImpl::FImpl* P) const
{
delete P;
}
@@ -1,205 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGTimedBuzzCommandImpl.h"
#include "SGBuildHacks/SGInclude_Core_TimedBuzzCommand.h"
#include "SGCoreImpl/SGCoreEnumCast.h"
#include "SGUtils/SGArrayUtils.h"
struct FSGTimedBuzzCommandImpl::FImpl
{
/************************
* Member variables
************************/
/************************
* Owner object
************************/
FSGTimedBuzzCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGTimedBuzzCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl()
: FSGBuzzCommandImpl(MakeShared<FTimedBuzzCommandType>()),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(const ESGFinger Finger, const int32 Magnitude,
const float DurationSeconds, const float StartTimeSeconds)
: FSGBuzzCommandImpl(MakeShared<FTimedBuzzCommandType>(FSGCoreEnumCast::ToEFinger(Finger), Magnitude,
DurationSeconds, StartTimeSeconds)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(const FSGBuzzCommandImpl& BaseCommand,
const float DurationSeconds, const float StartTimeSeconds)
: FSGBuzzCommandImpl(MakeShared<FTimedBuzzCommandType>(
BaseCommand.ToBuzzCommand(), DurationSeconds, StartTimeSeconds)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(const FTimedBuzzCommandType& TimedBuzzCommand)
: FSGBuzzCommandImpl(MakeShared<FTimedBuzzCommandType>(TimedBuzzCommand)),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(const TSharedRef<FTimedBuzzCommandType> TimedBuzzCommand)
: FSGBuzzCommandImpl(TimedBuzzCommand),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(const FSGTimedBuzzCommandImpl& Rhs)
: FSGBuzzCommandImpl(Rhs),
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGTimedBuzzCommandImpl::FSGTimedBuzzCommandImpl(FSGTimedBuzzCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGTimedBuzzCommandImpl::~FSGTimedBuzzCommandImpl() = default;
FSGTimedBuzzCommandImpl& FSGTimedBuzzCommandImpl::operator=(const FSGTimedBuzzCommandImpl& Rhs)
{
FSGBuzzCommandImpl::operator=(Rhs);
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGTimedBuzzCommandImpl& FSGTimedBuzzCommandImpl::operator=(FSGTimedBuzzCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGTimedBuzzCommandImpl::FTimedBuzzCommandType& FSGTimedBuzzCommandImpl::ToTimedBuzzCommand() const
{
return *StaticCastSharedRef<FTimedBuzzCommandType>(ToBuzzCommandRef());
}
TSharedRef<FSGTimedBuzzCommandImpl::FTimedBuzzCommandType> FSGTimedBuzzCommandImpl::ToTimedBuzzCommandRef() const
{
return StaticCastSharedRef<FTimedBuzzCommandType>(ToBuzzCommandRef());
}
FSGTimedBuzzCommandImpl::FTimedBuzzCommandType& FSGTimedBuzzCommandImpl::ToTimedBuzzCommand()
{
return *StaticCastSharedRef<FTimedBuzzCommandType>(ToBuzzCommandRef());
}
TSharedRef<FSGTimedBuzzCommandImpl::FTimedBuzzCommandType> FSGTimedBuzzCommandImpl::ToTimedBuzzCommandRef()
{
return StaticCastSharedRef<FTimedBuzzCommandType>(ToBuzzCommandRef());
}
FSGBuzzCommandImpl FSGTimedBuzzCommandImpl::Copy() const
{
return FSGBuzzCommandImpl{ToTimedBuzzCommandRef()->Copy()};
}
FSGBuzzCommandImpl FSGTimedBuzzCommandImpl::Merge(const FSGBuzzCommandImpl& BuzzCommand) const
{
return FSGBuzzCommandImpl{ToTimedBuzzCommandRef()->Merge(BuzzCommand.ToBuzzCommand())};
}
FSGBuzzCommandImpl FSGTimedBuzzCommandImpl::GetBaseCommand() const
{
return FSGBuzzCommandImpl{MakeShared<FBuzzCommandType>(ToTimedBuzzCommandRef()->GetBaseCommand())};
}
float FSGTimedBuzzCommandImpl::GetDuration() const
{
return ToTimedBuzzCommandRef()->GetDuration();
}
float FSGTimedBuzzCommandImpl::GetElapsedTime() const
{
return ToTimedBuzzCommandRef()->GetElapsedTime();
}
bool FSGTimedBuzzCommandImpl::HasTimeElapsed() const
{
return ToTimedBuzzCommandRef()->HasTimeElapsed();
}
float FSGTimedBuzzCommandImpl::NormalizedTime(const bool bClamp01) const
{
return ToTimedBuzzCommandRef()->NormalizedTime(bClamp01);
}
void FSGTimedBuzzCommandImpl::ResetTiming()
{
ToTimedBuzzCommandRef()->ResetTiming();
}
void FSGTimedBuzzCommandImpl::UpdateTiming(const float DeltaSeconds)
{
ToTimedBuzzCommandRef()->UpdateTiming(DeltaSeconds);
}
FString FSGTimedBuzzCommandImpl::ToString() const
{
return UTF8_TO_TCHAR(ToTimedBuzzCommandRef()->ToString().c_str());
}
FSGTimedBuzzCommandImpl::FImpl::FImpl(FSGTimedBuzzCommandImpl* InOwner)
: Owner(InOwner)
{
}
FSGTimedBuzzCommandImpl::FImpl::~FImpl() = default;
void FSGTimedBuzzCommandImpl::FImplDeleter::operator()(const FSGTimedBuzzCommandImpl::FImpl* P) const
{
delete P;
}
@@ -1,174 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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/SGTimedThumpCommandImpl.h"
#include "Containers/StringConv.h"
#include "Runtime/Launch/Resources/Version.h"
#include "SGBuildHacks/SGInclude_Core_TimedThumpCommand.h"
#include "SGCoreImpl/SGThumperCommandImpl.h"
struct FSGTimedThumpCommandImpl::FImpl
{
/************************
* Member variables
************************/
FTimedThumpCommandType TimedThumpCommand;
/************************
* Owner object
************************/
FSGTimedThumpCommandImpl* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(FSGTimedThumpCommandImpl* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
};
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl()
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
}
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl(const int32 Magnitude,
const float DurationSeconds, const float StartTimeSeconds)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->TimedThumpCommand = FTimedThumpCommandType(Magnitude, DurationSeconds, StartTimeSeconds);
}
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl(const FSGThumperCommandImpl& BaseCommand,
const float DurationSeconds, const float StartTimeSeconds)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->TimedThumpCommand = FTimedThumpCommandType(BaseCommand.ToThumperCommand(), DurationSeconds,
StartTimeSeconds);
}
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl(const FTimedThumpCommandType& SGTimedThumpCommand)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
{
Pimpl->TimedThumpCommand = SGTimedThumpCommand;
}
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl(const FSGTimedThumpCommandImpl& Rhs)
: Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
{
Pimpl->Owner = this;
}
FSGTimedThumpCommandImpl::FSGTimedThumpCommandImpl(FSGTimedThumpCommandImpl&& Rhs) SG_NOEXCEPT = default;
FSGTimedThumpCommandImpl::~FSGTimedThumpCommandImpl() = default;
FSGTimedThumpCommandImpl& FSGTimedThumpCommandImpl::operator=(const FSGTimedThumpCommandImpl& Rhs)
{
*Pimpl = *Rhs.Pimpl;
Pimpl->Owner = this;
return *this;
}
FSGTimedThumpCommandImpl& FSGTimedThumpCommandImpl::operator=(FSGTimedThumpCommandImpl&& Rhs) SG_NOEXCEPT = default;
const FSGTimedThumpCommandImpl::FTimedThumpCommandType& FSGTimedThumpCommandImpl::ToTimedThumpCommand() const
{
return Pimpl->TimedThumpCommand;
}
int32 FSGTimedThumpCommandImpl::GetMagnitude() const
{
return Pimpl->TimedThumpCommand.GetMagnitude();
}
float FSGTimedThumpCommandImpl::GetDuration() const
{
return Pimpl->TimedThumpCommand.GetDuration();
}
float FSGTimedThumpCommandImpl::GetElapsedTime() const
{
return Pimpl->TimedThumpCommand.GetElapsedTime();
}
bool FSGTimedThumpCommandImpl::HasTimeElapsed() const
{
return Pimpl->TimedThumpCommand.HasTimeElapsed();
}
FSGTimedThumpCommandImpl FSGTimedThumpCommandImpl::Copy(const bool bCopyElapsed) const
{
return FSGTimedThumpCommandImpl(Pimpl->TimedThumpCommand.Copy(bCopyElapsed));
}
void FSGTimedThumpCommandImpl::Update(const float DeltaSeconds)
{
Pimpl->TimedThumpCommand.Update(DeltaSeconds);
}
bool FSGTimedThumpCommandImpl::Equals(const FSGThumperCommandImpl& SGThumperCommandImpl) const
{
return Pimpl->TimedThumpCommand.Equals(SGThumperCommandImpl.ToThumperCommand());
}
FString FSGTimedThumpCommandImpl::ToString() const
{
return UTF8_TO_TCHAR(Pimpl->TimedThumpCommand.ToString().c_str());
}
FSGTimedThumpCommandImpl::FImpl::FImpl(FSGTimedThumpCommandImpl* InOwner)
: TimedThumpCommand(),
Owner(InOwner)
{
}
FSGTimedThumpCommandImpl::FImpl::~FImpl() = default;
void FSGTimedThumpCommandImpl::FImplDeleter::operator()(const FSGTimedThumpCommandImpl::FImpl* P) const
{
delete P;
}
@@ -66,8 +66,9 @@ void FSGTrackingImpl::CalculateLocation(const FVector& TrackedPosition, const FQ
NewPosition,
NewRotation);
OutNewPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(NewPosition);
OutNewRotation = FSGQuatImpl(NewRotation).ToFQuat();
OutNewPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(NewPosition));
OutNewRotation = FSGQuatImpl(MoveTemp(NewRotation)).ToFQuat();
}
const TArray<FVector>& FSGTrackingImpl::GetSenseGloveFingerToGlovePositionOrigin()
@@ -112,8 +113,9 @@ void FSGTrackingImpl::GetSenseGloveMountOffset(const bool bRightHanded, const ES
FTrackingType::GetSenseGloveMountOffset(bRightHanded, FSGCoreEnumCast::ToEFinger(ToFinger),
IPosition, IRotation);
OutIPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(IPosition);
OutIRotation = FSGQuatImpl(IRotation).ToFQuat();
OutIPosition = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(IPosition));
OutIRotation = FSGQuatImpl(MoveTemp(IRotation)).ToFQuat();
}
void FSGTrackingImpl::GetSenseGloveTrackerMountOffset(const ESGPositionalTrackingHardware Hardware,
@@ -126,8 +128,9 @@ void FSGTrackingImpl::GetSenseGloveTrackerMountOffset(const ESGPositionalTrackin
FTrackingType::GetSenseGloveTrackerMountOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware),
bRightHanded, PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(PositionOffset);
OutRotationOffset = FSGQuatImpl(RotationOffset).ToFQuat();
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(PositionOffset));
OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat();
}
const FVector& FSGTrackingImpl::GetSenseGloveViveToAttachPosition()
@@ -175,18 +178,6 @@ const FQuat& FSGTrackingImpl::GetNovaToWristRotationOffset()
return Offset;
}
void FSGTrackingImpl::GetNovaGloveWristOffset(const bool bRightHanded,
FVector& OutPositionOffset, FQuat& OutRotationOffset)
{
FSGVect3DImpl::FVect3DType PositionOffset;
FSGQuatImpl::FQuatType RotationOffset;
FTrackingType::GetNovaGloveWristOffset(bRightHanded, PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(PositionOffset);
OutRotationOffset = FSGQuatImpl(RotationOffset).ToFQuat();
}
const FVector& FSGTrackingImpl::GetRightNovaViveToAttachPosition()
{
static const FVector Position{
@@ -268,6 +259,79 @@ const FQuat& FSGTrackingImpl::GetLeftNovaPico2ToAttachRotation()
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNovaQuestProToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNovaQuestProToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNovaQuestProToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaQuestProToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNovaQuestProToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNovaQuestProToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNovaQuestProToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaQuestProToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNovaViveFocus3ToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNovaViveFocus3ToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNovaViveFocus3ToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNovaViveFocus3ToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNovaViveFocus3ToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNovaViveFocus3ToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNovaViveFocus3ToAttachRotation()).ToFQuat());
return Rotation;
}
void FSGTrackingImpl::GetNovaGloveWristOffset(const bool bRightHanded,
FVector& OutPositionOffset, FQuat& OutRotationOffset)
{
FSGVect3DImpl::FVect3DType PositionOffset;
FSGQuatImpl::FQuatType RotationOffset;
FTrackingType::GetNovaGloveWristOffset(bRightHanded, PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(PositionOffset));
OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat();
}
void FSGTrackingImpl::GetNovaGloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded,
FVector& OutPositionOffset, FQuat& OutRotationOffset)
{
@@ -277,8 +341,189 @@ void FSGTrackingImpl::GetNovaGloveTrackerOffset(const ESGPositionalTrackingHardw
FTrackingType::GetNovaGloveTrackerOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware), bRightHanded,
PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(PositionOffset);
OutRotationOffset = FSGQuatImpl(RotationOffset).ToFQuat();
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(PositionOffset));
OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat();
}
const FVector& FSGTrackingImpl::GetRightNova2ToWristPositionOffset()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNova2ToWristPositionOffset())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNova2ToWristRotationOffset()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ToWristRotationOffset()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNova2ToWristPositionOffset()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNova2ToWristPositionOffset())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNova2ToWristRotationOffset()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ToWristRotationOffset()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNova2Quest2ToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNova2Quest2ToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNova2Quest2ToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2Quest2ToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNova2Quest2ToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNova2Quest2ToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNova2Quest2ToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2Quest2ToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNova2QuestProToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNova2QuestProToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNova2QuestProToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2QuestProToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNova2QuestProToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNova2QuestProToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNova2QuestProToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2QuestProToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNova2ViveTrackerToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNova2ViveTrackerToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNova2ViveTrackerToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ViveTrackerToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNova2ViveTrackerToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNova2ViveTrackerToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ViveTrackerToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetRightNova2ViveWristTrackerToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetRightNova2ViveWristTrackerToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetRightNova2ViveWristTrackerToAttachRotation()).ToFQuat());
return Rotation;
}
const FVector& FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachPosition()
{
static FVector Position{
FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
FTrackingType::GetLeftNova2ViveWristTrackerToAttachPosition())
};
return Position;
}
const FQuat& FSGTrackingImpl::GetLeftNova2ViveWristTrackerToAttachRotation()
{
static FQuat Rotation(FSGQuatImpl(FTrackingType::GetLeftNova2ViveWristTrackerToAttachRotation()).ToFQuat());
return Rotation;
}
void FSGTrackingImpl::GetNova2GloveWristOffset(const bool bRightHanded, const FString& HardwareVersion,
FVector& OutPositionOffset, FQuat& OutRotationOffset)
{
FSGVect3DImpl::FVect3DType PositionOffset;
FSGQuatImpl::FQuatType RotationOffset;
FTrackingType::GetNova2GloveWristOffset(bRightHanded, TCHAR_TO_UTF8(*HardwareVersion),
PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(PositionOffset));
OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat();
}
void FSGTrackingImpl::GetNova2GloveTrackerOffset(const ESGPositionalTrackingHardware Hardware, const bool bRightHanded,
const FString& HardwareVersion,
FVector& OutPositionOffset, FQuat& OutRotationOffset)
{
FSGVect3DImpl::FVect3DType PositionOffset;
FSGQuatImpl::FQuatType RotationOffset;
FTrackingType::GetNova2GloveTrackerOffset(FSGCoreEnumCast::ToEPositionalTrackingHardware(Hardware), bRightHanded,
TCHAR_TO_UTF8(*HardwareVersion),
PositionOffset, RotationOffset);
OutPositionOffset = FSGUnits::MillimetersToCentimeters<FSGVect3DImpl::FVect3DType, FSGVect3DImpl>(
MoveTemp(PositionOffset));
OutRotationOffset = FSGQuatImpl(MoveTemp(RotationOffset)).ToFQuat();
}
FString FSGTrackingImpl::ToString(const ESGPositionalTrackingHardware Hardware)
@@ -207,9 +207,9 @@ float FSGVect3DImpl::Magnitude() const
return Pimpl->Vect3D.Magnitude();
}
void FSGVect3DImpl::Normalize()
void FSGVect3DImpl::Normalized()
{
Pimpl->Vect3D.Normalize();
Pimpl->Vect3D.Normalized();
}
void FSGVect3DImpl::Scale(const float Factor)
@@ -193,7 +193,7 @@ public:
/**
* Returns this vector normalized to have a Magnitude on 1.
*/
void Normalize();
void Normalized();
/**
* Scale all elements of this vector by a certain factor.
@@ -64,6 +64,8 @@ public:
static float GetThumbJointLimit(bool bRightHanded, int32 Joint, int32 Movement, bool bMax);
static float ClampJointAngle(float Value, int32 Finger, bool bRightHand, int32 Joint, int32 Movement);
static float NormalizeFingerFlexion(float FlexionInDegrees);
static float NormalizeThumbFlexion(float FlexionInDegrees);
@@ -160,7 +160,7 @@ public:
FString GetLastCommand() const;
public:
bool SendHaptics(const FString& Command) const;
bool SendHaptics(const FString& Command, int32 Channel = 0) const;
public:
virtual FString ToString() const override;
@@ -1,148 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "HAL/Platform.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCoreImpl/SGFingerCommandImpl.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Haptics
{
class BuzzCommand;
}
}
class SENSEGLOVECOREIMPL_API FSGBuzzCommandImpl : public FSGFingerCommandImpl
{
public:
typedef SGCore::Haptics::BuzzCommand FBuzzCommandType;
public:
static const FSGBuzzCommandImpl& Off();
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGBuzzCommandImpl();
public:
explicit FSGBuzzCommandImpl(const TArray<int32>& BuzzLevels);
FSGBuzzCommandImpl(int32 Thumb, int32 Index, int32 Middle, int32 Ring, int32 Pinky);
FSGBuzzCommandImpl(ESGFinger Finger, int32 BuzzLevel);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGBuzzCommandImpl(const FBuzzCommandType& BuzzCommand);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGBuzzCommandImpl(TSharedRef<FBuzzCommandType> BuzzCommand);
public:
/**
* The copy constructor.
*/
FSGBuzzCommandImpl(const FSGBuzzCommandImpl& Rhs);
/**
* The move constructor
*/
FSGBuzzCommandImpl(FSGBuzzCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGBuzzCommandImpl() override;
public:
/**
* The copy assignment operator.
*/
FSGBuzzCommandImpl& operator=(const FSGBuzzCommandImpl& Rhs);
/**
* The move assignment operator.
*/
FSGBuzzCommandImpl& operator=(FSGBuzzCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FBuzzCommandType& ToBuzzCommand() const;
/**
* The cast to underlying pointer type method.
*/
TSharedRef<FBuzzCommandType> ToBuzzCommandRef() const;
protected:
/**
* The non-const cast to underlying type method.
*/
FBuzzCommandType& ToBuzzCommand();
/**
* The non-const cast to underlying pointer type method.
*/
TSharedRef<FBuzzCommandType> ToBuzzCommandRef();
public:
virtual FSGBuzzCommandImpl Copy() const;
virtual FSGBuzzCommandImpl Merge(const FSGBuzzCommandImpl& Command) const;
};
@@ -36,46 +36,22 @@
#pragma once
#include "Containers/UnrealString.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
class FSGHandInterpolatorImpl;
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
class HandProfile;
class CustomWaveform;
}
class FSGNovaGloveHandProfileImpl;
class FSGSenseGloveHandProfileImpl;
class SENSEGLOVECOREIMPL_API FSGHandProfileImpl final
class SENSEGLOVECOREIMPL_API FSGCustomWaveformImpl final
{
public:
typedef SGCore::HandProfile FHandProfileType;
typedef SGCore::CustomWaveform FCustomWaveformType;
public:
static FSGHandProfileImpl Default(bool bRightHanded);
static FSGHandProfileImpl Deserialize(const FString& SerializedString);
public:
static const FString& GetProfileDirectory();
static const FString& GetLeftHandFileName();
static const FString& GetRightHandFileName();
static const FString& GetProfileFileName(bool bRightHanded);
static bool GetLatestProfile(bool bRightHanded, FSGHandProfileImpl& OutLatestProfile);
static bool StoreProfile(const FSGHandProfileImpl& ProfileToStore);
static bool ResetCalibration(bool bRightHanded, bool bOnDisk = true);
static void ResetCalibration(bool bOnDisk = true);
static FString ToString(ESGWaveformType Type);
private:
struct FImpl;
@@ -89,64 +65,100 @@ private:
FImplDeleter PimplDeleter;
public:
FSGHandProfileImpl();
FSGCustomWaveformImpl();
FSGHandProfileImpl(bool bRightHanded,
const FSGSenseGloveHandProfileImpl& SenseGloveHandProfile,
const FSGNovaGloveHandProfileImpl& NovaGloveHandProfile);
FSGCustomWaveformImpl(float Amplitude, float Duration);
FSGCustomWaveformImpl(float Amplitude, float Duration, float Frequency);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGHandProfileImpl(const FHandProfileType& SenseGloveHandProfile);
explicit FSGCustomWaveformImpl(const FCustomWaveformType& CustomWaveform);
public:
/**
* The copy constructor.
*/
FSGHandProfileImpl(const FSGHandProfileImpl& Rhs);
FSGCustomWaveformImpl(const FSGCustomWaveformImpl& Rhs);
/**
* The move constructor.
*/
FSGHandProfileImpl(FSGHandProfileImpl&& Rhs) SG_NOEXCEPT;
FSGCustomWaveformImpl(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGHandProfileImpl();
virtual ~FSGCustomWaveformImpl();
public:
/**
* The copy assignment operator.
*/
FSGHandProfileImpl& operator=(const FSGHandProfileImpl& Rhs);
FSGCustomWaveformImpl& operator=(const FSGCustomWaveformImpl& Rhs);
/**
* The move assignment operator.
*/
FSGHandProfileImpl& operator=(FSGHandProfileImpl&& Rhs) SG_NOEXCEPT;
FSGCustomWaveformImpl& operator=(FSGCustomWaveformImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FHandProfileType& ToHandProfile() const;
const FCustomWaveformType& ToCustomWaveform() const;
/**
* The cast to underlying type method.
*/
FCustomWaveformType& ToCustomWaveform();
public:
bool IsRight() const;
float GetAmplitude() const;
void SetAmplitude(float Amplitude);
FSGSenseGloveHandProfileImpl GetSenseGloveHandProfile() const;
ESGWaveformType GetWaveType() const;
void SetWaveType(ESGWaveformType Type);
FSGNovaGloveHandProfileImpl GetNovaGloveHandProfile() const;
bool IsInfinite() const;
void SetInfinite(bool bInfinite);
int32 GetRepeatAmount() const;
void SetRepeatAmount(int32 Amount);
float GetAttackTime() const;
void SetAttackTime(float Time);
float GetSustainTime() const;
void SetSustainTime(float Time);
float GetDecayTime() const;
void SetDecayTime(float Time);
float GetFrequencyStart() const;
void SetFrequencyStart(float Frequency);
float GetFrequencyEnd() const;
void SetFrequencyEnd(float Frequency);
float GetFrequencySwitchTime() const;
void SetFrequencySwitchTime(float Time);
float GetFrequencySwitchFactor() const;
void SetFrequencySwitchFactor(float Factor);
public:
bool Equals(const FSGHandProfileImpl& HandProfileImpl) const;
float GetEffectTime() const;
float GetTotalEffectTime() const;
void Reset();
bool FrequencyJumps() const;
public:
FString Serialize() const;
bool Equals(const FSGCustomWaveformImpl& CustomWaveformImpl) const;
public:
FString ToString() const;
};
@@ -50,7 +50,9 @@ namespace SGCore
}
class FSGBetaDeviceImpl;
class FSGHapticChannelInfoImpl;
class FSGHapticGloveImpl;
class FSGNova2GloveImpl;
class FSGNovaGloveImpl;
class FSGSenseGloveImpl;
@@ -65,6 +67,13 @@ public:
public:
static void ParseFirmware(const FString& RawFirmware, int32& OutMainVersion, int32& OutSubVersion);
static bool FirmwareNewerThan(int32 MyFirmwareMain, int32 MyFirmwareSub,
int32 ReferenceMain, int32 ReferenceSub,
bool bInclusive);
static bool FirmwareOlderThan(int32 MyFirmwareMain, int32 MyFirmwareSub,
int32 ReferenceMain, int32 ReferenceSub,
bool bInclusive);
static FString ToString(ESGDeviceType DeviceType);
private:
@@ -142,6 +151,11 @@ public:
*/
TSharedRef<FSGHapticGloveImpl> ToHapticGloveImplRef();
/**
* The cast to derived TSharedRef<FSGNova2GloveImpl> type method.
*/
TSharedRef<FSGNova2GloveImpl> ToNova2GloveImplRef();
/**
* The cast to derived TSharedRef<FSGNovaGloveImpl> type method.
*/
@@ -162,6 +176,9 @@ public:
virtual int32 GetSubFirmwareVersion() const;
virtual FString GetFirmwareString() const;
bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
FString GetAddress() const;
bool IsConnected() const;
@@ -171,7 +188,7 @@ public:
int32 PacketsPerSecondSent() const;
int32 GetDeviceIndex() const;
void SetDeviceIndex(int32 NewIndex);
virtual void SetDeviceIndex(int32 NewIndex);
virtual bool IsWireless() const;
@@ -179,5 +196,12 @@ public:
virtual bool IsCharging();
virtual bool GetBatteryLevel(float& OutLevel);
public:
virtual void SetHapticChannels(const FSGHapticChannelInfoImpl& Channels);
int32 GetHapticChannelCount() const;
int32 GetHapticChannelCount(ESGHapticChannelType ChannelType) const;
public:
virtual FString ToString() const;
};
@@ -83,7 +83,7 @@ public:
static bool GetSensorDataString(int32 IpcIndex, const FString& IpcAddress, FString& OutString);
static bool SendHaptics(int32 IpcIndex, const FString& IpcAddress, const FString& Commands);
static bool SendHaptics(int32 IpcIndex, const FString& IpcAddress, int32 ChannelIndex, const FString& Commands);
static FString GetDeviceStringAt(int32 IpcIndex, const FString& IpcAddress, int32 Index);
@@ -120,4 +120,8 @@ public:
int32 GetFirmwareVersion() const;
int32 GetSubFirmwareVersion() const;
public:
bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
};
File diff suppressed because it is too large Load Diff
@@ -1,169 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
namespace SGCore
{
namespace Haptics
{
class FingerCommand;
}
}
class FSGBuzzCommandImpl;
class FSGForceFeedbackCommandImpl;
class FSGTimedBuzzCommandImpl;
class SENSEGLOVECOREIMPL_API FSGFingerCommandImpl : public TSharedFromThis<FSGFingerCommandImpl>
{
public:
typedef SGCore::Haptics::FingerCommand FFingerCommandType;
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGFingerCommandImpl();
explicit FSGFingerCommandImpl(const TArray<int32>& Levels);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGFingerCommandImpl(const FFingerCommandType& FingerCommand);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGFingerCommandImpl(TSharedRef<FFingerCommandType> FingerCommand);
public:
/**
* The copy constructor.
*/
FSGFingerCommandImpl(const FSGFingerCommandImpl& Rhs);
/**
* The move constructor
*/
FSGFingerCommandImpl(FSGFingerCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGFingerCommandImpl();
public:
/**
* The copy assignment operator.
*/
FSGFingerCommandImpl& operator=(const FSGFingerCommandImpl& Rhs);
/**
* The move assignment operator.
*/
FSGFingerCommandImpl& operator=(FSGFingerCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FFingerCommandType& ToFingerCommand() const;
/**
* The cast to underlying type method.
*/
TSharedRef<FFingerCommandType> ToFingerCommandRef() const;
protected:
/**
* The non-const cast to underlying type method.
*/
FFingerCommandType& ToFingerCommand();
/**
* The non-const cast to underlying type method.
*/
TSharedRef<FFingerCommandType> ToFingerCommandRef();
public:
/**
* The cast to base TSharedRef<FSGFingerCommandImpl> type method.
*/
TSharedRef<FSGFingerCommandImpl> ToFingerCommandImplRef();
/**
* The cast to derived TSharedRef<FSGBuzzCommandImpl> type method.
*/
TSharedRef<FSGBuzzCommandImpl> ToBuzzCommandImplRef();
/**
* The cast to derived TSharedRef<FSGForceFeedbackCommandImpl> type method.
*/
TSharedRef<FSGForceFeedbackCommandImpl> ToForceFeedbackCommandImplRef();
/**
* The cast to derived TSharedRef<FSGTimedBuzzCommandImpl> type method.
*/
TSharedRef<FSGTimedBuzzCommandImpl> ToTimedBuzzCommandImplRef();
public:
virtual TArray<int32> GetLevels() const;
virtual int32 GetLevel(int32 Finger) const;
virtual void SetLevel(int32 Finger, int32 Value);
virtual bool Equals(const FSGFingerCommandImpl& FingerCommandImpl) const;
virtual FString ToString() const;
};
@@ -1,137 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "HAL/Platform.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCoreImpl/SGFingerCommandImpl.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Haptics
{
class ForceFeedbackCommand;
}
}
class SENSEGLOVECOREIMPL_API FSGForceFeedbackCommandImpl final : public FSGFingerCommandImpl
{
public:
typedef SGCore::Haptics::ForceFeedbackCommand FForceFeedbackCommandType;
public:
static const FSGForceFeedbackCommandImpl& Off();
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGForceFeedbackCommandImpl();
public:
explicit FSGForceFeedbackCommandImpl(const TArray<int32>& ForceFeedbackLevels);
FSGForceFeedbackCommandImpl(int32 Thumb, int32 Index, int32 Middle, int32 Ring, int32 Pinky);
FSGForceFeedbackCommandImpl(ESGFinger Finger, int32 BuzzLevel);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGForceFeedbackCommandImpl(const FForceFeedbackCommandType& ForceFeedbackCommand);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGForceFeedbackCommandImpl(TSharedRef<FForceFeedbackCommandType> ForceFeedbackCommand);
public:
/**
* The copy constructor.
*/
FSGForceFeedbackCommandImpl(const FSGForceFeedbackCommandImpl& Rhs);
/**
* The move constructor
*/
FSGForceFeedbackCommandImpl(FSGForceFeedbackCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGForceFeedbackCommandImpl() override;
public:
/**
* The copy assignment operator.
*/
FSGForceFeedbackCommandImpl& operator=(const FSGForceFeedbackCommandImpl& Rhs);
/**
* The move assignment operator.
*/
FSGForceFeedbackCommandImpl& operator=(FSGForceFeedbackCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FForceFeedbackCommandType& ToForceFeedbackCommand() const;
/**
* The cast to underlying pointer type method.
*/
TSharedRef<FForceFeedbackCommandType> ToForceFeedbackCommandRef() const;
public:
virtual FSGForceFeedbackCommandImpl Copy() const;
virtual FSGForceFeedbackCommandImpl Merge(const FSGForceFeedbackCommandImpl& Command) const;
};
@@ -59,19 +59,7 @@ public:
typedef SGCore::Kinematics::HandInterpolator FHandInterpolatorType;
public:
static FSGHandInterpolatorImpl Default(bool bRightHanded);
static FSGHandInterpolatorImpl Deserialize(const FString& SerializedString);
public:
static TArray<FVector> InterpolateFingerAngles(ESGFinger Finger, const FSGHandInterpolatorImpl& Interpolator,
const FVector& TotalGloveAngles);
static TArray<FVector> InterpolateThumbAngles(const FSGHandInterpolatorImpl& Interpolator,
const FVector& TotalGloveAngles);
static TArray<TArray<FVector>> InterpolateHandAngles(const FSGHandInterpolatorImpl& Interpolator,
const TArray<FVector>& TotalAngles);
static FSGHandInterpolatorImpl Deserialize(const FString& SerializedString, bool bRightHanded = true);
private:
struct FImpl;
@@ -87,10 +75,7 @@ private:
public:
FSGHandInterpolatorImpl();
explicit FSGHandInterpolatorImpl(const TArray<TArray<FSGInterpolationSetImpl>>& JointInterpolations);
FSGHandInterpolatorImpl(const TArray<TArray<FSGInterpolationSetImpl>>& JointInterpolations,
const FQuat& CmcStartRotation);
explicit FSGHandInterpolatorImpl(bool bRightHanded);
public:
/**
@@ -133,26 +118,13 @@ public:
const FHandInterpolatorType& ToHandInterpolator() const;
public:
TArray<TArray<FSGInterpolationSetImpl>> GetJointInterpolations() const;
float CalculateAngle(ESGFingerMovement Movement, float Value, bool bApplyLimits = true) const;
FQuat GetCmcStartRotation() const;
float CalculateAngle(ESGThumbMovement Movement, float Value, bool bApplyLimits = true) const;
public:
float CalculateAngle(ESGFinger Finger, int32 Movement, float Value) const;
float CalculateAngle(ESGFinger Finger, ESGFingerMovement Movement, float Value) const;
float CalculateAngle(ESGFinger Finger, ESGThumbMovement Movement, float Value) const;
public:
void SetInterpolation(int32 Finger, int32 Movement, float InputAt0, float InputAt1, float AngleAt0, float AngleAt1);
void SetInterpolation(ESGFinger Finger, ESGFingerMovement Movement,
float InputAt0, float InputAt1, float AngleAt0, float AngleAt1);
void SetInterpolation(ESGThumbMovement Movement, float InputAt0, float InputAt1, float AngleAt0, float AngleAt1);
FSGInterpolationSetImpl GetInterpolation(int32 Finger, int32 Movement) const;
TArray<TArray<FVector>> InterpolateHandAngles(
const TArray<TArray<float>>& Flexions, const TArray<float>& Abductions, float CmcTwist);
public:
bool Equals(const FSGHandInterpolatorImpl& HandInterpolatorImpl) const;
@@ -0,0 +1,118 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "HAL/Platform.h"
#include "Math/Quat.h"
#include "Math/Vector.h"
#include "Templates/SharedPointer.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
class HandLayer;
}
class FSGCustomWaveformImpl;
class FSGHandPoseImpl;
class FSGHapticGloveImpl;
class SENSEGLOVECOREIMPL_API FSGHandLayerImpl final
{
public:
typedef SGCore::HandLayer FHandLayerType;
public:
static bool DeviceConnected(bool bRightHanded);
static ESGDeviceType GetDeviceType(bool bRightHanded);
static bool GetFirstGloveHandedness();
static int32 GlovesConnected();
static bool GetGloveInstance(bool bRightHanded, TSharedPtr<FSGHapticGloveImpl>& OutGlove);
static ESGHapticGloveCalibrationState GetCalibrationState(bool bRightHanded);
static FString GetCalibrationInstructions(bool bRightHanded);
static void ResetCalibration(bool bRightHanded);
static void EndCalibration(bool bRightHanded);
static bool GetHandPose(bool bRightHanded, FSGHandPoseImpl& OutHandPose);
static void GetWristLocation(
bool bRightHanded,
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware,
FVector& OutWristPosition, FQuat& OutWristRotation);
static bool SendHaptics(bool bRightHanded);
static void StopAllHaptics(bool bRightHanded);
static bool QueueCommand_ForceFeedbackLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate);
static bool QueueCommand_ForceFeedbackLevels(
bool bRightHanded, const TArray<float>& Levels01, bool bSendImmediate);
static bool QueueCommand_SetVibroLevel(bool bRightHanded, int32 Finger, float Level01, bool bSendImmediate);
static bool QueueCommand_SetVibroLevels(bool bRightHanded, const TArray<float>& Levels01, bool bSendImmediate);
static bool SupportsCustomWaveform(bool bRightHanded, ESGHapticLocation AtLocation);
static bool SendCustomWaveform(bool bRightHanded, FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location);
static bool SupportsWristSqueeze(bool bRightHanded);
static bool QueueCommand_WristSqueeze(bool bRightHanded, float SqueezeLevel01, bool bSendImmediate);
static bool SupportsFlexionLocks(bool bRightHanded);
static bool QueueCommand_FlexionLock(bool bRightHanded, int32 Finger, float Flexion01, bool bSendImmediate);
static bool QueueCommand_ClearFlexionLock(bool bRightHanded, int32 Finger, bool bSendImmediate);
public:
FSGHandLayerImpl() = delete;
virtual ~FSGHandLayerImpl() = delete;
};
@@ -35,26 +35,31 @@
#pragma once
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "HAL/Platform.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Haptics
{
class TimedThumpCommand;
}
class HapticChannelInfo;
}
class FSGThumperCommandImpl;
class SENSEGLOVECOREIMPL_API FSGTimedThumpCommandImpl final
class SENSEGLOVECOREIMPL_API FSGHapticChannelInfoImpl final
{
public:
typedef SGCore::Haptics::TimedThumpCommand FTimedThumpCommandType;
typedef SGCore::HapticChannelInfo FHapticChannelInfoType;
public:
static FString GenerateAddress(int32 DeviceIndex, int32 ChannelIndex);
static FSGHapticChannelInfoImpl Parse(const FString& IpcString);
public:
static int32 GetStreamingType();
static int32 GetFireAndForgetType();
private:
struct FImpl;
@@ -68,70 +73,61 @@ private:
FImplDeleter PimplDeleter;
public:
FSGTimedThumpCommandImpl();
FSGHapticChannelInfoImpl();
public:
FSGTimedThumpCommandImpl(int32 Magnitude, float DurationSeconds, float StartTimeSeconds = 0.0f);
FSGTimedThumpCommandImpl(const FSGThumperCommandImpl& BaseCommand, float DurationSeconds,
float StartTimeSeconds = 0.0f);
FSGHapticChannelInfoImpl(const TArray<int32>& StreamIndex, const TArray<int32>& FireAndForgetIndex);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGTimedThumpCommandImpl(const FTimedThumpCommandType& TimedThumpCommand);
explicit FSGHapticChannelInfoImpl(const FHapticChannelInfoType& HapticChannelInfo);
public:
/**
* The copy constructor.
*/
FSGTimedThumpCommandImpl(const FSGTimedThumpCommandImpl& Rhs);
FSGHapticChannelInfoImpl(const FSGHapticChannelInfoImpl& Rhs);
/**
* The move constructor
* The move constructor.
*/
FSGTimedThumpCommandImpl(FSGTimedThumpCommandImpl&& Rhs) SG_NOEXCEPT;
FSGHapticChannelInfoImpl(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGTimedThumpCommandImpl();
virtual ~FSGHapticChannelInfoImpl();
public:
/**
* The copy assignment operator.
*/
FSGTimedThumpCommandImpl& operator=(const FSGTimedThumpCommandImpl& Rhs);
FSGHapticChannelInfoImpl& operator=(const FSGHapticChannelInfoImpl& Rhs);
/**
* The move assignment operator.
*/
FSGTimedThumpCommandImpl& operator=(FSGTimedThumpCommandImpl&& Rhs) SG_NOEXCEPT;
FSGHapticChannelInfoImpl& operator=(FSGHapticChannelInfoImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FTimedThumpCommandType& ToTimedThumpCommand() const;
const FHapticChannelInfoType& ToHapticChannelInfo() const;
public:
int32 GetMagnitude() const;
int32 GetStreamChannelCount() const;
int32 GetFireAndForgetChannelCount() const;
int32 GetTotalChannelCount() const;
float GetDuration() const;
FString GetAddress_Unguarded(ESGHapticChannelType Type, int32 TypeIndex) const;
float GetElapsedTime() const;
void GetIpcParams_Unguarded(ESGHapticChannelType Type, int32 TypeIndex,
int32& OutIndex, FString& OutAddressString) const;
bool HasTimeElapsed() const;
void RegenerateAddresses(int32 ForDeviceIndex);
public:
virtual FSGTimedThumpCommandImpl Copy(bool bCopyElapsed = true) const;
virtual void Update(float DeltaSeconds);
virtual bool Equals(const FSGThumperCommandImpl& SGThumperCommandImpl) const;
public:
virtual FString ToString() const;
TArray<FString> GetAllAddresses() const;
};
@@ -1,150 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/Array.h"
#include "Math/Vector.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Calibration
{
class HapticGloveCalibrationCheck;
}
}
class FSGSensorRangeImpl;
class SENSEGLOVECOREIMPL_API FSGHapticGloveCalibrationCheckImpl
{
public:
typedef SGCore::Calibration::HapticGloveCalibrationCheck FHapticGloveCalibrationCheckType;
public:
static float GetSenseGloveThreshold();
static float GetNovaGloveThreshold();
static float GetSenseGloveMinFlexion();
static float GetNovaGloveMinFlexion();
static float GetSenseGloveMinAbduction();
static float GetNovaGloveMinAbduction();
public:
static bool NeedsCheck(ESGDeviceType DeviceType);
static int32 OutOfBounds(const FSGSensorRangeImpl& PreviousRange, const TArray<FVector>& CurrentValues,
ESGDeviceType DeviceType);
static bool MovedMinimum(const TArray<FVector>& CurrentRange, ESGDeviceType DeviceType);
static bool MatchesLast(const TArray<FVector>& CurrentRange, const TArray<FVector>& LastRange,
ESGDeviceType DeviceType);
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGHapticGloveCalibrationCheckImpl();
explicit FSGHapticGloveCalibrationCheckImpl(const FSGSensorRangeImpl& LastCalibrationRange);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGHapticGloveCalibrationCheckImpl(
const FHapticGloveCalibrationCheckType& HapticGloveCalibrationCheck);
public:
/**
* The copy constructor.
*/
FSGHapticGloveCalibrationCheckImpl(const FSGHapticGloveCalibrationCheckImpl& Rhs);
/**
* The move constructor.
*/
FSGHapticGloveCalibrationCheckImpl(FSGHapticGloveCalibrationCheckImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGHapticGloveCalibrationCheckImpl();
public:
/**
* The copy assignment operator.
*/
FSGHapticGloveCalibrationCheckImpl& operator=(const FSGHapticGloveCalibrationCheckImpl& Rhs);
/**
* The move assignment operator.
*/
FSGHapticGloveCalibrationCheckImpl& operator=(FSGHapticGloveCalibrationCheckImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FHapticGloveCalibrationCheckType& ToHapticGloveCalibrationCheck() const;
public:
ESGCalibrationStage GetCalibrationStage() const;
bool ReachedConclusion() const;
public:
virtual void Reset();
void CheckRange(const TArray<FVector>& CurrentValues, float DeltaSeconds, ESGDeviceType DeviceType);
};
@@ -1,192 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/UnrealString.h"
#include "Math/Vector.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGCoreImpl/SGHapticGloveCalibrationSequenceImpl.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Calibration
{
class HapticGloveCalibrationSequence;
}
}
class FSGCalibrationDataPointImpl;
class FSGHandPoseImpl;
class FSGHandProfileImpl;
class FSGHapticGloveImpl;
class FSGHapticGloveQuickCalibrationImpl;
class FSGSensorRangeImpl;
class SENSEGLOVECOREIMPL_API FSGHapticGloveCalibrationSequenceImpl
: public TSharedFromThis<FSGHapticGloveCalibrationSequenceImpl>
{
public:
typedef SGCore::Calibration::HapticGloveCalibrationSequence FHapticGloveCalibrationSequenceType;
public:
static int32 GetMaxDataPoints();
public:
static bool CompileProfile(const FSGSensorRangeImpl& SensorRange, ESGDeviceType ForDevice, bool bRightHanded,
FSGHandProfileImpl& OutProfile);
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGHapticGloveCalibrationSequenceImpl();
explicit FSGHapticGloveCalibrationSequenceImpl(TSharedRef<FSGHapticGloveImpl> LinkedGlove);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGHapticGloveCalibrationSequenceImpl(
const FHapticGloveCalibrationSequenceType& HapticGloveCalibrationSequence);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGHapticGloveCalibrationSequenceImpl(
TSharedRef<FHapticGloveCalibrationSequenceType> HapticGloveCalibrationSequence);
public:
/**
* The copy constructor.
*/
FSGHapticGloveCalibrationSequenceImpl(const FSGHapticGloveCalibrationSequenceImpl& Rhs);
/**
* The move constructor.
*/
FSGHapticGloveCalibrationSequenceImpl(FSGHapticGloveCalibrationSequenceImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGHapticGloveCalibrationSequenceImpl();
public:
/**
* The copy assignment operator.
*/
FSGHapticGloveCalibrationSequenceImpl& operator=(const FSGHapticGloveCalibrationSequenceImpl& Rhs);
/**
* The move assignment operator.
*/
FSGHapticGloveCalibrationSequenceImpl& operator=(FSGHapticGloveCalibrationSequenceImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FHapticGloveCalibrationSequenceType& ToHapticGloveCalibrationSequence() const;
/**
* The cast to underlying pointer type method.
*/
TSharedRef<FHapticGloveCalibrationSequenceType> ToHapticGloveCalibrationSequenceRef() const;
public:
/**
* The cast to base TSharedRef<FSGHapticGloveCalibrationSequenceImpl> type method.
*/
TSharedRef<FSGHapticGloveCalibrationSequenceImpl> ToHapticGloveCalibrationSequenceImplRef();
/**
* The cast to derived TSharedRef<FSGHapticGloveCalibrationSequenceImpl> type method.
*/
TSharedRef<FSGHapticGloveQuickCalibrationImpl> ToHapticGloveQuickCalibrationImplRef();
public:
TSharedRef<FSGHapticGloveImpl> GetLinkedGlove() const;
void SetLinkedGlove(const TSharedRef<FSGHapticGloveImpl> LinkedGlove);
TArray<FSGCalibrationDataPointImpl> GetCalibrationPoints() const;
float GetElapsedTime() const;
bool IsManuallyCompleted() const;
virtual int32 GetCurrentStage() const;
SIZE_T GetCalibrationPointsCount() const;
virtual bool AutoCompleted() const;
virtual bool Completed() const;
public:
virtual void Reset();
virtual void AddDataPoint(const TArray<FVector>& CalibrationPoints);
virtual void Update(float DeltaSeconds);
virtual void ConfirmCurrentStep();
public:
virtual bool CompileRange(FSGSensorRangeImpl& OutSensorRange) const;
virtual bool CompileProfile(ESGDeviceType ForDevice, bool bRightHanded, FSGHandProfileImpl& OutProfile) const;
bool GetHandPose(FSGHandPoseImpl& OutCurrentHandPose) const;
virtual bool GetHandPose(bool bRightHanded, FSGHandPoseImpl& OutCurrentHandPose) const;
virtual FString GetCurrentInstruction(const FString& NextStepKey = FString{""}) const;
};
@@ -1,165 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/Array.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
namespace SGCore
{
namespace Haptics
{
class HapticGloveCommandBuffer;
}
}
class FSGBuzzCommandImpl;
class FSGFingerCommandImpl;
class FSGForceFeedbackCommandImpl;
class FSGThumperCommandImpl;
class FSGTimedBuzzCommandImpl;
class FSGTimedThumpCommandImpl;
class SENSEGLOVECOREIMPL_API FSGHapticGloveCommandBufferImpl final
{
public:
typedef SGCore::Haptics::HapticGloveCommandBuffer FHapticGloveCommandBufferType;
public:
static int32 GetMaxForceFeedbackCommands();
static int32 GetMaxBuzzCommands();
static int32 GetMaxThumpCommands();
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGHapticGloveCommandBufferImpl();
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGHapticGloveCommandBufferImpl(const FHapticGloveCommandBufferType& HapticGloveCommandBuffer);
public:
/**
* The copy constructor.
*/
FSGHapticGloveCommandBufferImpl(const FSGHapticGloveCommandBufferImpl& Rhs);
/**
* The move constructor.
*/
FSGHapticGloveCommandBufferImpl(FSGHapticGloveCommandBufferImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGHapticGloveCommandBufferImpl();
public:
/**
* The copy assignment operator.
*/
FSGHapticGloveCommandBufferImpl& operator=(const FSGHapticGloveCommandBufferImpl& Rhs);
/**
* The move assignment operator.
*/
FSGHapticGloveCommandBufferImpl& operator=(FSGHapticGloveCommandBufferImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FHapticGloveCommandBufferType& ToHapticGloveCommandBuffer() const;
public:
TArray<FSGForceFeedbackCommandImpl> GetForceFeedbackCommandsQueue() const;
TArray<FSGTimedBuzzCommandImpl> GetBuzzCommandsQueue() const;
TArray<FSGTimedThumpCommandImpl> GetThumperCommandsQueue() const;
public:
void ClearForceFeedbackCommandsQueue();
void ClearVibrations();
void Clear();
void AddCommand(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand);
void AddCommand(const FSGTimedBuzzCommandImpl& BuzzCommand);
void AddCommand(const FSGTimedThumpCommandImpl& ThumpCommand);
void UpdateTimedCommands(float DeltaSeconds);
public:
FSGForceFeedbackCommandImpl GetTotalForceFeedbackLevels(
const FSGForceFeedbackCommandImpl& LastForceFeedbackCommand) const;
FSGForceFeedbackCommandImpl GetTotalForceFeedbackLevels() const;
FSGBuzzCommandImpl GetTotalBuzzLevels() const;
FSGThumperCommandImpl GetTotalThumperLevels() const;
public:
void FlushHaptics(const FSGForceFeedbackCommandImpl& LastBrakeLevel,
FSGForceFeedbackCommandImpl& OutForceFeedbackCommand,
FSGBuzzCommandImpl& OutBuzzCommand, FSGThumperCommandImpl& OutThumperCommand,
bool bClearForceFeedbackQueue = true);
void FlushHaptics(float DeltaSeconds, const FSGForceFeedbackCommandImpl& LastBrakeLevel,
FSGForceFeedbackCommandImpl& OutForceFeedbackCommand, FSGBuzzCommandImpl& OutBuzzCommand,
FSGThumperCommandImpl& OutThumperCommand);
};
@@ -1,87 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/UnrealString.h"
#include "Templates/SharedPointer.h"
class FSGHandProfileImpl;
class FSGHapticGloveImpl;
class FSGSensorRangeImpl;
namespace SGCore
{
class HapticGloveHandProfiles;
}
class SENSEGLOVECOREIMPL_API FSGHapticGloveHandProfilesImpl final
{
public:
typedef SGCore::HapticGloveHandProfiles FHapticGloveHandProfilesType;
public:
static const FString& GetProfileDirectory();
static void SetProfileDirectory(const FString& Directory);
static void GetLeftHandProfile(FSGHandProfileImpl& OutHandProfileImpl);
static void SetLeftHandProfile(const FSGHandProfileImpl& HandProfileImpl);
static void GetRightHandProfile(FSGHandProfileImpl& OutHandProfileImpl);
static void SetRightHandProfile(const FSGHandProfileImpl& HandProfileImpl);
static void GetProfile(bool bRightHanded, FSGHandProfileImpl& OutHandProfileImpl);
static void SetProfile(const FSGHandProfileImpl& HandProfileImpl);
static void SetProfile(const FSGHandProfileImpl& HandProfileImpl, bool bRightHanded);
static void RestoreDefaults();
static void RestoreDefaults(bool bRightHanded);
static void TryLoadingFromDisk();
static bool SaveLastRange(const FSGSensorRangeImpl& CurrentRange, const TSharedRef<FSGHapticGloveImpl> ForGlove);
static bool LoadLastRange(const TSharedRef<FSGHapticGloveImpl> ForGlove, FSGSensorRangeImpl& OutLastRange);
public:
FSGHapticGloveHandProfilesImpl() = delete;
virtual ~FSGHapticGloveHandProfilesImpl() = delete;
};
@@ -32,6 +32,7 @@
*
*/
#pragma once
#include <memory>
@@ -54,11 +55,8 @@ namespace SGCore
}
class FSGBasicHandModelImpl;
class FSGBuzzCommandImpl;
class FSGForceFeedbackCommandImpl;
class FSGCustomWaveformImpl;
class FSGHandPoseImpl;
class FSGHandProfileImpl;
class FSGThumperCommandImpl;
class SENSEGLOVECOREIMPL_API FSGHapticGloveImpl : public FSGDeviceImpl
{
@@ -76,12 +74,17 @@ public:
typedef std::vector<FHapticGlovePtrType> FHapticGlovePtrVectorType;
public:
static TArray<TSharedRef<FSGHapticGloveImpl>> GetHapticGloves();
static TArray<TSharedRef<FSGHapticGloveImpl>> GetHapticGloves(bool bConnectedOnly = true);
static bool GetGlove(TSharedPtr<FSGHapticGloveImpl>& OutGlove);
static bool GetGlove(bool bRightHanded, TSharedPtr<FSGHapticGloveImpl>& OutGlove);
public:
static FString ToString(ESGHapticGloveCalibrationState State);
static FString ToString(ESGHapticLocation Location);
private:
struct FImpl;
@@ -149,56 +152,44 @@ public:
virtual int32 GetFirmwareVersion() const override;
virtual int32 GetSubFirmwareVersion() const override;
public:
virtual bool IsRight() const;
virtual bool GetImuRotation(FQuat& OutImu);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose);
virtual bool GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const;
virtual bool GetHandPose(FSGHandPoseImpl& OutHandPose);
#if PLATFORM_ANDROID
virtual bool GetHandPose(float DeltaTime, FSGHandPoseImpl& OutHandPose);
#endif /* PLATFORM_ANDROID */
virtual bool GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const;
FSGBasicHandModelImpl GetHandGeometry() const;
void SetHandGeometry(const FSGBasicHandModelImpl& HandGeometry);
public:
virtual ESGHapticGloveCalibrationState GetCalibrationState() const;
virtual void EndCalibration();
virtual void ResetCalibration();
virtual FString GetCalibrationInstruction() const;
public:
virtual void StopHaptics();
virtual void StopVibrations();
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand);
virtual void SendHaptics(const FSGBuzzCommandImpl& BuzzCommand);
virtual void SendHaptics(const FSGThumperCommandImpl& ThumperCommand);
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand);
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand,
const FSGThumperCommandImpl& ThumperCommand);
virtual bool SendHaptics();
public:
virtual bool GetCalibrationValues(TArray<FVector>& OutValues);
virtual bool QueueForceFeedbackLevels(const TArray<float>& Levels01);
virtual void ResetCalibrationRange();
virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01);
virtual void UpdateCalibrationRange();
virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const;
virtual void UpdateCalibrationRange(const TArray<FVector>& CalibrationValues);
virtual void GetCalibrationRange(TArray<FVector>& OutMinValues,
TArray<FVector>& OutMaxValues);
virtual void UpdateCalibration(FSGHandProfileImpl& OutProfile);
virtual void ApplyCalibration(FSGHandProfileImpl& OutProfile) const;
virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location);
public:
virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -208,4 +199,7 @@ public:
virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware,
FVector& OutGlovePosition, FQuat& OutGloveRotation) const;
public:
virtual FString ToString() const override;
};
@@ -1,156 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/UnrealString.h"
#include "Math/Vector.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCoreImpl/SGHapticGloveCalibrationSequenceImpl.h"
namespace SGCore
{
namespace Calibration
{
class HapticGloveQuickCalibration;
}
}
class FSGHandPoseImpl;
class FSGHandProfileImpl;
class FSGHapticGloveImpl;
class FSGSensorRangeImpl;
class SENSEGLOVECOREIMPL_API FSGHapticGloveQuickCalibrationImpl final : public FSGHapticGloveCalibrationSequenceImpl
{
public:
typedef SGCore::Calibration::HapticGloveQuickCalibration FHapticGloveQuickCalibrationType;
public:
static float GetDefaultAutoEndTimeout();
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGHapticGloveQuickCalibrationImpl();
explicit FSGHapticGloveQuickCalibrationImpl(TSharedRef<FSGHapticGloveImpl> GloveToCalibrate,
float AutoEndTimeout = GetDefaultAutoEndTimeout());
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGHapticGloveQuickCalibrationImpl(const FHapticGloveQuickCalibrationType& HapticGloveQuickCalibration);
public:
/**
* The copy constructor.
*/
FSGHapticGloveQuickCalibrationImpl(const FSGHapticGloveQuickCalibrationImpl& Rhs);
/**
* The move constructor.
*/
FSGHapticGloveQuickCalibrationImpl(FSGHapticGloveQuickCalibrationImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGHapticGloveQuickCalibrationImpl();
public:
/**
* The copy assignment operator.
*/
FSGHapticGloveQuickCalibrationImpl& operator=(const FSGHapticGloveQuickCalibrationImpl& Rhs);
/**
* The move assignment operator.
*/
FSGHapticGloveQuickCalibrationImpl& operator=(FSGHapticGloveQuickCalibrationImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FHapticGloveQuickCalibrationType& ToHapticGloveQuickCalibration() const;
/**
* The cast to underlying pointer type method.
*/
TSharedRef<FHapticGloveQuickCalibrationType> ToHapticGloveQuickCalibrationRef() const;
public:
float GetAutoEndTimeout() const;
int32 GetSmoothingSamples() const;
FSGSensorRangeImpl GetSensorRange() const;
FSGHandProfileImpl GetTemporaryProfile() const;
bool CanAnimate() const;
public:
virtual bool AutoCompleted() const override;
public:
virtual void Reset() override;
virtual void Update(float DeltaSeconds) override;
virtual void AddDataPoint(const TArray<FVector>& CalibrationData) override;
virtual void ConfirmCurrentStep() override;
virtual bool CompileRange(FSGSensorRangeImpl& OutSensorRange) const override;
virtual bool GetHandPose(bool bRightHanded, FSGHandPoseImpl& OutCurrentHandPose) const override;
virtual FString GetCurrentInstruction(const FString& NextStepKey = FString{""}) const override;
};
@@ -35,6 +35,7 @@
#pragma once
#include "Containers/Array.h"
#include "Math/Quat.h"
#include "Math/Vector.h"
@@ -63,4 +64,8 @@ public:
static bool ForwardKinematics(
const FSGBasicHandModelImpl& Profile, ESGFinger Finger, const TArray<FVector>& JointAngles,
TArray<FVector>& OutNewPositions, TArray<FQuat>& OutNewRotations);
public:
FSGJointKinematicsImpl() = delete;
virtual ~FSGJointKinematicsImpl() = delete;
};
@@ -57,4 +57,8 @@ public:
static FString BackendVersion();
static FString SGConnectVersion();
public:
FSGLibraryImpl() = delete;
virtual ~FSGLibraryImpl() = delete;
};
@@ -0,0 +1,284 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include <memory>
#include <vector>
#include "Containers/UnrealString.h"
#include "Math/Quat.h"
#include "Math/Vector.h"
#include "Runtime/Launch/Resources/Version.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCoreImpl/SGHapticGloveImpl.h"
namespace SGCore
{
namespace Nova
{
class Nova2Glove;
}
}
class FSGBasicHandModelImpl;
class FSGHandInterpolatorImpl;
class FSGHandPoseImpl;
class FSGNova2GloveHandProfileImpl;
class FSGNova2GloveSensorDataImpl;
class FSGNovaGloveInfoImpl;
class FSGSensorNormalizationImpl;
class SENSEGLOVECOREIMPL_API FSGNova2GloveImpl final : public FSGHapticGloveImpl
{
#if ENGINE_MAJOR_VERSION >= 5
friend class SharedPointerInternals::TIntrusiveReferenceController<FSGNova2GloveImpl, ESPMode::ThreadSafe>;
#else
friend class SharedPointerInternals::TIntrusiveReferenceController<FSGNova2GloveImpl>;
#endif /* ENGINE_MAJOR_VERSION >= 5 */
public:
typedef SGCore::Nova::Nova2Glove FNova2GloveType;
typedef std::vector<FNova2GloveType> FNova2GloveVectorType;
typedef std::shared_ptr<FNova2GloveType> FNova2GlovePtrType;
typedef std::vector<FNova2GlovePtrType> FNova2GlovePtrVectorType;
public:
static TSharedRef<FSGDeviceImpl> Parse(const FString& ConstantsString);
static TArray<FSGNova2GloveImpl> GetNova2Gloves();
static bool GetNova2Glove(FSGNova2GloveImpl& OutGlove);
static bool GetNova2Glove(bool bRightHanded, FSGNova2GloveImpl& OutGlove);
public:
static void CalculateGloveLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion,
FVector& OutGlovePosition, FQuat& OutGloveRotation);
static void CalculateWristLocation(
const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded, const FString& HardwareVersion,
FVector& OutWristPosition, FQuat& OutWristRotation);
public:
static ANSICHAR GetStreamByte();
static const TArray<float>& GetNova2SensorRanges();
public:
static TArray<float> ToNormalizedValues(const FSGNova2GloveSensorDataImpl& SensorData);
static TArray<float> ToNormalizedValues(
const FSGNova2GloveSensorDataImpl& SensorData, FSGSensorNormalizationImpl& OutSensorNormalizer);
public:
static TArray<TArray<FVector>> CalculateHandAngles(
const TArray<float>& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator, bool bInfluenceIndex);
static TArray<TArray<FVector>> ToNormalizedAngles(
const TArray<float>& NormalizedData, const FSGNovaGloveInfoImpl& GloveInfo);
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGNova2GloveImpl();
explicit FSGNova2GloveImpl(const FSGNovaGloveInfoImpl& DeviceInfo);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGNova2GloveImpl(const FNova2GloveType Nova2Glove);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGNova2GloveImpl(const FNova2GlovePtrType Nova2Glove);
public:
/**
* The copy constructor.
*/
FSGNova2GloveImpl(const FSGNova2GloveImpl& Rhs);
/**
* The move constructor.
*/
FSGNova2GloveImpl(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGNova2GloveImpl() override;
public:
/**
* The copy assignment operator.
*/
FSGNova2GloveImpl& operator=(const FSGNova2GloveImpl& Rhs);
/**
* The move assignment operator.
*/
FSGNova2GloveImpl& operator=(FSGNova2GloveImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FNova2GloveType& ToNova2Glove() const;
/**
* The cast to underlying pointer type method.
*/
FNova2GlovePtrType ToNova2GlovePtr() const;
/**
* The checked cast to underlying pointer type method.
*/
FNova2GlovePtrType ToNova2GlovePtrChecked() const;
public:
virtual ESGDeviceType GetDeviceType() const override;
virtual FString GetDeviceId() const override;
virtual FString GetHardwareVersion() const override;
virtual int32 GetFirmwareVersion() const override;
virtual int32 GetSubFirmwareVersion() const override;
public:
virtual bool HasBattery() const override;
virtual bool IsCharging() override;
virtual bool GetBatteryLevel(float& OutBatteryLevel) override;
public:
virtual bool IsRight() const override;
virtual bool GetImuRotation(FQuat& OutImu) override;
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override;
virtual bool GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const override;
public:
virtual ESGHapticGloveCalibrationState GetCalibrationState() const override;
virtual void EndCalibration() override;
virtual void ResetCalibration() override;
public:
virtual void StopHaptics() override;
virtual void StopVibrations() override;
virtual bool SendHaptics() override;
public:
virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override;
virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location) override;
public:
virtual bool QueueForceFeedbackLevels(const TArray<float>& Levels01) override;
virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override;
virtual bool QueueSqueezeLevel(float SqueezeLevel01);
public:
virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware,
FVector& OutGlovePosition, FQuat& OutGloveRotation) const override;
virtual void GetWristLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware,
FVector& OutWristPosition, FQuat& OutWristRotation) const override;
public:
FSGNovaGloveInfoImpl GetGloveInfo() const;
bool DoesIndexInfluenceOthers() const;
void SetIndexInfluencesOthers(bool bInfluenceOthers);
bool SupportsOnBoardNormalization() const;
public:
bool GetSensorData(FSGNova2GloveSensorDataImpl& OutSensorData) const;
bool GetNormalizedInput(TArray<float>& OutNormalizedValues) const;
virtual bool SendRawData();
virtual bool SendNormalizedData();
public:
virtual ESGNova2VibroMotor ToNovaMotor(ESGHapticLocation Location) const;
virtual int32 ChannelIndex(ESGNova2VibroMotor Motor) const;
virtual void ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, ESGNova2VibroMotor Motor) const;
virtual bool SendCustomWaveform_Nova2(FSGCustomWaveformImpl& OutWaveform, ESGNova2VibroMotor Motor,
bool bValidateWaveform = true);
public:
virtual FString ToString() const override;
};
@@ -42,28 +42,23 @@
#include "SGBuildHacks/SGPlatform.h"
#include "SGTypes/SGCoreTypes.h"
class FSGHandInterpolatorImpl;
namespace SGCore
{
namespace SG
namespace Nova
{
class SenseGloveHandProfile;
class Nova2GloveSensorData;
}
}
class SENSEGLOVECOREIMPL_API FSGSenseGloveHandProfileImpl final
class FSGNovaGloveInfoImpl;
class SENSEGLOVECOREIMPL_API FSGNova2GloveSensorDataImpl final
{
public:
typedef SGCore::SG::SenseGloveHandProfile FSenseGloveHandProfileType;
typedef SGCore::Nova::Nova2GloveSensorData FNova2GloveSensorDataType;
public:
static FSGSenseGloveHandProfileImpl Default(bool bRightHanded);
static FSGSenseGloveHandProfileImpl Deserialize(const FString& SerializedString);
public:
static const FVector& GetDefaultThimbleOffset();
static FSGNova2GloveSensorDataImpl Parse(const FString& RawData, const FSGNovaGloveInfoImpl& GloveInfo);
private:
struct FImpl;
@@ -77,68 +72,72 @@ private:
FImplDeleter PimplDeleter;
public:
FSGSenseGloveHandProfileImpl();
FSGNova2GloveSensorDataImpl();
FSGSenseGloveHandProfileImpl(bool bRightHanded, const FSGHandInterpolatorImpl& Interpolator,
ESGThumbSolver ThumbSolver, ESGFingerSolver FingerSolver,
const TArray<FVector>& FingerThimbleOffset);
FSGNova2GloveSensorDataImpl(const ESGNormalizationState NormalizationState,
const TArray<TArray<FVector>>& Values, int32 ParsedValues,
const FQuat& ImuRotation, bool bImuParsed, float BatteryLevel, bool bCharging);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGSenseGloveHandProfileImpl(const FSenseGloveHandProfileType& SenseGloveHandProfile);
explicit FSGNova2GloveSensorDataImpl(const FNova2GloveSensorDataType& Nova2GloveSensorData);
public:
/**
* The copy constructor.
*/
FSGSenseGloveHandProfileImpl(const FSGSenseGloveHandProfileImpl& Rhs);
FSGNova2GloveSensorDataImpl(const FSGNova2GloveSensorDataImpl& Rhs);
/**
* The move constructor.
*/
FSGSenseGloveHandProfileImpl(FSGSenseGloveHandProfileImpl&& Rhs) SG_NOEXCEPT;
FSGNova2GloveSensorDataImpl(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGSenseGloveHandProfileImpl();
virtual ~FSGNova2GloveSensorDataImpl();
public:
/**
* The copy assignment operator.
*/
FSGSenseGloveHandProfileImpl& operator=(const FSGSenseGloveHandProfileImpl& Rhs);
FSGNova2GloveSensorDataImpl& operator=(const FSGNova2GloveSensorDataImpl& Rhs);
/**
* The move assignment operator.
*/
FSGSenseGloveHandProfileImpl& operator=(FSGSenseGloveHandProfileImpl&& Rhs) SG_NOEXCEPT;
FSGNova2GloveSensorDataImpl& operator=(FSGNova2GloveSensorDataImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FSenseGloveHandProfileType& ToSenseGloveHandProfile() const;
const FNova2GloveSensorDataType& ToNova2GloveSensorData() const;
public:
bool IsRight() const;
ESGNormalizationState GetSensorState() const;
FSGHandInterpolatorImpl GetInterpolationSet() const;
TArray<TArray<FVector>> GetSensorValues() const;
float GetSensorValue(ESGFinger Finger, ESGNova2SensorLocation Location) const;
ESGThumbSolver GetThumbSolver() const;
int32 GetParsedValues() const;
ESGFingerSolver GetFingerSolver() const;
FQuat GetImuRotation() const;
TArray<FVector> GetFingerThimbleOffset() const;
bool IsImuParsed() const;
public:
bool Equals(const FSGSenseGloveHandProfileImpl& SenseGloveHandProfileImpl) const;
float GetBatteryLevel() const;
void Reset();
bool IsCharging() const;
public:
FString Serialize() const;
bool Equals(const FSGNova2GloveSensorDataImpl& Nova2GloveSensorDataImpl) const;
public:
FString ToString() const;
};
@@ -1,72 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/Array.h"
#include "Math/Vector.h"
class FSGNovaGloveHandProfileImpl;
namespace SGCore
{
namespace Calibration
{
class NovaGloveCalibration;
}
}
class SENSEGLOVECOREIMPL_API FSGNovaGloveCalibrationImpl final
{
public:
typedef SGCore::Calibration::NovaGloveCalibration FNovaGloveCalibrationType;
public:
static void ApplyDefaultCalibrationInterpolationValues(
const TArray<FVector>& RetractedValues,
const TArray<FVector>& ExtendedValues,
const FSGNovaGloveHandProfileImpl& Profile);
static void ApplyInterpolationValues(
const TArray<FVector>& RetractedValues,
const TArray<FVector>& ExtendedValues,
const TArray<TArray<FVector>>& RetractedAngles,
const TArray<TArray<FVector>>& ExtendedAngles,
const FSGNovaGloveHandProfileImpl& Profile);
public:
FSGNovaGloveCalibrationImpl() = delete;
virtual ~FSGNovaGloveCalibrationImpl() = delete;
};
@@ -1,131 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 NovaGlove
*
* 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
*
*
*/
#pragma once
#include "Containers/UnrealString.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
class FSGHandInterpolatorImpl;
namespace SGCore
{
namespace Nova
{
class NovaGloveHandProfile;
}
}
class SENSEGLOVECOREIMPL_API FSGNovaGloveHandProfileImpl final
{
public:
typedef SGCore::Nova::NovaGloveHandProfile FNovaGloveHandProfileType;
public:
static FSGNovaGloveHandProfileImpl Default(bool bRightHanded);
static FSGNovaGloveHandProfileImpl Deserialize(const FString& SerializedString);
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGNovaGloveHandProfileImpl();
FSGNovaGloveHandProfileImpl(bool bRightHanded, const FSGHandInterpolatorImpl& Interpolator);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGNovaGloveHandProfileImpl(const FNovaGloveHandProfileType& NovaGloveHandProfile);
public:
/**
* The copy constructor.
*/
FSGNovaGloveHandProfileImpl(const FSGNovaGloveHandProfileImpl& Rhs);
/**
* The move constructor.
*/
FSGNovaGloveHandProfileImpl(FSGNovaGloveHandProfileImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGNovaGloveHandProfileImpl();
public:
/**
* The copy assignment operator.
*/
FSGNovaGloveHandProfileImpl& operator=(const FSGNovaGloveHandProfileImpl& Rhs);
/**
* The move assignment operator.
*/
FSGNovaGloveHandProfileImpl& operator=(FSGNovaGloveHandProfileImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FNovaGloveHandProfileType& ToNovaGloveHandProfile() const;
public:
bool IsRight() const;
FSGHandInterpolatorImpl GetInterpolationSet() const;
public:
bool Equals(const FSGNovaGloveHandProfileImpl& NovaGloveHandProfileImpl) const;
void Reset();
public:
FString Serialize() const;
};
@@ -38,6 +38,8 @@
#include <memory>
#include <vector>
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Math/Quat.h"
#include "Math/Vector.h"
#include "Runtime/Launch/Resources/Version.h"
@@ -56,14 +58,13 @@ namespace SGCore
}
class FSGBasicHandModelImpl;
class FSGBuzzCommandImpl;
class FSGForceFeedbackCommandImpl;
class FSGHandInterpolatorImpl;
class FSGHandPoseImpl;
class FSGHandProfileImpl;
class FSGNovaGloveHandProfileImpl;
class FSGNovaGloveInfoImpl;
class FSGNovaGloveSensorDataImpl;
class FSGThumperCommandImpl;
class FSGSensorNormalizationImpl;
class FSGThresholdCommandImpl;
class SENSEGLOVECOREIMPL_API FSGNovaGloveImpl final : public FSGHapticGloveImpl
{
@@ -81,16 +82,6 @@ public:
typedef std::shared_ptr<FNovaGloveType> FNovaGlovePtrType;
typedef std::vector<FNovaGlovePtrType> FNovaGlovePtrVectorType;
public:
static ANSICHAR GetHapticsByte();
static const FVector& GetMinCalibrationRange();
public:
static FSGHandPoseImpl CalculateHandPose(const FSGBasicHandModelImpl& HandModel,
const FSGNovaGloveSensorDataImpl& NovaData,
const FSGNovaGloveHandProfileImpl& Profile);
public:
static TSharedRef<FSGDeviceImpl> Parse(const FString& ConstantsString);
@@ -100,12 +91,6 @@ public:
static bool GetNovaGlove(bool bRightHanded, FSGNovaGloveImpl& OutGlove);
public:
static TArray<FVector> GetCalibrationValues(const FSGNovaGloveSensorDataImpl& SensorData);
static void CalibrateInterpolation(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues,
FSGNovaGloveHandProfileImpl& OutProfile);
public:
static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware, bool bRightHanded,
@@ -116,11 +101,29 @@ public:
FVector& OutWristPosition, FQuat& OutWristRotation);
public:
static FString ToBytes(const FSGThumperCommandImpl& ThumperCommand);
static ANSICHAR GetHapticsByte();
static FString ToBytes(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand);
static ANSICHAR GetThresholdsByte();
static FString ToBytes(const FSGBuzzCommandImpl& BuzzCommand);
static ANSICHAR GetIgnoreThresholdsByte();
static const TArray<float>& GetNovaSensorRanges();
public:
static TArray<float> ToNormalizedValues(const FSGNovaGloveSensorDataImpl& SensorData);
static TArray<float> ToNormalizedValues(
const FSGNovaGloveSensorDataImpl& SensorData, FSGSensorNormalizationImpl& OutSensorNormalizer);
public:
static TArray<TArray<FVector>> CalculateHandAngles(
const TArray<float>& NormalizedValues, const FSGHandInterpolatorImpl& Interpolator);
public:
static FString ToNovaCommandAsFlexion(const FSGThresholdCommandImpl& Thresholds);
static FString ToNovaCommandAsRaw(
const FSGThresholdCommandImpl& Thresholds, const FSGSensorNormalizationImpl& Interpolator);
private:
struct FImpl;
@@ -204,6 +207,9 @@ public:
virtual int32 GetSubFirmwareVersion() const override;
public:
virtual void SetDeviceIndex(int32 NewIndex) override;
public:
virtual bool HasBattery() const override;
@@ -212,40 +218,37 @@ public:
virtual bool GetBatteryLevel(float& OutBatteryLevel) override;
public:
bool GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData);
virtual bool IsRight() const override;
virtual bool GetImuRotation(FQuat& OutImu) override;
/// HACK
/// 'FSGNovaGloveImpl::GetHandPose' hides overloaded virtual functions [-Werror,-Woverloaded-virtual]
/// tell the compiler we want both the GetHandPose from FSGHapticGloveImpl and FSGNovaGloveImpl
using FSGHapticGloveImpl::GetHandPose;
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override;
bool GetHandPose(const FSGBasicHandModelImpl& HandModel, const FSGNovaGloveHandProfileImpl& Profile,
FSGHandPoseImpl& OutHandPose);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose) override;
virtual bool GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose) override;
virtual bool GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const override;
public:
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand,
const FSGThumperCommandImpl& ThumperCommand) override;
virtual ESGHapticGloveCalibrationState GetCalibrationState() const override;
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand) override;
virtual void EndCalibration() override;
virtual void SendHaptics(const FSGBuzzCommandImpl& BuzzCommand) override;
virtual void SendHaptics(const FSGThumperCommandImpl& ThumperCommand) override;
virtual void ResetCalibration() override;
public:
virtual bool GetCalibrationValues(TArray<FVector>& OutValues) override;
virtual void StopHaptics() override;
virtual void ApplyCalibration(FSGHandProfileImpl& OutProfile) const override;
virtual void StopVibrations() override;
void ApplyCalibration(FSGNovaGloveHandProfileImpl& OutProfile) const;
virtual bool SendHaptics() override;
public:
virtual bool SupportsCustomWaveform(ESGHapticLocation AtLocation) const override;
virtual bool SendCustomWaveform(FSGCustomWaveformImpl& OutWaveform, ESGHapticLocation Location) override;
public:
virtual bool QueueForceFeedbackLevels(const TArray<float>& Levels01) override;
virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override;
public:
virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -256,6 +259,45 @@ public:
ESGPositionalTrackingHardware TrackingHardware,
FVector& OutWristPosition, FQuat& OutWristRotation) const override;
public:
FSGNovaGloveInfoImpl GetGloveInfo() const;
bool SupportsThresholds() const;
bool SupportsCustomWaveforms() const;
bool SupportsOnBoardNormalization() const;
public:
bool GetSensorData(FSGNovaGloveSensorDataImpl& OutSensorData) const;
bool GetNormalizedInput(TArray<float>& OutNormalizedValues) const;
public:
virtual FString ToNovaCommand(
const TArray<float>& ForceFeedbackLevels, const TArray<float>& BuzzLevels, float WristLevel) const;
virtual bool QueueVibroLevels(const TArray<float>& Amplitudes);
virtual bool QueueVibroLevel(int32 Finger, float Amplitude);
virtual bool QueueWristLevel(float Amplitude);
public:
virtual ESGNovaVibroMotor ToNovaMotor(ESGHapticLocation Location) const;
virtual int32 ChannelIndex(ESGNovaVibroMotor Motor) const;
virtual void ValidateWaveform(FSGCustomWaveformImpl& OutWaveform, ESGNovaVibroMotor Motor) const;
virtual bool SendCustomWaveform_Nova(FSGCustomWaveformImpl& OutWaveform, ESGNovaVibroMotor Motor,
bool bValidateWaveform = true);
public:
bool QueueThresholdCommand_Flexion(int32 Finger, float FlexionThreshold);
virtual bool QueueClearThreshold(int32 Finger);
public:
virtual FString ToString() const override;
};
@@ -131,6 +131,11 @@ public:
int32 GetNumberOfSensors() const;
public:
bool FirmwareNewerThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
bool FirmwareOlderThan(int32 FirmwareMain, int32 FirmwareSub, bool bInclusive) const;
public:
bool Equals(const FSGNovaGloveInfoImpl& SGNovaGloveInfo) const;
@@ -40,6 +40,7 @@
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
@@ -121,12 +122,16 @@ public:
const FNovaGloveSensorDataType& ToNovaGloveSensorData() const;
public:
TArray<FVector> GetSensorValues() const;
ESGNormalizationState GetSensorState() const;
FQuat GetImuRotation() const;
TArray<FVector> GetSensorValues() const;
float GetSensorValue(ESGFinger Finger, ESGNovaSensorLocation Location) const;
int32 GetParsedValues() const;
public:
FQuat GetImuRotation() const;
bool IsImuParsed() const;
public:
@@ -57,15 +57,13 @@ namespace SGCore
}
class FSGBasicHandModelImpl;
class FSGBuzzCommandImpl;
class FSGForceFeedbackCommandImpl;
class FSGHandInterpolatorImpl;
class FSGHandPoseImpl;
class FSGHandProfileImpl;
class FSGSenseGloveHandProfileImpl;
class FSGSenseGloveInfoImpl;
class FSGSenseGlovePoseImpl;
class FSGSenseGloveSensorDataImpl;
class FSGThumperCommandImpl;
class FSGSenseGloveSensorNormalizerImpl;
class SENSEGLOVECOREIMPL_API FSGSenseGloveImpl final : public FSGHapticGloveImpl
{
@@ -83,22 +81,6 @@ public:
typedef std::shared_ptr<FSenseGloveType> FSenseGlovePtrType;
typedef std::vector<FSenseGlovePtrType> FSenseGlovePtrVectorType;
public:
static ANSICHAR GetHapticsByte();
static ANSICHAR GetThumperByte();
public:
static FSGSenseGlovePoseImpl CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
const FSGSenseGloveInfoImpl& GloveModel);
static FSGSenseGlovePoseImpl CalculateGlovePose(const TArray<TArray<FVector>>& GloveAngles,
const FSGSenseGloveInfoImpl& GloveModel);
static FSGHandPoseImpl CalculateHandPose(const FSGSenseGlovePoseImpl& GlovePose,
const FSGBasicHandModelImpl& HandModel,
const FSGSenseGloveHandProfileImpl& Profile);
public:
static TSharedRef<FSGDeviceImpl> Parse(const FString& ConstantsString);
@@ -108,12 +90,6 @@ public:
static bool GetSenseGlove(bool bRightHanded, FSGSenseGloveImpl& OutGlove);
public:
static TArray<FVector> GetCalibrationValues(const FSGSenseGlovePoseImpl& GlovePose);
static void CalibrateInterpolation(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues,
bool bRightHanded, FSGSenseGloveHandProfileImpl& OutProfile);
public:
static void CalculateGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
ESGPositionalTrackingHardware TrackingHardware,
@@ -127,6 +103,34 @@ public:
const FQuat& GloveWristRotationOffset,
FVector& OutWristPosition, FQuat& OutWristRotation);
public:
static ANSICHAR GetHapticsByte();
static ANSICHAR GetThumperByte();
static const FVector& GetDefaultThimbleOffset();
public:
static FSGSenseGlovePoseImpl CalculateGlovePose(const FSGSenseGloveSensorDataImpl& SensorData,
const FSGSenseGloveInfoImpl& GloveModel);
static FSGSenseGlovePoseImpl CalculateGlovePose(const TArray<TArray<FVector>>& GloveAngles,
const FSGSenseGloveInfoImpl& GloveModel);
static void NormalizeValues(const TArray<FVector>& SumAngles,
const FSGSenseGloveSensorNormalizerImpl& Normalizer,
TArray<float>& OutFlexions, TArray<float>& OutAbductions);
public:
static void CalculateHandAngles(
const FSGSenseGlovePoseImpl& GlovePose, const FSGSenseGloveSensorNormalizerImpl& Normalizer,
const FSGHandInterpolatorImpl& NormalizedToAngles,
TArray<TArray<FVector>>& OutHandAngles);
static void CalculateHandPose(const FSGSenseGlovePoseImpl& GlovePose, const FSGBasicHandModelImpl& HandModel,
const FSGSenseGloveSensorNormalizerImpl& Normalizer,
const FSGHandInterpolatorImpl& NormalizedToAngles, FSGHandPoseImpl& OutHandPose);
private:
struct FImpl;
@@ -198,11 +202,6 @@ public:
*/
FSenseGlovePtrType ToSenseGlovePtrChecked() const;
public:
FSGSenseGloveInfoImpl GetGloveModel() const;
virtual bool IsRight() const override;
public:
virtual ESGDeviceType GetDeviceType() const override;
@@ -215,55 +214,32 @@ public:
virtual int32 GetSubFirmwareVersion() const override;
public:
bool GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const;
virtual bool IsRight() const override;
virtual bool GetImuRotation(FQuat& OutImu) override;
bool GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, FSGHandPoseImpl& OutHandPose) const override;
bool GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, FSGSenseGlovePoseImpl& OutGlovePose);
/// HACK
/// 'FSGSenseGloveImpl::GetHandPose' hides overloaded virtual functions [-Werror,-Woverloaded-virtual]
/// tell the compiler we want both the GetHandPose from FSGHapticGloveImpl and FSGSenseGloveImpl
using FSGHapticGloveImpl::GetHandPose;
bool GetHandPose(const FSGBasicHandModelImpl& HandModel, const FSGSenseGloveHandProfileImpl& Profile,
FSGHandPoseImpl& OutHandPose);
virtual bool GetHandPose(const FSGBasicHandModelImpl& HandGeometry, const FSGHandProfileImpl& HandProfile,
FSGHandPoseImpl& OutHandPose) override;
virtual bool GetHandPose(const FSGHandProfileImpl& HandProfile, FSGHandPoseImpl& OutHandPose) override;
virtual bool GetHandAngles(TArray<TArray<FVector>>& OutHandAngles) const override;
public:
/// HACK
/// 'FSGSenseGloveImpl::SendHaptics' hides overloaded virtual functions [-Werror,-Woverloaded-virtual]
/// tell the compiler we want both the SendHaptics from FSGHapticGloveImpl and FSGSenseGloveImpl
using FSGHapticGloveImpl::SendHaptics;
virtual ESGHapticGloveCalibrationState GetCalibrationState() const override;
bool SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand,
ESGSenseGloveThumperCommand ThumperCommand = ESGSenseGloveThumperCommand::None);
virtual void EndCalibration() override;
bool SendHaptics(ESGSenseGloveThumperCommand ThumperCommand);
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand) override;
virtual void SendHaptics(const FSGBuzzCommandImpl& BuzzCommand) override;
virtual void SendHaptics(const FSGForceFeedbackCommandImpl& ForceFeedbackCommand,
const FSGBuzzCommandImpl& BuzzCommand,
const FSGThumperCommandImpl& ThumperCommand) override;
virtual void ResetCalibration() override;
public:
virtual bool GetCalibrationValues(TArray<FVector>& OutValues) override;
virtual void StopHaptics() override;
virtual void ResetCalibrationRange() override;
virtual void StopVibrations() override;
virtual void ApplyCalibration(FSGHandProfileImpl& OutProfile) const override;
virtual bool SendHaptics() override;
void ApplyCalibration(FSGSenseGloveHandProfileImpl& OutProfile) const;
public:
virtual bool QueueForceFeedbackLevels(const TArray<float>& Levels01) override;
virtual bool QueueForceFeedbackLevel(int32 Finger, float Level01) override;
public:
virtual void GetGloveLocation(const FVector& ReferencePosition, const FQuat& ReferenceRotation,
@@ -284,6 +260,29 @@ public:
const FQuat& GloveWristRotationOffset,
FVector& OutWristPosition, FQuat& OutWristRotation) const;
public:
FSGSenseGloveInfoImpl GetGloveInfo() const;
TArray<FVector> GetFingerThimbleOffsets() const;
void SetFingerThimbleOffset(int32 Finger, const FVector& Offset);
bool SupportsWristActuator() const;
public:
bool GetSensorData(FSGSenseGloveSensorDataImpl& OutSensorData) const;
bool GetGlovePose(FSGSenseGlovePoseImpl& OutGlovePose) const;
bool GetGlovePose(const FSGSenseGloveSensorDataImpl& SensorData, FSGSenseGlovePoseImpl& OutGlovePose) const;
public:
virtual bool QueueVibroLevels(const TArray<float>& Amplitudes);
virtual bool QueueVibroLevel(int32 Finger, float Amplitude);
virtual bool QueueThumperCommand(ESGSenseGloveThumperCommand Command);
public:
virtual FString ToString() const override;
};
@@ -137,9 +137,7 @@ public:
TArray<FVector> GetTotalGloveAngles() const;
TArray<FVector> CalculateFingerTips(const FSGSenseGloveHandProfileImpl& SenseGloveHandProfileImpl) const;
TArray<FVector> CalculateFingerTips(const TArray<FVector>& FingerOffsets) const;
TArray<FVector> CalculateFingertips(const TArray<FVector>& FingerOffsets) const;
bool Equals(const FSGSenseGlovePoseImpl& SenseGlovePoseImpl) const;
@@ -77,8 +77,8 @@ private:
public:
FSGSenseGloveSensorDataImpl();
FSGSenseGloveSensorDataImpl(const TArray<TArray<float>>& SensorAngles, const FQuat& ImuRotation, int32 ParsedValues,
bool bImuParsed);
FSGSenseGloveSensorDataImpl(const TArray<TArray<float>>& SensorAngles, const FQuat& ImuRotation,
int32 ParsedValues, bool bImuParsed);
public:
/**
@@ -35,23 +35,24 @@
#pragma once
#include "Containers/UnrealString.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
namespace SGCore
{
namespace Calibration
namespace SG
{
class CalibrationDataPoint;
class SenseGloveSensorNormalizer;
}
}
class SENSEGLOVECOREIMPL_API FSGCalibrationDataPointImpl final
class FSGSenseGloveInfoImpl;
class SENSEGLOVECOREIMPL_API FSGSenseGloveSensorNormalizerImpl final
{
public:
typedef SGCore::Calibration::CalibrationDataPoint FCalibrationDataPointType;
typedef SGCore::SG::SenseGloveSensorNormalizer FSenseGloveSensorNormalizerType;
private:
struct FImpl;
@@ -65,55 +66,52 @@ private:
FImplDeleter PimplDeleter;
public:
FSGCalibrationDataPointImpl();
FSGSenseGloveSensorNormalizerImpl();
FSGCalibrationDataPointImpl(int32 CurrentStage, const TArray<FVector>& CalibrationValues);
explicit FSGSenseGloveSensorNormalizerImpl(bool bRightHanded);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGCalibrationDataPointImpl(const FCalibrationDataPointType& CalibrationDataPoint);
explicit FSGSenseGloveSensorNormalizerImpl(const FSenseGloveSensorNormalizerType& SenseGloveSensorNormalizer);
public:
/**
* The copy constructor.
*/
FSGCalibrationDataPointImpl(const FSGCalibrationDataPointImpl& Rhs);
FSGSenseGloveSensorNormalizerImpl(const FSGSenseGloveSensorNormalizerImpl& Rhs);
/**
* The move constructor.
*/
FSGCalibrationDataPointImpl(FSGCalibrationDataPointImpl&& Rhs) SG_NOEXCEPT;
FSGSenseGloveSensorNormalizerImpl(FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGCalibrationDataPointImpl();
virtual ~FSGSenseGloveSensorNormalizerImpl();
public:
/**
* The copy assignment operator.
*/
FSGCalibrationDataPointImpl& operator=(const FSGCalibrationDataPointImpl& Rhs);
FSGSenseGloveSensorNormalizerImpl& operator=(const FSGSenseGloveSensorNormalizerImpl& Rhs);
/**
* The move assignment operator.
*/
FSGCalibrationDataPointImpl& operator=(FSGCalibrationDataPointImpl&& Rhs) SG_NOEXCEPT;
FSGSenseGloveSensorNormalizerImpl& operator=(FSGSenseGloveSensorNormalizerImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FCalibrationDataPointType& ToCalibrationDataPoint() const;
const FSenseGloveSensorNormalizerType& ToSenseGloveSensorNormalizer() const;
public:
TArray<FVector> GetCalibrationValues() const;
float NormalizeFlexion(int32 Finger, float SumFlexionAngles) const;
int32 GetStage() const;
public:
FString ToLogData(const FString& Delimiter = "\t") const;
float NormalizeAbduction(int32 Finger, float SumAbductionAngles) const;
};
@@ -35,26 +35,25 @@
#pragma once
#include "HAL/Platform.h"
#include "Containers/Array.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
namespace SGCore
{
namespace Haptics
namespace Util
{
class ThumperCommand;
class SensorNormalization;
}
}
class SENSEGLOVECOREIMPL_API FSGThumperCommandImpl final
class FSGSenseGloveInfoImpl;
class SENSEGLOVECOREIMPL_API FSGSensorNormalizationImpl final
{
public:
typedef SGCore::Haptics::ThumperCommand FThumperCommandType;
public:
static const FSGThumperCommandImpl& Off();
typedef SGCore::Util::SensorNormalization FSensorNormalizationType;
private:
struct FImpl;
@@ -68,56 +67,76 @@ private:
FImplDeleter PimplDeleter;
public:
FSGThumperCommandImpl();
explicit FSGThumperCommandImpl(int32 Magnitude);
FSGSensorNormalizationImpl();
explicit FSGSensorNormalizationImpl(const TArray<float>& MovementRanges);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGThumperCommandImpl(const FThumperCommandType& ThumperCommand);
explicit FSGSensorNormalizationImpl(const FSensorNormalizationType& SensorNormalization);
public:
/**
* The copy constructor.
*/
FSGThumperCommandImpl(const FSGThumperCommandImpl& Rhs);
FSGSensorNormalizationImpl(const FSGSensorNormalizationImpl& Rhs);
/**
* The move constructor
* The move constructor.
*/
FSGThumperCommandImpl(FSGThumperCommandImpl&& Rhs) SG_NOEXCEPT;
FSGSensorNormalizationImpl(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGThumperCommandImpl();
virtual ~FSGSensorNormalizationImpl();
public:
/**
* The copy assignment operator.
*/
FSGThumperCommandImpl& operator=(const FSGThumperCommandImpl& Rhs);
FSGSensorNormalizationImpl& operator=(const FSGSensorNormalizationImpl& Rhs);
/**
* The move assignment operator.
*/
FSGThumperCommandImpl& operator=(FSGThumperCommandImpl&& Rhs) SG_NOEXCEPT;
FSGSensorNormalizationImpl& operator=(FSGSensorNormalizationImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FThumperCommandType& ToThumperCommand() const;
const FSensorNormalizationType& ToSensorNormalization() const;
/**
* The cast to underlying type method.
*/
FSensorNormalizationType& ToSensorNormalization();
public:
int32 GetMagnitude() const;
void SetMagnitude(int32 Magnitude);
bool CollectsNormalization() const;
FSGThumperCommandImpl Copy() const;
void SetCollectNormalization(bool bCollectNormalization);
FSGThumperCommandImpl Merge(const FSGThumperCommandImpl& ThumperCommandImpl) const;
public:
int32 GetLength() const;
virtual bool Equals(const FSGThumperCommandImpl& ThumperCommandImpl) const;
int32 GetMoveCount() const;
bool AllSensorsMoving() const;
void ResetNormalization();
void UpdateNormalization(float Value, int32 Index);
float NormalizeValue(float Value, int32 Index);
TArray<float> NormalizeValues(const TArray<float>& Values);
bool MovedEnough(int32 Index) const;
float Denormalize(float Value01, int32 Index, float FallbackValue = 1.0f) const;
};
@@ -35,33 +35,26 @@
#pragma once
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Math/Vector.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
namespace SGCore
{
namespace Calibration
namespace Haptics
{
class SensorRange;
class ThresholdCommand;
}
}
class SENSEGLOVECOREIMPL_API FSGSensorRangeImpl final
class FSGSenseGloveInfoImpl;
class SENSEGLOVECOREIMPL_API FSGThresholdCommandImpl final
{
public:
typedef SGCore::Calibration::SensorRange FSensorRangeType;
public:
static const FSGSensorRangeImpl& ForCalibration();
static FSGSensorRangeImpl Deserialize(const FString& SerializedString);
static void CheckMax(const FVector CurrentValues, FVector& OutMaxValues);
static void CheckMin(const FVector& CurrentValues, FVector& OutMinValues);
typedef SGCore::Haptics::ThresholdCommand FThresholdCommandType;
private:
struct FImpl;
@@ -75,70 +68,74 @@ private:
FImplDeleter PimplDeleter;
public:
FSGSensorRangeImpl();
FSGSensorRangeImpl(const TArray<FVector>& MinValues, const TArray<FVector>& MaxValues);
FSGThresholdCommandImpl();
FSGThresholdCommandImpl(const TArray<bool>& AffectedFingers, const TArray<float>& ThresholdValues);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGSensorRangeImpl(const FSensorRangeType& SensorRange);
explicit FSGThresholdCommandImpl(const FThresholdCommandType& ThresholdCommand);
public:
/**
* The copy constructor.
*/
FSGSensorRangeImpl(const FSGSensorRangeImpl& Rhs);
FSGThresholdCommandImpl(const FSGThresholdCommandImpl& Rhs);
/**
* The move constructor.
*/
FSGSensorRangeImpl(FSGSensorRangeImpl&& Rhs) SG_NOEXCEPT;
FSGThresholdCommandImpl(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGSensorRangeImpl();
virtual ~FSGThresholdCommandImpl();
public:
/**
* The copy assignment operator.
*/
FSGSensorRangeImpl& operator=(const FSGSensorRangeImpl& Rhs);
FSGThresholdCommandImpl& operator=(const FSGThresholdCommandImpl& Rhs);
/**
* The move assignment operator.
*/
FSGSensorRangeImpl& operator=(FSGSensorRangeImpl&& Rhs) SG_NOEXCEPT;
FSGThresholdCommandImpl& operator=(FSGThresholdCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FSensorRangeType& ToSensorRange() const;
const FThresholdCommandType& ToThresholdCommand() const;
/**
* The cast to underlying type method.
*/
FThresholdCommandType& ToThresholdCommand();
public:
TArray<FVector> GetMinValues() const;
float GetThreshold(int32 Finger) const;
void SetMinValues(const TArray<FVector>& Values);
void SetThreshold(int32 Finger, float ThresholdValue);
TArray<FVector> GetMaxValues() const;
TArray<float> GetThresholds() const;
void SetMaxValues(const TArray<FVector>& Values);
void SetThresholds(const TArray<bool>& AffectedFingers, const TArray<float>& ThresholdValues);
TArray<FVector> GetRange() const;
bool GetFingerActive(int32 Finger) const;
TArray<bool> GetActiveFingers() const;
void ClearThreshold(int32 Finger);
void ClearThresholds();
public:
void UpdateRange();
void CheckForExtremes(const TArray<FVector>& OtherValues);
bool Equals(const FSGThresholdCommandImpl& ThresholdCommand) const;
public:
FString RangeString(bool bYOnly = true) const;
FString ToString(bool bYOnly = true) const;
FString Serialize() const;
FString ToString() const;
};
@@ -1,163 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2024 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
*
*
*/
#pragma once
#include "Containers/UnrealString.h"
#include "HAL/Platform.h"
#include "Templates/SharedPointer.h"
#include "Templates/UniquePtr.h"
#include "SGBuildHacks/SGPlatform.h"
#include "SGCoreImpl/SGBuzzCommandImpl.h"
#include "SGTypes/SGCoreTypes.h"
namespace SGCore
{
namespace Haptics
{
class TimedBuzzCommand;
}
}
class SENSEGLOVECOREIMPL_API FSGTimedBuzzCommandImpl final : public FSGBuzzCommandImpl
{
public:
typedef SGCore::Haptics::TimedBuzzCommand FTimedBuzzCommandType;
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
public:
FSGTimedBuzzCommandImpl();
public:
FSGTimedBuzzCommandImpl(ESGFinger Finger, int32 Magnitude, float DurationSeconds, float StartTimeSeconds = 0.0f);
FSGTimedBuzzCommandImpl(const FSGBuzzCommandImpl& BaseCommand, float DurationSeconds,
float StartTimeSeconds = 0.0f);
public:
/**
* The cast from underlying type constructor.
*/
explicit FSGTimedBuzzCommandImpl(const FTimedBuzzCommandType& TimedBuzzCommand);
/**
* The cast from underlying pointer type constructor.
*/
explicit FSGTimedBuzzCommandImpl(TSharedRef<FTimedBuzzCommandType> TimedBuzzCommand);
public:
/**
* The copy constructor.
*/
FSGTimedBuzzCommandImpl(const FSGTimedBuzzCommandImpl& Rhs);
/**
* The move constructor
*/
FSGTimedBuzzCommandImpl(FSGTimedBuzzCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The destructor.
*/
virtual ~FSGTimedBuzzCommandImpl();
public:
/**
* The copy assignment operator.
*/
FSGTimedBuzzCommandImpl& operator=(const FSGTimedBuzzCommandImpl& Rhs);
/**
* The move assignment operator.
*/
FSGTimedBuzzCommandImpl& operator=(FSGTimedBuzzCommandImpl&& Rhs) SG_NOEXCEPT;
public:
/**
* The cast to underlying type method.
*/
const FTimedBuzzCommandType& ToTimedBuzzCommand() const;
/**
* The cast to underlying pointer type method.
*/
TSharedRef<FTimedBuzzCommandType> ToTimedBuzzCommandRef() const;
protected:
/**
* The non-const cast to underlying type method.
*/
FTimedBuzzCommandType& ToTimedBuzzCommand();
/**
* The non-const cast to underlying type method.
*/
TSharedRef<FTimedBuzzCommandType> ToTimedBuzzCommandRef();
public:
virtual FSGBuzzCommandImpl Copy() const override;
virtual FSGBuzzCommandImpl Merge(const FSGBuzzCommandImpl& BuzzCommand) const override;
public:
virtual FSGBuzzCommandImpl GetBaseCommand() const;
float GetDuration() const;
float GetElapsedTime() const;
virtual bool HasTimeElapsed() const;
virtual float NormalizedTime(bool bClamp01 = true) const;
public:
virtual void ResetTiming();
virtual void UpdateTiming(float DeltaSeconds);
public:
virtual FString ToString() const override;
};
@@ -68,19 +68,14 @@ public:
FVector& OutPositionOffset, FQuat& OutRotationOffset);
static const FVector& GetSenseGloveViveToAttachPosition();
static const FQuat& GetSenseGloveViveToAttachRotation();
static const FVector& GetSenseGloveOculusTouchToAttachPosition();
static const FQuat& GetSenseGloveOculusTouchToAttachRotation();
static const FVector& GetNovaToWristPositionOffset();
static const FQuat& GetNovaToWristRotationOffset();
static void GetNovaGloveWristOffset(bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset);
static const FVector& GetRightNovaViveToAttachPosition();
static const FQuat& GetRightNovaViveToAttachRotation();
@@ -95,11 +90,64 @@ public:
static const FVector& GetRightNovaPico2ToAttachPosition();
static const FQuat& GetRightNovaPico2ToAttachRotation();
static const FQuat& GetLeftNovaPico2ToAttachRotation();
static const FVector& GetRightNovaQuestProToAttachPosition();
static const FQuat& GetRightNovaQuestProToAttachRotation();
static const FVector& GetLeftNovaQuestProToAttachPosition();
static const FQuat& GetLeftNovaQuestProToAttachRotation();
static const FVector& GetRightNovaViveFocus3ToAttachPosition();
static const FQuat& GetRightNovaViveFocus3ToAttachRotation();
static const FVector& GetLeftNovaViveFocus3ToAttachPosition();
static const FQuat& GetLeftNovaViveFocus3ToAttachRotation();
static void GetNovaGloveWristOffset(bool bRightHanded, FVector& OutPositionOffset, FQuat& OutRotationOffset);
static void GetNovaGloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded,
FVector& OutPositionOffset, FQuat& OutRotationOffset);
static const FVector& GetRightNova2ToWristPositionOffset();
static const FQuat& GetRightNova2ToWristRotationOffset();
static const FVector& GetLeftNova2ToWristPositionOffset();
static const FQuat& GetLeftNova2ToWristRotationOffset();
static const FVector& GetRightNova2Quest2ToAttachPosition();
static const FQuat& GetRightNova2Quest2ToAttachRotation();
static const FVector& GetLeftNova2Quest2ToAttachPosition();
static const FQuat& GetLeftNova2Quest2ToAttachRotation();
static const FVector& GetRightNova2QuestProToAttachPosition();
static const FQuat& GetRightNova2QuestProToAttachRotation();
static const FVector& GetLeftNova2QuestProToAttachPosition();
static const FQuat& GetLeftNova2QuestProToAttachRotation();
static const FVector& GetRightNova2ViveTrackerToAttachPosition();
static const FQuat& GetRightNova2ViveTrackerToAttachRotation();
static const FVector& GetLeftNova2ViveTrackerToAttachPosition();
static const FQuat& GetLeftNova2ViveTrackerToAttachRotation();
static const FVector& GetRightNova2ViveWristTrackerToAttachPosition();
static const FQuat& GetRightNova2ViveWristTrackerToAttachRotation();
static const FVector& GetLeftNova2ViveWristTrackerToAttachPosition();
static const FQuat& GetLeftNova2ViveWristTrackerToAttachRotation();
static void GetNova2GloveWristOffset(bool bRightHanded, const FString& HardwareVersion,
FVector& OutPositionOffset, FQuat& OutRotationOffset);
static void GetNova2GloveTrackerOffset(ESGPositionalTrackingHardware Hardware, bool bRightHanded,
const FString& HardwareVersion,
FVector& OutPositionOffset,
FQuat& OutRotationOffset);
static FString ToString(ESGPositionalTrackingHardware Hardware);
public:
@@ -194,6 +194,8 @@ public class SenseGloveCoreImpl : ModuleRules
case WindowsCompiler.VisualStudio2022:
LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc143"));
break;
#endif
#if ! UE_5_4_OR_LATER && UE_5_0_OR_LATER
case WindowsCompiler.VisualStudio2019:
LibraryPath = Path.GetFullPath(Path.Combine(LibraryPath, "msvc142"));
break;