183 lines
5.7 KiB
C++
183 lines
5.7 KiB
C++
/**
|
|
* @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 "SenseGloveTrackingModule.h"
|
|
|
|
#include "Framework/Application/SlateApplication.h"
|
|
|
|
#include "SGLog/SGLog.h"
|
|
#include "SGTracking/SGXRTracker.h"
|
|
|
|
#define LOCTEXT_NAMESPACE "FSenseGloveTrackingModule"
|
|
|
|
struct FSenseGloveTrackingModule::FImpl
|
|
{
|
|
/************************
|
|
* Member variables
|
|
************************/
|
|
|
|
TSharedPtr<FSGXRTracker> InputDevice;
|
|
|
|
/************************
|
|
* Owner object
|
|
************************/
|
|
|
|
FSenseGloveTrackingModule* Owner;
|
|
|
|
/************************
|
|
* Constructor / Destructor
|
|
************************/
|
|
|
|
explicit FImpl(FSenseGloveTrackingModule* InOwner);
|
|
~FImpl();
|
|
|
|
/************************
|
|
* Default copy constructor & copy assignment operator
|
|
************************/
|
|
|
|
FImpl(const FImpl& Rhs) = default;
|
|
FImpl& operator=(const FImpl& Rhs) = default;
|
|
};
|
|
|
|
|
|
FSenseGloveTrackingModule::FSenseGloveTrackingModule()
|
|
: IInputDeviceModule(),
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
|
|
{
|
|
}
|
|
|
|
FSenseGloveTrackingModule::FSenseGloveTrackingModule(const FSenseGloveTrackingModule& Rhs)
|
|
: IInputDeviceModule(Rhs),
|
|
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{*Rhs.Pimpl}, PimplDeleter))
|
|
{
|
|
Pimpl->Owner = this;
|
|
}
|
|
|
|
FSenseGloveTrackingModule::FSenseGloveTrackingModule(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default;
|
|
|
|
FSenseGloveTrackingModule::~FSenseGloveTrackingModule() = default;
|
|
|
|
FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(const FSenseGloveTrackingModule& Rhs)
|
|
{
|
|
IInputDeviceModule::operator=(Rhs);
|
|
*Pimpl = *Rhs.Pimpl;
|
|
Pimpl->Owner = this;
|
|
return *this;
|
|
}
|
|
|
|
FSenseGloveTrackingModule& FSenseGloveTrackingModule::operator=(FSenseGloveTrackingModule&& Rhs) SG_NOEXCEPT = default;
|
|
|
|
void FSenseGloveTrackingModule::StartupModule()
|
|
{
|
|
SGLOG("Starting up SenseGloveTracking module...");
|
|
|
|
IInputDeviceModule::StartupModule();
|
|
|
|
/// HACK!
|
|
// Generic Application might not be instantiated at this point so we create the input device with a dummy message
|
|
// handler. When the Generic Application creates the input device it passes a valid message handler to it which is
|
|
// further on used for all the controller events. This hack fixes issues caused by using a custom input device
|
|
// before the Generic Application has instantiated it. Eg. within BeginPlay().
|
|
// This also fixes the warnings that pop up on the custom input keys when the blueprint loads. Those warnings are
|
|
// caused because Unreal loads the Blueprints before the input device has been instantiated and has added its keys,
|
|
// thus leading Unreal to believe that those keys don't exist. This hack causes an earlier instantiation of the
|
|
// input device, and consequently, the custom keys.
|
|
TSharedPtr<FGenericApplicationMessageHandler> DummyMessageHandler(new FGenericApplicationMessageHandler());
|
|
CreateInputDevice(DummyMessageHandler.ToSharedRef());
|
|
}
|
|
|
|
void FSenseGloveTrackingModule::PreUnloadCallback()
|
|
{
|
|
SGLOG("Unloading SenseGloveTracking module...");
|
|
|
|
IInputDeviceModule::PreUnloadCallback();
|
|
}
|
|
|
|
void FSenseGloveTrackingModule::PostLoadCallback()
|
|
{
|
|
SGLOG("Loading of SenseGloveTracking module has succeeded!");
|
|
|
|
IInputDeviceModule::PostLoadCallback();
|
|
}
|
|
|
|
void FSenseGloveTrackingModule::ShutdownModule()
|
|
{
|
|
SGLOG("Shutting down SenseGloveTracking module...");
|
|
|
|
IInputDeviceModule::ShutdownModule();
|
|
}
|
|
|
|
TSharedPtr<IInputDevice> FSenseGloveTrackingModule::CreateInputDevice(
|
|
const TSharedRef<FGenericApplicationMessageHandler>& InMessageHandler)
|
|
{
|
|
SGLOG("Creating the SenseGloveTracking input device...");
|
|
|
|
if (!Pimpl->InputDevice.IsValid())
|
|
{
|
|
TSharedPtr<FSGXRTracker> HandTrackingInputDevice(new FSGXRTracker(InMessageHandler));
|
|
Pimpl->InputDevice = HandTrackingInputDevice;
|
|
}
|
|
else
|
|
{
|
|
Pimpl->InputDevice.Get()->SetMessageHandler(InMessageHandler);
|
|
}
|
|
|
|
return Pimpl->InputDevice;
|
|
}
|
|
|
|
TSharedPtr<IInputDevice> FSenseGloveTrackingModule::GetInputDevice()
|
|
{
|
|
if (!Pimpl->InputDevice.IsValid())
|
|
{
|
|
CreateInputDevice(FSlateApplication::Get().GetPlatformApplication()->GetMessageHandler());
|
|
}
|
|
|
|
return Pimpl->InputDevice;
|
|
}
|
|
|
|
FSenseGloveTrackingModule::FImpl::FImpl(FSenseGloveTrackingModule* InOwner)
|
|
: InputDevice(nullptr),
|
|
Owner(InOwner)
|
|
{
|
|
}
|
|
|
|
FSenseGloveTrackingModule::FImpl::~FImpl() = default;
|
|
|
|
void FSenseGloveTrackingModule::FImplDeleter::operator()(const FImpl* P) const
|
|
{
|
|
delete P;
|
|
}
|
|
|
|
#undef LOCTEXT_NAMESPACE |