Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e1ceb2f7fc |
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.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
@@ -3,18 +3,18 @@
|
|||||||
|
|
||||||
#include "LumiCharacter.h"
|
#include "LumiCharacter.h"
|
||||||
|
|
||||||
#include "Camera/CameraComponent.h"
|
|
||||||
#include "Components/CapsuleComponent.h"
|
|
||||||
#include "Engine/LocalPlayer.h"
|
#include "Engine/LocalPlayer.h"
|
||||||
#include "Engine/UserInterfaceSettings.h"
|
#include "Engine/UserInterfaceSettings.h"
|
||||||
#include "GameFramework/CharacterMovementComponent.h"
|
#include "Camera/CameraComponent.h"
|
||||||
#include "GameFramework/Controller.h"
|
#include "Components/CapsuleComponent.h"
|
||||||
#include "GameFramework/SpringArmComponent.h"
|
#include "GameFramework/SpringArmComponent.h"
|
||||||
|
#include "GameFramework/Controller.h"
|
||||||
#include "InputActionValue.h"
|
#include "InputActionValue.h"
|
||||||
|
#include "GameFramework/CharacterMovementComponent.h"
|
||||||
#include "WizardingCentral/Utils/OneDollar/UniStrokeDataTable.h"
|
#include "WizardingCentral/Utils/OneDollar/UniStrokeDataTable.h"
|
||||||
#include "WizardingCentral/Utils/OneDollar/UniStrokeResult.h"
|
#include "WizardingCentral/Utils/OneDollar/UniStrokeResult.h"
|
||||||
|
|
||||||
static const FString SpellTemplatesTablePath = TEXT("/Game/DataTables/SpellTemplates.SpellTemplates");
|
DEFINE_LOG_CATEGORY(LogLumiCharacter);
|
||||||
|
|
||||||
// Sets default values
|
// Sets default values
|
||||||
ALumiCharacter::ALumiCharacter()
|
ALumiCharacter::ALumiCharacter()
|
||||||
@@ -49,16 +49,7 @@ ALumiCharacter::ALumiCharacter()
|
|||||||
// Spell System
|
// Spell System
|
||||||
bIsDrawing = false;
|
bIsDrawing = false;
|
||||||
SpellRecognizer = new FUniStrokeRecognizer();
|
SpellRecognizer = new FUniStrokeRecognizer();
|
||||||
if (SpellTemplatesTable == nullptr)
|
if (SpellTemplatesTable)
|
||||||
{
|
|
||||||
SpellTemplatesTable = Cast<UDataTable>(
|
|
||||||
StaticLoadObject(
|
|
||||||
UDataTable::StaticClass(),
|
|
||||||
nullptr,
|
|
||||||
*SpellTemplatesTablePath
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
LoadSpellTemplates();
|
LoadSpellTemplates();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -76,7 +67,7 @@ void ALumiCharacter::BeginPlay()
|
|||||||
|
|
||||||
if (!GetPlayerController(LumiController))
|
if (!GetPlayerController(LumiController))
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Error, TEXT("ALumiCharacter::BeginPlay() Failed to get LumiController!"));
|
UE_LOG(LogLumiCharacter, Error, TEXT("ALumiCharacter::BeginPlay() Failed to get LumiController!"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,21 +111,19 @@ bool ALumiCharacter::IsLastJump() const
|
|||||||
|
|
||||||
void ALumiCharacter::OnGrabActionTriggered(const FInputActionValue& Value)
|
void ALumiCharacter::OnGrabActionTriggered(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Log, TEXT("Grab Triggered"));
|
UE_LOG(LogLumiCharacter, Log, TEXT("Grab Triggered"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiCharacter::OnJumpActionStarted(const FInputActionValue& Value)
|
void ALumiCharacter::OnJumpActionStarted(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
// Broadcast that the jump has started
|
// Broadcast that the jump has started
|
||||||
OnJumpStarted.Broadcast();
|
OnJumpStarted.Broadcast();
|
||||||
UE_LOG(LogTemp, Log, TEXT("Jump Started"));
|
UE_LOG(LogLumiCharacter, Log, TEXT("Jump Started"));
|
||||||
|
|
||||||
Jump();
|
Jump();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiCharacter::OnJumpActionOngoing(const FInputActionValue& Value)
|
void ALumiCharacter::OnJumpActionOngoing(const FInputActionValue& Value) {}
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALumiCharacter::OnJumpActionCompleted(const FInputActionValue& Value)
|
void ALumiCharacter::OnJumpActionCompleted(const FInputActionValue& Value)
|
||||||
{
|
{
|
||||||
@@ -182,12 +171,12 @@ void ALumiCharacter::OnLookActionTriggered(const FInputActionValue& Value)
|
|||||||
|
|
||||||
void ALumiCharacter::OnDefaultStance_Implementation()
|
void ALumiCharacter::OnDefaultStance_Implementation()
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Log, TEXT("OnDefaultStance_Implementation()"));
|
UE_LOG(LogLumiCharacter, Log, TEXT("OnDefaultStance_Implementation()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiCharacter::OnMagicStance_Implementation()
|
void ALumiCharacter::OnMagicStance_Implementation()
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Log, TEXT("OnMagicStance_Implementation()"));
|
UE_LOG(LogLumiCharacter, Log, TEXT("OnMagicStance_Implementation()"));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiCharacter::OnSpellActionStarted()
|
void ALumiCharacter::OnSpellActionStarted()
|
||||||
@@ -201,7 +190,7 @@ void ALumiCharacter::OnSpellActionCompleted()
|
|||||||
if (SpellSystemState == Casting)
|
if (SpellSystemState == Casting)
|
||||||
SpellSystemState = bIsTraining ? Training : Recognizing;
|
SpellSystemState = bIsTraining ? Training : Recognizing;
|
||||||
|
|
||||||
UE_LOG(LogTemp, Log, TEXT("OnSpellActionCompleted() Current State: %d"), SpellSystemState);
|
UE_LOG(LogLumiCharacter, Log, TEXT("OnSpellActionCompleted() Current State: %d"), SpellSystemState);
|
||||||
|
|
||||||
switch (SpellSystemState)
|
switch (SpellSystemState)
|
||||||
{
|
{
|
||||||
@@ -287,16 +276,6 @@ void ALumiCharacter::AddSpellTemplateToTable(const FString& Name)
|
|||||||
HideTrainWidget();
|
HideTrainWidget();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiCharacter::OnSpellCast_Implementation(const FString& SpellName)
|
|
||||||
{
|
|
||||||
UE_LOG(
|
|
||||||
LogTemp,
|
|
||||||
Log,
|
|
||||||
TEXT("ALumiCharacter::OnSpellCast_Implementation() Spell: %s"),
|
|
||||||
*SpellName
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ALumiCharacter::GetPlayerController(APlayerController*& LumiController) const
|
bool ALumiCharacter::GetPlayerController(APlayerController*& LumiController) const
|
||||||
{
|
{
|
||||||
LumiController = Cast<APlayerController>(this->Controller);
|
LumiController = Cast<APlayerController>(this->Controller);
|
||||||
@@ -321,19 +300,17 @@ void ALumiCharacter::LoadSpellTemplates() const
|
|||||||
void ALumiCharacter::CastSpell()
|
void ALumiCharacter::CastSpell()
|
||||||
{
|
{
|
||||||
const TArray<FVector2D>* CurrentPoints = SpellOverlay->GetSpellPoints();
|
const TArray<FVector2D>* CurrentPoints = SpellOverlay->GetSpellPoints();
|
||||||
const FUniStrokeResult Result = SpellRecognizer->Recognize(*CurrentPoints);
|
const FUniStrokeResult Result = SpellRecognizer->Recognize(*CurrentPoints, false);
|
||||||
|
|
||||||
bool bHasMatch = false;
|
bool bHasMatch = false;
|
||||||
if (Result.Score < 0.8f)
|
if (Result.Score < 0.8f)
|
||||||
{
|
{
|
||||||
UE_LOG(LogTemp, Log, TEXT("ALumiCharacter::CastSpell() No match found!"));
|
UE_LOG(LogLumiCharacter, Log, TEXT("ALumiCharacter::CastSpell() No match found!"));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bHasMatch = true;
|
bHasMatch = true;
|
||||||
UE_LOG(LogTemp, Log, TEXT("ALumiCharacter::CastSpell() Spell: %s"), *Result.Name);
|
UE_LOG(LogLumiCharacter, Log, TEXT("ALumiCharacter::CastSpell() Spell: %s"), *Result.Name);
|
||||||
|
|
||||||
OnSpellCast(Result.Name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle Spell Casting
|
// TODO: Handle Spell Casting
|
||||||
|
|||||||
@@ -15,6 +15,8 @@ class USpringArmComponent;
|
|||||||
class UCameraComponent;
|
class UCameraComponent;
|
||||||
struct FInputActionValue;
|
struct FInputActionValue;
|
||||||
|
|
||||||
|
DECLARE_LOG_CATEGORY_EXTERN(LogLumiCharacter, Log, All);
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FJumpDelegate);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FJumpDelegate);
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FStanceChangedDelegate,
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FStanceChangedDelegate,
|
||||||
@@ -143,24 +145,13 @@ public:
|
|||||||
OnSpellActionCompleted();
|
OnSpellActionCompleted();
|
||||||
void
|
void
|
||||||
OnSpellPositionActionTriggered(const FInputActionValue& Value);
|
OnSpellPositionActionTriggered(const FInputActionValue& Value);
|
||||||
void
|
|
||||||
OnSpellTrainSwitchActionCompleted();
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Spell")
|
void OnSpellTrainSwitchActionCompleted();
|
||||||
void
|
|
||||||
SetIsTraining(const bool bTraining);
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Spell")
|
void SetIsTraining(const bool bTraining);
|
||||||
void
|
void HideTrainWidget();
|
||||||
HideTrainWidget();
|
void ShowTrainWidget();
|
||||||
|
void AddSpellTemplateToTable(const FString& Name);
|
||||||
UFUNCTION(BlueprintCallable, Category = "Spell")
|
|
||||||
void
|
|
||||||
ShowTrainWidget();
|
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "Spell")
|
|
||||||
void
|
|
||||||
AddSpellTemplateToTable(const FString& Name);
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
@@ -201,10 +192,6 @@ protected:
|
|||||||
virtual void
|
virtual void
|
||||||
BeginPlay() override;
|
BeginPlay() override;
|
||||||
|
|
||||||
UFUNCTION(BlueprintNativeEvent, Category = "Spell")
|
|
||||||
void
|
|
||||||
OnSpellCast(const FString& SpellName);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool
|
bool
|
||||||
GetPlayerController(APlayerController*& LumiController) const;
|
GetPlayerController(APlayerController*& LumiController) const;
|
||||||
|
|||||||
@@ -30,11 +30,6 @@ void ALumiController::GetLumiCharacter(ALumiCharacter*& OutLumiCharacter) const
|
|||||||
OutLumiCharacter = LumiCharacter;
|
OutLumiCharacter = LumiCharacter;
|
||||||
}
|
}
|
||||||
|
|
||||||
ALumiCharacter* ALumiController::GetLumiCharacter() const
|
|
||||||
{
|
|
||||||
return LumiCharacter;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ALumiController::OnPossess(APawn* InPawn)
|
void ALumiController::OnPossess(APawn* InPawn)
|
||||||
{
|
{
|
||||||
Super::OnPossess(InPawn);
|
Super::OnPossess(InPawn);
|
||||||
@@ -104,8 +99,8 @@ void ALumiController::OnPossess(APawn* InPawn)
|
|||||||
{
|
{
|
||||||
EnhancedInputComponent->BindAction(SpellAction,
|
EnhancedInputComponent->BindAction(SpellAction,
|
||||||
ETriggerEvent::Started,
|
ETriggerEvent::Started,
|
||||||
this,
|
LumiCharacter,
|
||||||
&ALumiController::OnSpellActionStarted);
|
&ALumiCharacter::OnSpellActionStarted);
|
||||||
EnhancedInputComponent->BindAction(SpellAction,
|
EnhancedInputComponent->BindAction(SpellAction,
|
||||||
ETriggerEvent::Completed,
|
ETriggerEvent::Completed,
|
||||||
this,
|
this,
|
||||||
@@ -133,12 +128,12 @@ void ALumiController::OnUnPossess()
|
|||||||
|
|
||||||
void ALumiController::OnSpellActionStarted()
|
void ALumiController::OnSpellActionStarted()
|
||||||
{
|
{
|
||||||
// ShowMouseCursor();
|
ShowMouseCursor();
|
||||||
LumiCharacter->OnSpellActionStarted();
|
LumiCharacter->OnSpellActionStarted();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ALumiController::OnSpellActionCompleted()
|
void ALumiController::OnSpellActionCompleted()
|
||||||
{
|
{
|
||||||
LumiCharacter->OnSpellActionCompleted();
|
LumiCharacter->OnSpellActionCompleted();
|
||||||
// HideMouseCursor();
|
HideMouseCursor();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,10 +60,6 @@ public:
|
|||||||
void
|
void
|
||||||
GetLumiCharacter(ALumiCharacter*& OutLumiCharacter) const;
|
GetLumiCharacter(ALumiCharacter*& OutLumiCharacter) const;
|
||||||
|
|
||||||
UFUNCTION(BlueprintCallable, Category = "LumiController")
|
|
||||||
ALumiCharacter*
|
|
||||||
GetLumiCharacter() const;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void
|
virtual void
|
||||||
OnPossess(APawn* InPawn) override;
|
OnPossess(APawn* InPawn) override;
|
||||||
|
|||||||
@@ -1,27 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "UObject/Interface.h"
|
|
||||||
#include "SpellInteractable.generated.h"
|
|
||||||
|
|
||||||
UINTERFACE(MinimalAPI, Blueprintable)
|
|
||||||
class USpellInteractable : public UInterface
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interface for objects that can be interacted with by spells.
|
|
||||||
*/
|
|
||||||
class WIZARDINGCENTRAL_API ISpellInteractable
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
/**
|
|
||||||
* Called when the spell is cast on the object.
|
|
||||||
* @param SpellName The name of the spell that was cast.
|
|
||||||
*/
|
|
||||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable, Category = "Spell")
|
|
||||||
void OnSpellCast(const FString& SpellName);
|
|
||||||
};
|
|
||||||
@@ -1,24 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
|
|
||||||
#include "SpellInteractableActor.h"
|
|
||||||
|
|
||||||
|
|
||||||
// Sets default values
|
|
||||||
ASpellInteractableActor::ASpellInteractableActor()
|
|
||||||
{
|
|
||||||
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
|
|
||||||
PrimaryActorTick.bCanEverTick = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called when the game starts or when spawned
|
|
||||||
void ASpellInteractableActor::BeginPlay()
|
|
||||||
{
|
|
||||||
Super::BeginPlay();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Called every frame
|
|
||||||
void ASpellInteractableActor::Tick(float DeltaTime)
|
|
||||||
{
|
|
||||||
Super::Tick(DeltaTime);
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
// Fill out your copyright notice in the Description page of Project Settings.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "CoreMinimal.h"
|
|
||||||
#include "SpellInteractable.h"
|
|
||||||
#include "GameFramework/Actor.h"
|
|
||||||
#include "SpellInteractableActor.generated.h"
|
|
||||||
|
|
||||||
UCLASS()
|
|
||||||
class WIZARDINGCENTRAL_API ASpellInteractableActor : public AActor,
|
|
||||||
public ISpellInteractable
|
|
||||||
{
|
|
||||||
GENERATED_BODY()
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Sets default values for this actor's properties
|
|
||||||
ASpellInteractableActor();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
// Called when the game starts or when spawned
|
|
||||||
virtual void BeginPlay() override;
|
|
||||||
|
|
||||||
public:
|
|
||||||
// Called every frame
|
|
||||||
virtual void Tick(float DeltaTime) override;
|
|
||||||
};
|
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "UniStrokePoint.h"
|
#include "UniStrokePoint.h"
|
||||||
|
|
||||||
|
#include "ScreenPass.h"
|
||||||
|
|
||||||
FUniStrokePoint::FUniStrokePoint()
|
FUniStrokePoint::FUniStrokePoint()
|
||||||
{
|
{
|
||||||
this->X = 0.0f;
|
this->X = 0.0f;
|
||||||
@@ -47,7 +49,9 @@ FUniStrokePoint::BoundingBox(const TArray<FUniStrokePoint>& Points)
|
|||||||
{
|
{
|
||||||
// Edge case
|
// Edge case
|
||||||
if (Points.Num() == 0)
|
if (Points.Num() == 0)
|
||||||
|
{
|
||||||
return FUniStrokeRectangle();
|
return FUniStrokeRectangle();
|
||||||
|
}
|
||||||
|
|
||||||
float MinX = Points[0].X;
|
float MinX = Points[0].X;
|
||||||
float MinY = Points[0].Y;
|
float MinY = Points[0].Y;
|
||||||
@@ -82,16 +86,14 @@ FUniStrokePoint::Vectorize(const TArray<FUniStrokePoint>& Points)
|
|||||||
const float Magnitude = FMath::Sqrt(Sum);
|
const float Magnitude = FMath::Sqrt(Sum);
|
||||||
|
|
||||||
for (float& V : Vector)
|
for (float& V : Vector)
|
||||||
|
{
|
||||||
V /= Magnitude;
|
V /= Magnitude;
|
||||||
|
}
|
||||||
|
|
||||||
return Vector;
|
return Vector;
|
||||||
}
|
}
|
||||||
|
|
||||||
FString FUniStrokePoint::ToString() const
|
// TODO: Proofread this function
|
||||||
{
|
|
||||||
return FString::Printf(TEXT("X=%.3f Y=%.3f"), X, Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
float
|
float
|
||||||
FUniStrokePoint::OptimalCosineDistance(const TArray<float>& VectorA,
|
FUniStrokePoint::OptimalCosineDistance(const TArray<float>& VectorA,
|
||||||
const TArray<float>& VectorB)
|
const TArray<float>& VectorB)
|
||||||
@@ -171,7 +173,9 @@ FUniStrokePoint::Resample(TArray<FUniStrokePoint>& Points,
|
|||||||
|
|
||||||
// Edge case
|
// Edge case
|
||||||
if (Points.Num() == Num - 1)
|
if (Points.Num() == Num - 1)
|
||||||
|
{
|
||||||
Points.Add(OldPoints.Last());
|
Points.Add(OldPoints.Last());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
@@ -381,7 +385,9 @@ FUniStrokePoint::PathDistance(const TArray<FUniStrokePoint>& PathA,
|
|||||||
{
|
{
|
||||||
// Edge case: Different number of points
|
// Edge case: Different number of points
|
||||||
if (PathA.Num() != PathB.Num())
|
if (PathA.Num() != PathB.Num())
|
||||||
|
{
|
||||||
return TNumericLimits<float>::Max();
|
return TNumericLimits<float>::Max();
|
||||||
|
}
|
||||||
|
|
||||||
// d <- 0
|
// d <- 0
|
||||||
float d = 0;
|
float d = 0;
|
||||||
|
|||||||
@@ -84,9 +84,6 @@ struct WIZARDINGCENTRAL_API FUniStrokePoint
|
|||||||
static TArray<float>
|
static TArray<float>
|
||||||
Vectorize(const TArray<FUniStrokePoint>& Points);
|
Vectorize(const TArray<FUniStrokePoint>& Points);
|
||||||
|
|
||||||
FString
|
|
||||||
ToString() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float X;
|
float X;
|
||||||
float Y;
|
float Y;
|
||||||
|
|||||||
@@ -12,13 +12,16 @@ FUniStrokeRecognizer::~FUniStrokeRecognizer()
|
|||||||
|
|
||||||
// TODO: Review this function
|
// TODO: Review this function
|
||||||
FUniStrokeResult
|
FUniStrokeResult
|
||||||
FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints)
|
FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints,
|
||||||
|
const bool& UseProtractor)
|
||||||
{
|
{
|
||||||
TArray<FUniStrokePoint> Points = FUniStrokePoint::From(VectorPoints);
|
TArray<FUniStrokePoint> Points = FUniStrokePoint::From(VectorPoints);
|
||||||
|
|
||||||
// Edge case: Not enough points
|
// Edge case: Not enough points
|
||||||
if (Points.Num() < 2 || FUniStrokePoint::PathLength(Points) < 100.0f)
|
if (Points.Num() < 2 || FUniStrokePoint::PathLength(Points) < 100.0f)
|
||||||
|
{
|
||||||
return FUniStrokeResult("Too few points made", 0.0);
|
return FUniStrokeResult("Too few points made", 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
const FUniStrokeTemplate Candidate = FUniStrokeTemplate("", Points);
|
const FUniStrokeTemplate Candidate = FUniStrokeTemplate("", Points);
|
||||||
int TemplateIndex = -1;
|
int TemplateIndex = -1;
|
||||||
@@ -30,7 +33,12 @@ FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints)
|
|||||||
for (int i = 0; i < Templates.Num(); i++)
|
for (int i = 0; i < Templates.Num(); i++)
|
||||||
{
|
{
|
||||||
// d <- DistanceAtBestAngle(points, T, -theta, theta, threshold)
|
// d <- DistanceAtBestAngle(points, T, -theta, theta, threshold)
|
||||||
const float d = FUniStrokePoint::DistanceAtBestAngle(
|
const float d = UseProtractor
|
||||||
|
? FUniStrokePoint::OptimalCosineDistance(
|
||||||
|
Templates[i].Vector,
|
||||||
|
Candidate.Vector
|
||||||
|
)
|
||||||
|
: FUniStrokePoint::DistanceAtBestAngle(
|
||||||
Candidate.Points,
|
Candidate.Points,
|
||||||
Templates[i].Points,
|
Templates[i].Points,
|
||||||
-AngleRange,
|
-AngleRange,
|
||||||
@@ -49,8 +57,7 @@ FUniStrokeRecognizer::Recognize(const TArray<FVector2D>& VectorPoints)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// score <- 1 – b / 0.5 sqrt(size^2 + size^2)
|
// score <- 1 – b / 0.5 sqrt(size^2 + size^2)
|
||||||
static const float HalfDiagonal = 0.5 * FMath::Sqrt(2 * FMath::Square(SquareSize));
|
const float Score = UseProtractor ? 1.0 - b : 1.0 - b / HalfDiagonal;
|
||||||
const float Score = 1.0 - b / HalfDiagonal;
|
|
||||||
|
|
||||||
// return <T', score>
|
// return <T', score>
|
||||||
return TemplateIndex == -1
|
return TemplateIndex == -1
|
||||||
|
|||||||
@@ -8,6 +8,8 @@
|
|||||||
#include "UniStrokeRecognizer.generated.h"
|
#include "UniStrokeRecognizer.generated.h"
|
||||||
|
|
||||||
static constexpr int NumTemplates = 16;
|
static constexpr int NumTemplates = 16;
|
||||||
|
static const float Diagonal = FMath::Sqrt(2 * FMath::Square(SquareSize));
|
||||||
|
static const float HalfDiagonal = 0.5 * Diagonal;
|
||||||
static constexpr float AngleRange = FMath::DegreesToRadians(45.0);
|
static constexpr float AngleRange = FMath::DegreesToRadians(45.0);
|
||||||
static constexpr float AnglePrecision = FMath::DegreesToRadians(2.0);
|
static constexpr float AnglePrecision = FMath::DegreesToRadians(2.0);
|
||||||
|
|
||||||
@@ -20,7 +22,7 @@ struct WIZARDINGCENTRAL_API FUniStrokeRecognizer
|
|||||||
~FUniStrokeRecognizer();
|
~FUniStrokeRecognizer();
|
||||||
|
|
||||||
FUniStrokeResult
|
FUniStrokeResult
|
||||||
Recognize(const TArray<FVector2D>& VectorPoints);
|
Recognize(const TArray<FVector2D>& VectorPoints, const bool& UseProtractor);
|
||||||
|
|
||||||
void
|
void
|
||||||
AddTemplate(const FString& Name, const TArray<FVector2D>& VectorPoints);
|
AddTemplate(const FString& Name, const TArray<FVector2D>& VectorPoints);
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ FUniStrokeTemplate::FUniStrokeTemplate()
|
|||||||
}
|
}
|
||||||
|
|
||||||
FUniStrokeTemplate::FUniStrokeTemplate(const FString& Name,
|
FUniStrokeTemplate::FUniStrokeTemplate(const FString& Name,
|
||||||
const TArray<FUniStrokePoint>& Points)
|
const TArray<FUniStrokePoint>)
|
||||||
{
|
{
|
||||||
this->Name = Name;
|
this->Name = Name;
|
||||||
this->Points = Points;
|
this->Points = Points;
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ struct WIZARDINGCENTRAL_API FUniStrokeTemplate
|
|||||||
|
|
||||||
FUniStrokeTemplate();
|
FUniStrokeTemplate();
|
||||||
FUniStrokeTemplate(const FString& Name,
|
FUniStrokeTemplate(const FString& Name,
|
||||||
const TArray<FUniStrokePoint>& Points);
|
const TArray<FUniStrokePoint>);
|
||||||
~FUniStrokeTemplate();
|
~FUniStrokeTemplate();
|
||||||
|
|
||||||
FString Name;
|
FString Name;
|
||||||
|
|||||||
Reference in New Issue
Block a user