add partion implementation of the virtual hand

This commit is contained in:
Mamadou Babaei
2023-03-28 10:34:20 +02:00
parent 89a9200413
commit 02cb09d504
30 changed files with 834 additions and 126 deletions
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,36 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#include "SenseGlove/Animation/SGAnimInstanceProxy.h"
@@ -33,20 +33,40 @@
*/
#include "SenseGlove/Animation/SGAnimInstance.h"
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
USGAnimInstance::USGAnimInstance(const FObjectInitializer& ObjectInitializer)
USGVirtualHandAnimInstance::USGVirtualHandAnimInstance(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
}
void USGAnimInstance::NativeInitializeAnimation()
void USGVirtualHandAnimInstance::NativeInitializeAnimation()
{
Super::NativeInitializeAnimation();
}
FSGAnimInstanceProxy* USGAnimInstance::CreateAnimInstanceProxy()
void USGVirtualHandAnimInstance::NativeUpdateAnimation(const float DeltaSeconds)
{
return new FSGAnimInstanceProxy();
Super::NativeUpdateAnimation(DeltaSeconds);
}
void USGVirtualHandAnimInstance::NativePostEvaluateAnimation()
{
Super::NativePostEvaluateAnimation();
}
void USGVirtualHandAnimInstance::NativeUninitializeAnimation()
{
Super::NativeUninitializeAnimation();
}
void USGVirtualHandAnimInstance::NativeBeginPlay()
{
Super::NativeBeginPlay();
}
FSGVirtualHandAnimInstanceProxy* USGVirtualHandAnimInstance::CreateAnimInstanceProxy()
{
return new FSGVirtualHandAnimInstanceProxy();
}
@@ -33,10 +33,44 @@
*/
#include "SenseGlove/GameFramework/SGCharacter.h"
#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h"
ASGCharacter::ASGCharacter(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
void FSGVirtualHandAnimInstanceProxy::Initialize(UAnimInstance* InAnimInstance)
{
FAnimInstanceProxy::Initialize(InAnimInstance);
}
void FSGVirtualHandAnimInstanceProxy::Uninitialize(UAnimInstance* InAnimInstance)
{
FAnimInstanceProxy::Uninitialize(InAnimInstance);
}
void FSGVirtualHandAnimInstanceProxy::PreUpdate(UAnimInstance* InAnimInstance, const float DeltaSeconds)
{
FAnimInstanceProxy::PreUpdate(InAnimInstance, DeltaSeconds);
}
void FSGVirtualHandAnimInstanceProxy::Update(const float DeltaSeconds)
{
FAnimInstanceProxy::Update(DeltaSeconds);
}
void FSGVirtualHandAnimInstanceProxy::PreEvaluateAnimation(UAnimInstance* InAnimInstance)
{
FAnimInstanceProxy::PreEvaluateAnimation(InAnimInstance);
}
bool FSGVirtualHandAnimInstanceProxy::Evaluate(FPoseContext& Output)
{
return FAnimInstanceProxy::Evaluate(Output);
}
void FSGVirtualHandAnimInstanceProxy::PostUpdate(UAnimInstance* InAnimInstance) const
{
FAnimInstanceProxy::PostUpdate(InAnimInstance);
}
void FSGVirtualHandAnimInstanceProxy::PostEvaluate(UAnimInstance* InAnimInstance)
{
FAnimInstanceProxy::PostEvaluate(InAnimInstance);
}
@@ -35,12 +35,12 @@
#include "SenseGlove/GameFramework//SGGameModeBase.h"
#include "SenseGlove/GameFramework/SGCharacter.h"
#include "SenseGlove/GameFramework/SGPawn.h"
#include "SenseGlove/GameFramework/SGPlayerController.h"
ASGGameModeBase::ASGGameModeBase(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
DefaultPawnClass = ASGCharacter::StaticClass();
DefaultPawnClass = ASGPawn::StaticClass();
PlayerControllerClass = ASGPlayerController::StaticClass();
}
@@ -0,0 +1,98 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#include "SenseGlove/GameFramework/SGPawn.h"
#include "Components/ActorComponent.h"
#include "SenseGlove/GameFramework/SGPawn.h"
struct ASGPawn::FImpl
{
/************************
* Static methods
************************/
/************************
* Owner object
************************/
ASGPawn* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(ASGPawn* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
/************************
* Methods
************************/
};
ASGPawn::ASGPawn(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer),
#if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 24 )
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
#else
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}))
#endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 24 ) */
{
PrimaryActorTick.bCanEverTick = true;
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
SetRootComponent(SceneRoot);
}
ASGPawn::FImpl::FImpl(ASGPawn* InOwner)
: Owner(InOwner)
{
}
ASGPawn::FImpl::~FImpl() = default;
void ASGPawn::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -0,0 +1,333 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#include "SenseGlove/GameFramework/SGVirtualHand.h"
#include "Components/SkeletalMeshComponent.h"
#include "Engine/SkeletalMesh.h"
#include "UObject/ConstructorHelpers.h"
#include "SenseGlove/Animation/SGVirtualHandAnimInstance.h"
#include "SGCore/SGHandPose.h"
#include "SGCore/SGHapticGlove.h"
#include "SGLog/SGLog.h"
struct ASGVirtualHand::FImpl
{
/************************
* Static methods
************************/
FORCEINLINE static const FString& GetDefaultLeftHandMeshPath()
{
static const FString Path(TEXT("SkeletalMesh'/SenseGlove/Meshes/"
"SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left'"));
return Path;
}
FORCEINLINE static const FString& GetDefaultLeftHandMeshPathOnly()
{
static const FString Path(TEXT("/SenseGlove/Meshes/"
"SK_SenseGlove_VirtualHand_Left.SK_SenseGlove_VirtualHand_Left"));
return Path;
}
FORCEINLINE static const FString& GetDefaultRightHandMeshPath()
{
static const FString Path(TEXT("SkeletalMesh'/SenseGlove/Meshes/"
"SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right'"));
return Path;
}
FORCEINLINE static const FString& GetDefaultRightHandMeshPathOnly()
{
static const FString Path(TEXT("/SenseGlove/Meshes/"
"SK_SenseGlove_VirtualHand_Right.SK_SenseGlove_VirtualHand_Right"));
return Path;
}
/************************
* Owner object
************************/
ASGVirtualHand* Owner;
/************************
* Constructor / Destructor
************************/
explicit FImpl(ASGVirtualHand* InOwner);
~FImpl();
/************************
* Default copy constructor & copy assignment operator
************************/
FImpl(const FImpl& Rhs) = default;
FImpl& operator=(const FImpl& Rhs) = default;
/************************
* Methods
************************/
bool IsEditor() const;
void SetHandMesh(USkeletalMesh* VirtualHandMesh, bool bReinitPos) const;
FString GetDefaultMeshPath() const;
bool IsUsingUserMesh() const;
USkeletalMesh* LoadDefaultMesh() const;
void SetDefaultMesh() const;
bool CheckGlove() const;
};
ASGVirtualHand::ASGVirtualHand(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer),
#if ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 24 )
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}, PimplDeleter))
#else
Pimpl(TUniquePtr<FImpl, FImplDeleter>(new FImpl{this}))
#endif /* ENGINE_MAJOR_VERSION == 5 || ( ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION > 24 ) */
{
PrimaryActorTick.bCanEverTick = true;
SceneRoot = CreateDefaultSubobject<USceneComponent>(TEXT("SceneRoot"));
SetRootComponent(SceneRoot);
Mesh = CreateDefaultSubobject<USkeletalMeshComponent>(TEXT("Mesh"));
Mesh->SetupAttachment(RootComponent);
Mesh->SetCastShadow(true);
Mesh->SetCastHiddenShadow(false);
Mesh->bCastDynamicShadow = true;
Mesh->SetOnlyOwnerSee(false);
Mesh->SetReceivesDecals(true);
Mesh->SetCanEverAffectNavigation(false);
Mesh->SetCollisionObjectType(ECC_WorldDynamic);
Mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Mesh->SetCollisionResponseToAllChannels(ECR_Overlap);
Mesh->SetCollisionResponseToChannel(ECC_WorldStatic, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_WorldDynamic, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_Pawn, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_Visibility, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_PhysicsBody, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_Vehicle, ECR_Block);
Mesh->SetCollisionResponseToChannel(ECC_Destructible, ECR_Block);
AnimInstanceClass = USGVirtualHandAnimInstance::StaticClass();
bRight = true;
bHiddenInGameIfNoGloveDetected = true;
bAnimateInEditor = true;
const FString SkeletalMeshPath(Pimpl->GetDefaultMeshPath());
const ConstructorHelpers::FObjectFinder<USkeletalMesh> SkeletalMesh(*SkeletalMeshPath);
ensureAlwaysMsgf(SkeletalMesh.Succeeded() && SkeletalMesh.Object,
TEXT("Failed to load the skeletal mesh: '%s'"), *SkeletalMeshPath);
Pimpl->SetHandMesh(SkeletalMesh.Object, true);
Glove = nullptr;
}
void ASGVirtualHand::SetHandMesh(USkeletalMesh* VirtualHandMesh, const bool bReinitPos) const
{
Pimpl->SetHandMesh(VirtualHandMesh, bReinitPos);
}
void ASGVirtualHand::Tick(const float DeltaSeconds)
{
#if WITH_EDITOR
if (Pimpl->IsEditor())
{
EditorTick(DeltaSeconds);
return;
}
#endif
Super::Tick(DeltaSeconds);
(void)Pimpl->CheckGlove();
}
bool ASGVirtualHand::ShouldTickIfViewportsOnly() const
{
if (!bAnimateInEditor)
{
return false;
}
if (Pimpl->IsEditor())
{
return true;
}
return false;
}
void ASGVirtualHand::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
if (!Pimpl->IsUsingUserMesh())
{
Pimpl->SetDefaultMesh();
}
}
void ASGVirtualHand::EditorTick(float DeltaSeconds)
{
(void)Pimpl->CheckGlove();
}
bool ASGVirtualHand::IsGloveConnected()
{
return Pimpl->CheckGlove();
}
USGHandPose* ASGVirtualHand::GetHandPose()
{
USGHandPose* HandPose = nullptr;
if (IsValid(Glove))
{
Glove->GetHandPose(this, HandPose);
}
return HandPose;
}
ASGVirtualHand::FImpl::FImpl(ASGVirtualHand* InOwner)
: Owner(InOwner)
{
}
ASGVirtualHand::FImpl::~FImpl() = default;
void ASGVirtualHand::FImpl::SetHandMesh(USkeletalMesh* VirtualHandMesh, const bool bReinitPos) const
{
ensureAlwaysMsgf(IsValid(VirtualHandMesh), TEXT("Invalid VirtualHandMesh object!"));
ensureAlwaysMsgf(IsValid(Owner->Mesh), TEXT("Invalid Mesh object!"));
ensureAlwaysMsgf(IsValid(Owner->AnimInstanceClass), TEXT("Invalid AnimInstanceClass object!"));
Owner->Mesh->SetSkeletalMesh(VirtualHandMesh, bReinitPos);
Owner->Mesh->SetAnimInstanceClass(Owner->AnimInstanceClass);
}
bool ASGVirtualHand::FImpl::IsEditor() const
{
const UWorld* World = Owner->GetWorld();
if (World && World->WorldType == EWorldType::Editor)
{
return true;
}
return false;
}
FString ASGVirtualHand::FImpl::GetDefaultMeshPath() const
{
FString SkeletalMeshPath;
if (Owner->bRight)
{
SkeletalMeshPath = GetDefaultRightHandMeshPath();
}
else
{
SkeletalMeshPath = GetDefaultLeftHandMeshPath();
}
return SkeletalMeshPath;
}
bool ASGVirtualHand::FImpl::IsUsingUserMesh() const
{
ensureAlwaysMsgf(IsValid(Owner->Mesh), TEXT("Invalid Mesh object!"));
if (!IsValid(Owner->Mesh->SkeletalMesh))
{
return false;
}
const FString CurrentMeshPath(Owner->Mesh->SkeletalMesh->GetPathName());
const FString LeftHandDefaultMeshPath(GetDefaultLeftHandMeshPath());
const FString LeftHandDefaultMeshPathOnly(GetDefaultLeftHandMeshPathOnly());
const FString RightHandDefaultMeshPath(GetDefaultRightHandMeshPath());
const FString RightHandDefaultMeshPathOnly(GetDefaultRightHandMeshPathOnly());
if (CurrentMeshPath == LeftHandDefaultMeshPath
|| CurrentMeshPath == LeftHandDefaultMeshPathOnly
|| CurrentMeshPath == RightHandDefaultMeshPath
|| CurrentMeshPath == RightHandDefaultMeshPathOnly)
{
return false;
}
return true;
}
USkeletalMesh* ASGVirtualHand::FImpl::LoadDefaultMesh() const
{
const FString SkeletalMeshPath(GetDefaultMeshPath());
USkeletalMesh* SkeletalMesh = Cast<USkeletalMesh>(
StaticLoadObject(USkeletalMesh::StaticClass(), nullptr, *SkeletalMeshPath));
ensureAlwaysMsgf(SkeletalMesh, TEXT("Failed to load the skeletal mesh: '%s'"), *SkeletalMeshPath);
return SkeletalMesh;
}
void ASGVirtualHand::FImpl::SetDefaultMesh() const
{
SetHandMesh(LoadDefaultMesh(), true);
}
bool ASGVirtualHand::FImpl::CheckGlove() const
{
const bool bGloveWasPresent = IsValid(Owner->Glove);
const bool bFoundGlove = USGHapticGlove::GetGlove(Owner, Owner->IsRight(), Owner->Glove);
if (!bFoundGlove && bGloveWasPresent)
{
SGLOG_ERROR(FString::Printf(TEXT("Could not find a %s glove"),
(Owner->bRight ? TEXT("right-handed") : TEXT("left-handed"))));
}
return bFoundGlove;
}
void ASGVirtualHand::FImplDeleter::operator()(const FImpl* P) const
{
delete P;
}
@@ -37,18 +37,33 @@
#include "Animation/AnimInstance.h"
#include "SenseGlove/Animation/SGAnimInstanceProxy.h"
#include "SenseGlove/Animation/SGVirtualHandAnimInstanceProxy.h"
#include "SGAnimInstance.generated.h"
#include "SGVirtualHandAnimInstance.generated.h"
UCLASS(Transient, Blueprintable, HideCategories=SGAnimInstance, BlueprintType, Meta=(BlueprintThreadSafe), Within=SkeletalMeshComponent)
class SENSEGLOVE_API USGAnimInstance : public UAnimInstance
UCLASS(Transient, Blueprintable, BlueprintType, meta=(BlueprintThreadSafe), Within=SkeletalMeshComponent)
class SENSEGLOVE_API USGVirtualHandAnimInstance : public UAnimInstance
{
GENERATED_UCLASS_BODY()
public:
// the below functions are the native overrides for each phase
// Native initialization override point
virtual void NativeInitializeAnimation() override;
// Native update override point. It is usually a good idea to simply gather data in this step and
// for the bulk of the work to be done in NativeUpdateAnimation.
virtual void NativeUpdateAnimation(float DeltaSeconds) override;
// Native Post Evaluate override point
virtual void NativePostEvaluateAnimation() override;
// Native Uninitialize override point
virtual void NativeUninitializeAnimation() override;
// Executed when begin play is called on the owning component
virtual void NativeBeginPlay() override;
protected:
virtual FSGAnimInstanceProxy* CreateAnimInstanceProxy() override;
virtual FSGVirtualHandAnimInstanceProxy* CreateAnimInstanceProxy() override;
};
@@ -37,10 +37,39 @@
#include "Animation/AnimInstanceProxy.h"
#include "SGAnimInstanceProxy.generated.h"
#include "SGVirtualHandAnimInstanceProxy.generated.h"
USTRUCT()
struct SENSEGLOVE_API FSGAnimInstanceProxy : public FAnimInstanceProxy
struct SENSEGLOVE_API FSGVirtualHandAnimInstanceProxy : public FAnimInstanceProxy
{
GENERATED_USTRUCT_BODY()
protected:
/** Called when our anim instance is being initialized */
virtual void Initialize(UAnimInstance* InAnimInstance) override;
/** Called when our anim instance is being uninitialized */
virtual void Uninitialize(UAnimInstance* InAnimInstance) override;
/** Called before update so we can copy any data we need */
virtual void PreUpdate(UAnimInstance* InAnimInstance, float DeltaSeconds) override;
/** Update override point */
virtual void Update(float DeltaSeconds) override;
/** Called on the game thread pre-evaluate. */
virtual void PreEvaluateAnimation(UAnimInstance* InAnimInstance) override;
/**
* Evaluate override point
* @return true if this function is implemented, false otherwise.
* Note: the node graph will not be evaluated if this function returns true
*/
virtual bool Evaluate(FPoseContext& Output) override;
/** Called after update so we can copy any data we need */
virtual void PostUpdate(UAnimInstance* InAnimInstance) const override;
/** Called after evaluate so we can do any game thread work we need to */
virtual void PostEvaluate(UAnimInstance* InAnimInstance) override;
};
@@ -1,46 +0,0 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#pragma once
#include "GameFramework/Character.h"
#include "SGCharacter.generated.h"
UCLASS(Config=Game, BlueprintType)
class SENSEGLOVE_API ASGCharacter : public ACharacter
{
GENERATED_UCLASS_BODY()
};
@@ -0,0 +1,98 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#pragma once
#include "GameFramework/Pawn.h"
#include "Templates/UniquePtr.h"
#include "SGPawn.generated.h"
class UActorComponent;
class UMotionControllerComponent;
UCLASS(Config=Game, BlueprintType, Blueprintable)
class SENSEGLOVE_API ASGPawn : public APawn
{
GENERATED_UCLASS_BODY()
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
USceneComponent* SceneRoot;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
UMotionControllerComponent* MotionControllerLeft;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
UMotionControllerComponent* MotionControllerRight;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
UActorComponent* HandLeft;
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
UActorComponent* HandRight;
protected:
FORCEINLINE UMotionControllerComponent* GetMotionContollerLeft() const
{
return MotionControllerLeft;
}
FORCEINLINE UMotionControllerComponent* GetMotionContollerRight() const
{
return MotionControllerRight;
}
FORCEINLINE UActorComponent* GetHandLeft() const
{
return HandLeft;
}
FORCEINLINE UActorComponent* GetHandRight() const
{
return HandRight;
}
};
@@ -0,0 +1,162 @@
/**
* @file
*
* @author Mamadou Babaei <mamadou@senseglove.com>
*
* @section LICENSE
*
* (The MIT License)
*
* Copyright (c) 2020 - 2023 SenseGlove
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*
* @section DESCRIPTION
*
*
*/
#pragma once
#include "GameFramework/Actor.h"
#include "Templates/UniquePtr.h"
#include "SGVirtualHand.generated.h"
class USkeletalMesh;
class USkeletalMeshComponent;
class USceneComponent;
class USGHandPose;
class USGHapticGlove;
UCLASS(Config=Game, BlueprintType)
class SENSEGLOVE_API ASGVirtualHand : public AActor
{
GENERATED_UCLASS_BODY()
private:
struct FImpl;
struct FImplDeleter
{
void operator()(const FImpl* P) const;
};
TUniquePtr<FImpl, FImplDeleter> Pimpl;
FImplDeleter PimplDeleter;
private:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
USceneComponent* SceneRoot;
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
USkeletalMeshComponent* Mesh;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
UClass* AnimInstanceClass;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
uint8 bRight : 1;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
uint8 bHiddenInGameIfNoGloveDetected : 1;
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category="SenseGlove", meta=(AllowPrivateAccess="true"))
uint8 bAnimateInEditor : 1;
private:
UPROPERTY(Transient)
USGHapticGlove* Glove;
public:
FORCEINLINE USkeletalMeshComponent* GetMesh() const
{
return Mesh;
}
public:
FORCEINLINE bool IsLeft() const
{
return !IsRight();
}
FORCEINLINE bool IsRight() const
{
return !!bRight;
}
FORCEINLINE void SetRight(const bool bInRight)
{
bRight = bInRight;
}
FORCEINLINE bool IsHiddenInGameIfNoGloveDetected() const
{
return !!bHiddenInGameIfNoGloveDetected;
}
FORCEINLINE void SetHiddenIfNoGloveDetected(const bool bInHiddenIfNoGloveDetected)
{
bHiddenInGameIfNoGloveDetected = bInHiddenIfNoGloveDetected;
}
FORCEINLINE bool IsAnimateInEditor() const
{
return bAnimateInEditor;
}
FORCEINLINE void SetAnimateInEditor(const bool bInAnimateInEditor)
{
bAnimateInEditor = bInAnimateInEditor;
}
void SetHandMesh(USkeletalMesh* VirtualHandMesh, bool bReinitPos) const;
protected:
FORCEINLINE void SetMesh(USkeletalMeshComponent* InMesh)
{
Mesh = InMesh;
}
FORCEINLINE UClass* GetAnimInstanceClass() const
{
return AnimInstanceClass;
}
FORCEINLINE void SetAnimInstanceClass(UClass* InAnimInstanceClass)
{
AnimInstanceClass = InAnimInstanceClass;
}
public:
virtual void Tick(float DeltaSeconds) override;
virtual bool ShouldTickIfViewportsOnly() const override;
virtual void OnConstruction(const FTransform& Transform) override;
protected:
virtual void EditorTick(float DeltaSeconds);
public:
bool IsGloveConnected();
USGHandPose* GetHandPose();
};
+1
View File
@@ -54,6 +54,7 @@ public class SenseGlove : ModuleRules
{
"CoreUObject",
"Engine",
"HeadMountedDisplay",
"SenseGloveConnect",
"SenseGloveCore",
"SenseGloveLog",