Creating a new Context Steering behaviour
A context steering module fills the interest and the danger map.
This is an example of a module that fills the interest map. It takes the main direction and apply a dot product between the direction and the rays.
(Remember to add “AtomsUnreal” and “AtomsRealtime” to the dependency of you plugin/project)
#pragma once
#include "CoreMinimal.h"
#include "AtomsUnreal/Public/ContextSteering/AtomsContextSteeringBehaviour.h"
#include "AtomsContextSteeringMyDirectionBehaviour.generated.h"
/* Take the input agent direction and do a dot with the samples in the angle range, starting form the forward sample 0.*/
UCLASS(DefaultToInstanced, editinlinenew, DisplayName = "My Direction")
class UAtomsContextSteeringMyDirectionBehaviour : public UAtomsContextSteeringBehaviour
{
GENERATED_BODY()
public:
/** Angle used to reduce the interest values, decrease the interest value from 1 to 0 insdie hte angle range*/
UPROPERTY(EditAnywhere, Category = "Behaviour")
float Angle;
/** Teh angle coudl be controlled by a metadata if the agent has a double metadat with this name*/
UPROPERTY(EditAnywhere, Category = "Behaviour")
FString Metadata;
UAtomsContextSteeringMyDirectionBehaviour();
virtual void Initialize(class UContextSteering_BehaviourComponent* ParentComponent) override;
virtual void Evaluate(Atoms::AgentGroup* AgentGroup, Atoms::Agent* Agent, const float DeltaTime) override;
private:
std::string m_metadataName;
};
#include "AtomsContextSteeringMyDirectionBehaviour.h"
#include <AtomsCore/Metadata/DoubleMetadata.h>
UAtomsContextSteeringMyDirectionBehaviour::UAtomsContextSteeringMyDirectionBehaviour() :
Angle(180.0f)
{
}
void UAtomsContextSteeringMyDirectionBehaviour::Initialize(class UContextSteering_BehaviourComponent* ParentComponent)
{
if (!Metadata.IsEmpty())
m_metadataName = TCHAR_TO_UTF8(*Metadata);
else
m_metadataName.clear();
}
void UAtomsContextSteeringMyDirectionBehaviour::Evaluate(Atoms::AgentGroup* AgentGroup, Atoms::Agent* Agent, const float DeltaTime)
{
Atoms::ContextSteeringData& data = Agent->contextSteeringData();
auto& samplesMap = data.samples;
auto& interestMap = data.interest;
const AtomsMath::Vector3& Direction = Agent->direction()->get();
float AngleValue = Angle;
if (!m_metadataName.empty())
{
AtomsCore::DoubleMetadata* angleMeta = Agent->metadata().getTypedEntryRaw<AtomsCore::DoubleMetadata>(m_metadataName);
AngleValue = angleMeta ? angleMeta->value() : AngleValue;
}
AtomsMath::Quaternion quat;
if (AngleValue < 179.9)
{
float AngleRad = FMath::DegreesToRadians(AngleValue);
for (size_t j = 0; j < interestMap.size(); ++j)
{
quat.setAxisAngle(data.up, samplesMap[j]);
AtomsMath::Vector3 sample_direction = quat.rotateVector(data.direction);
double CurrentAngle = FMath::Acos(FMath::Min(FMath::Max(-1.0, Direction.dot(sample_direction)), 1.0));
interestMap[j] = (FMath::Cos(FMath::Min(M_PI, CurrentAngle * M_PI / AngleRad)) * 0.5 + 0.5) * data.distance;
}
}
else
{
for (size_t j = 0; j < interestMap.size(); ++j)
{
quat.setAxisAngle(data.up, samplesMap[j]);
AtomsMath::Vector3 sample_direction = quat.rotateVector(data.direction);
interestMap[j] = (Direction.dot(sample_direction) * 0.5 + 0.5) * data.distance;
}
}
}
Instead, this module fills the danger map using the result of the line trace method.
#pragma once
#include "CoreMinimal.h"
#include "Engine/EngineTypes.h"
#include "AtomsUnreal/Public/ContextSteering/AtomsContextSteeringBehaviour.h"
#include "AtomsContextSteeringMyLineTraceAvoidanceBehaviour.generated.h"
/* Filter the inreset/danger map using a gauss filter*/
UCLASS(DefaultToInstanced, editinlinenew, DisplayName = "My Line Trace Avoidance")
class UAtomsContextSteeringMyLineTraceAvoidanceBehaviour : public UAtomsContextSteeringBehaviour
{
GENERATED_BODY()
public:
/** Collision channel used by the line trace */
UPROPERTY(EditAnywhere, Category = "Behaviour")
TEnumAsByte<enum ECollisionChannel> CollisionChannel;
/** Height offset */
UPROPERTY(EditAnywhere, Category = "Behaviour")
float HeightOffset;
UAtomsContextSteeringMyLineTraceAvoidanceBehaviour();
virtual void Initialize(class UContextSteering_BehaviourComponent* ParentComponent) override;
virtual void Evaluate(Atoms::AgentGroup* AgentGroup, Atoms::Agent* Agent, const float DeltaTime) override;
private:
class UWorld* World;
};
Copyright © 2017, Toolchefs LTD.