add partion implementation of the virtual hand

This commit is contained in:
Mamadou Babaei
2023-03-28 10:38:48 +02:00
parent f3e5b20c46
commit 8710a08489
30 changed files with 834 additions and 126 deletions
@@ -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",