356 lines
9.7 KiB
C
356 lines
9.7 KiB
C
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "MassEntityHandle.h"
|
|
#include "MassEntityTypes.h"
|
|
#include "MassCommonTypes.h"
|
|
#include "MassLookAtTypes.h"
|
|
#include "ZoneGraphTypes.h"
|
|
#include "Containers/StaticArray.h"
|
|
#include "MassLookAtFragments.generated.h"
|
|
|
|
#define UE_API MASSAIBEHAVIOR_API
|
|
|
|
/** Primary look at mode, gazing can be applied on top. */
|
|
UENUM()
|
|
enum class EMassLookAtMode : uint8
|
|
{
|
|
/** Look forward */
|
|
LookForward,
|
|
/** Look along the current path */
|
|
LookAlongPath,
|
|
/** Track specified entity */
|
|
LookAtEntity,
|
|
};
|
|
|
|
/** Different gaze modes applied on top of the look at mode. */
|
|
UENUM()
|
|
enum class EMassLookAtGazeMode : uint8
|
|
{
|
|
/** No gazing */
|
|
None,
|
|
/** Look constantly in gaze direction until next gaze target is picked. */
|
|
Constant,
|
|
/** Quick look at gaze target, ease in back to main look direction. */
|
|
Glance,
|
|
};
|
|
|
|
/**
|
|
* Struct that holds all parameters of the current entity look at
|
|
*/
|
|
USTRUCT()
|
|
struct FMassLookAtFragment : public FMassFragment
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Resets gaze related properties in the fragment to their default values */
|
|
void ResetGaze()
|
|
{
|
|
GazeTargetLocation = FVector::ZeroVector;
|
|
GazeDirection = FVector::ForwardVector;
|
|
GazeTrackedEntity.Reset();
|
|
GazeStartTime = 0.0f;
|
|
GazeDuration = 0.0f;
|
|
RandomGazeMode = EMassLookAtGazeMode::None;
|
|
RandomGazeYawVariation = 0;
|
|
RandomGazePitchVariation = 0;
|
|
bRandomGazeEntities = false;
|
|
}
|
|
|
|
/** Resets all properties in the fragment to their default values */
|
|
void ResetAll()
|
|
{
|
|
ResetMainLookAt();
|
|
ResetGaze();
|
|
}
|
|
|
|
/** Resets main LookAt related properties in the fragment to their default values */
|
|
void ResetMainLookAt()
|
|
{
|
|
MainTargetLocation = FVector::ZeroVector;
|
|
Direction = FVector::ForwardVector;
|
|
TrackedEntity.Reset();
|
|
LastSeenActionID = 0;
|
|
LookAtMode = EMassLookAtMode::LookForward;
|
|
}
|
|
|
|
/** Resets gaze and main LookAt (if override not active) related properties in the fragment to their default values */
|
|
void ResetSystemicLookAt()
|
|
{
|
|
if (OverrideState == EOverrideState::ActiveSystemicOnly
|
|
|| OverrideState == EOverrideState::OverridenSystemic
|
|
|| OverrideState == EOverrideState::PendingSystemicReactivation)
|
|
{
|
|
ResetGaze();
|
|
|
|
// Only reset main LookAt properties if no override is active.
|
|
// In that case it will be handled by the LookAtSubsystem when updating the override requests.
|
|
if (OverrideState == EOverrideState::ActiveSystemicOnly
|
|
|| OverrideState == EOverrideState::PendingSystemicReactivation)
|
|
{
|
|
ResetMainLookAt();
|
|
OverrideState = EOverrideState::AllDisabled;
|
|
}
|
|
else
|
|
{
|
|
OverrideState = EOverrideState::ActiveOverrideOnly;
|
|
}
|
|
}
|
|
}
|
|
|
|
/** Current look at main target location. */
|
|
UPROPERTY(Transient)
|
|
FVector MainTargetLocation = FVector::ZeroVector;
|
|
|
|
/** Current gaze target location. */
|
|
UPROPERTY(Transient)
|
|
FVector GazeTargetLocation = FVector::ZeroVector;
|
|
|
|
/** Current look at direction (with gaze applied). */
|
|
UPROPERTY(Transient)
|
|
FVector Direction = FVector::ForwardVector;
|
|
|
|
/** Current gaze direction, applied on top of look at direction based on gaze mode. */
|
|
UPROPERTY(Transient)
|
|
FVector GazeDirection = FVector::ForwardVector;
|
|
|
|
/** Specific entity that is being tracked as primary look at. */
|
|
UPROPERTY(Transient)
|
|
FMassEntityHandle TrackedEntity;
|
|
|
|
/** Entity that is tracked as part of gazing. */
|
|
UPROPERTY(Transient)
|
|
FMassEntityHandle GazeTrackedEntity;
|
|
|
|
/** Start time of the current gaze. */
|
|
UPROPERTY(Transient)
|
|
double GazeStartTime = 0.;
|
|
|
|
/** Duration of the current gaze. */
|
|
UPROPERTY(Transient)
|
|
float GazeDuration = 0.0f;
|
|
|
|
/** Last seen action ID, used to check when look at trajectory needs to be updated. */
|
|
UPROPERTY(Transient)
|
|
uint16 LastSeenActionID = 0;
|
|
|
|
/** Primary look at mode. */
|
|
UPROPERTY(Transient)
|
|
EMassLookAtMode LookAtMode = EMassLookAtMode::LookForward;
|
|
|
|
/** Primary look at interpolation speed (not used by the LookAt processor but can be forwarded to the animation system). */
|
|
UPROPERTY(Transient)
|
|
EMassLookAtInterpolationSpeed InterpolationSpeed = EMassLookAtInterpolationSpeed::Regular;
|
|
|
|
/**
|
|
* Primary look at custom interpolation speed used when 'InterpolationSpeed = EMassLookAtInterpolationSpeed::Custom'
|
|
* (not used by the LookAt processor but can be forwarded to the animation system).
|
|
*/
|
|
UPROPERTY(Transient)
|
|
float CustomInterpolationSpeed = UE::Mass::LookAt::DefaultCustomInterpolationSpeed;
|
|
|
|
/** Gaze look at mode. */
|
|
UPROPERTY(Transient)
|
|
EMassLookAtGazeMode RandomGazeMode = EMassLookAtGazeMode::None;
|
|
|
|
/** Random gaze angle yaw variation (in degrees). */
|
|
UPROPERTY(Transient)
|
|
uint8 RandomGazeYawVariation = 0;
|
|
|
|
/** Random gaze angle pitch variation (in degrees). */
|
|
UPROPERTY(Transient)
|
|
uint8 RandomGazePitchVariation = 0;
|
|
|
|
/** Whether random gaze can also pick interesting entities to look at. */
|
|
UPROPERTY(Transient)
|
|
uint8 bRandomGazeEntities : 1 = false;
|
|
|
|
enum class EOverrideState : uint8
|
|
{
|
|
/** No active task and no active override */
|
|
AllDisabled,
|
|
|
|
/** No active task, only an active override */
|
|
ActiveOverrideOnly,
|
|
|
|
/** Active task only, no active override */
|
|
ActiveSystemicOnly,
|
|
|
|
/** Active task overriden */
|
|
OverridenSystemic,
|
|
|
|
/**
|
|
* Intermediate state used from 'OverridenSystemic' after removing last override request
|
|
* to allow active task to reapply its values and transition to 'ActiveSystemicOnly'
|
|
*/
|
|
PendingSystemicReactivation
|
|
};
|
|
|
|
/** Current state based on the systemic task and active overrides */
|
|
EOverrideState OverrideState : 7 = EOverrideState::AllDisabled;
|
|
};
|
|
|
|
/**
|
|
* Special tag to mark an entity that could be tracked by the LookAt
|
|
*/
|
|
USTRUCT()
|
|
struct UE_DEPRECATED(5.6, "Use FMassLookAtTargetFragment instead") MASSAIBEHAVIOR_API FMassLookAtTargetTag : public FMassTag
|
|
{
|
|
GENERATED_BODY()
|
|
};
|
|
|
|
/**
|
|
* Struct that holds all parameters of a look at request
|
|
*/
|
|
USTRUCT()
|
|
struct FMassLookAtRequestFragment : public FMassFragment
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FMassLookAtRequestFragment() = default;
|
|
FMassLookAtRequestFragment(const FMassEntityHandle ViewerEntity, const FMassLookAtPriority Priority, const EMassLookAtMode Mode)
|
|
: ViewerEntity(ViewerEntity)
|
|
, Priority(Priority)
|
|
, LookAtMode(Mode)
|
|
{
|
|
}
|
|
|
|
FMassLookAtRequestFragment(
|
|
const FMassEntityHandle ViewerEntity
|
|
, const FMassLookAtPriority Priority
|
|
, const EMassLookAtMode Mode
|
|
, const FMassEntityHandle Target
|
|
, const EMassLookAtInterpolationSpeed InterpolationSpeed
|
|
, const float CustomInterpolationSpeed)
|
|
: FMassLookAtRequestFragment(ViewerEntity, Priority, Mode)
|
|
{
|
|
TargetEntity = Target;
|
|
this->InterpolationSpeed = InterpolationSpeed;
|
|
this->CustomInterpolationSpeed = CustomInterpolationSpeed;
|
|
}
|
|
|
|
UPROPERTY(Transient)
|
|
FMassEntityHandle ViewerEntity;
|
|
|
|
UPROPERTY(Transient)
|
|
FMassEntityHandle TargetEntity;
|
|
|
|
UPROPERTY(Transient)
|
|
FMassLookAtPriority Priority{static_cast<uint8>(EMassLookAtPriorities::LowestPriority)};
|
|
|
|
UPROPERTY(Transient)
|
|
EMassLookAtMode LookAtMode = EMassLookAtMode::LookForward;
|
|
|
|
UPROPERTY(Transient)
|
|
EMassLookAtInterpolationSpeed InterpolationSpeed = EMassLookAtInterpolationSpeed::Regular;
|
|
|
|
UPROPERTY(Transient)
|
|
float CustomInterpolationSpeed = UE::Mass::LookAt::DefaultCustomInterpolationSpeed;
|
|
|
|
friend FString LexToString(const FMassLookAtRequestFragment& Fragment)
|
|
{
|
|
if (Fragment.LookAtMode == EMassLookAtMode::LookAtEntity)
|
|
{
|
|
return FString::Printf(TEXT("Priority = %d Mode = %s Target = [%s]")
|
|
, Fragment.Priority.Get()
|
|
, *UEnum::GetValueAsString(Fragment.LookAtMode)
|
|
, *LexToString(Fragment.TargetEntity));
|
|
}
|
|
|
|
return FString::Printf(TEXT("Priority=%d Mode=%s")
|
|
, Fragment.Priority.Get()
|
|
, *UEnum::GetValueAsString(Fragment.LookAtMode));
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Fragment to mark an entity that could be tracked by the LookAt processor
|
|
* and providing information that could be used to get more accurate locations.
|
|
*/
|
|
USTRUCT()
|
|
struct FMassLookAtTargetFragment : public FMassFragment
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
/** Offset in local space to add to the target transform to get the final location */
|
|
UPROPERTY(Transient)
|
|
FVector Offset = FVector::ZeroVector;
|
|
|
|
/** When a viewer is searching for a random target this priority will influence the selected target */
|
|
UPROPERTY(Transient)
|
|
FMassLookAtPriority Priority{static_cast<uint8>(EMassLookAtPriorities::LowestPriority)};
|
|
|
|
UE::Mass::LookAt::FTargetHashGrid2D::FCellLocation CellLocation;
|
|
};
|
|
|
|
/** Tag to tell if the entity is in the LookAt target grid */
|
|
USTRUCT()
|
|
struct FMassInLookAtTargetGridTag : public FMassTag
|
|
{
|
|
GENERATED_BODY()
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMassLookAtTrajectoryPoint
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
void Set(const FVector InPosition, const FVector2D InTangent, const float InDistanceAlongLane)
|
|
{
|
|
Position = InPosition;
|
|
Tangent.Set(InTangent);
|
|
DistanceAlongLane.Set(InDistanceAlongLane);
|
|
}
|
|
|
|
/** Position of the path. */
|
|
FVector Position = FVector::ZeroVector;
|
|
|
|
/** Tangent direction of the path. */
|
|
FMassSnorm8Vector2D Tangent;
|
|
|
|
/** Position of the point along the original path. (Could potentially be uint16 at 10cm accuracy) */
|
|
FMassInt16Real10 DistanceAlongLane = FMassInt16Real10(0.0f);
|
|
};
|
|
|
|
USTRUCT()
|
|
struct FMassLookAtTrajectoryFragment : public FMassFragment
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
FMassLookAtTrajectoryFragment() = default;
|
|
|
|
static constexpr uint8 MaxPoints = 3;
|
|
|
|
void Reset()
|
|
{
|
|
NumPoints = 0;
|
|
}
|
|
|
|
bool AddPoint(const FVector Position, const FVector2D Tangent, const float DistanceAlongLane)
|
|
{
|
|
if (NumPoints < MaxPoints)
|
|
{
|
|
FMassLookAtTrajectoryPoint& Point = Points[NumPoints++];
|
|
Point.Set(Position, Tangent, DistanceAlongLane);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UE_API FVector GetPointAtDistanceExtrapolated(const float DistanceAlongPath) const;
|
|
|
|
/** Path points */
|
|
TStaticArray<FMassLookAtTrajectoryPoint, MaxPoints> Points;
|
|
|
|
/** Lane handle the trajectory was build for. */
|
|
FZoneGraphLaneHandle LaneHandle;
|
|
|
|
/** Number of points on path. */
|
|
uint8 NumPoints = 0;
|
|
|
|
bool bMoveReverse = false;
|
|
};
|
|
|
|
#undef UE_API
|