// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
#pragma once
#include "Engine/Scripting/ScriptingObject.h"
#include "NavigationTypes.h"
class NavMesh;
class NavMeshRuntime;
class dtCrowd;
struct dtCrowdAgentParams;
///
/// Navigation steering behaviors system for a group of agents. Handles avoidance between agents by using an adaptive RVO sampling calculation.
///
API_CLASS() class FLAXENGINE_API NavCrowd : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(NavCrowd);
private:
dtCrowd* _crowd;
public:
~NavCrowd();
///
/// Initializes the crowd.
///
/// The maximum radius of any agent that will be added to the crowd.
/// maximum number of agents the crowd can manage.
/// The navigation mesh to use for crowd movement planning. Use null to pick the first navmesh.
/// True if failed, otherwise false.
API_FUNCTION() bool Init(float maxAgentRadius = 100.0f, int32 maxAgents = 25, NavMesh* navMesh = nullptr);
///
/// Initializes the crowd.
///
/// The properties of the agents that will be added to the crowd.
/// maximum number of agents the crowd can manage.
/// True if failed, otherwise false.
API_FUNCTION() bool Init(const NavAgentProperties& agentProperties, int32 maxAgents = 25);
///
/// Initializes the crowd.
///
/// The maximum radius of any agent that will be added to the crowd.
/// maximum number of agents the crowd can manage.
/// The navigation mesh to use for crowd movement planning.
/// True if failed, otherwise false.
bool Init(float maxAgentRadius, int32 maxAgents, NavMeshRuntime* navMesh);
///
/// Adds a new agent to the crowd.
///
/// The agent position.
/// The agent properties.
/// The agent unique ID or -1 if failed to add it (eg. too many active agents).
API_FUNCTION() int32 AddAgent(const Vector3& position, const NavAgentProperties& properties);
///
/// Gets the agent current position.
///
/// The agent ID.
/// The agent current position.
API_FUNCTION() Vector3 GetAgentPosition(int32 id) const;
///
/// Gets the agent current velocity (direction * speed).
///
/// The agent ID.
/// The agent current velocity (direction * speed).
API_FUNCTION() Vector3 GetAgentVelocity(int32 id) const;
///
/// Updates the agent properties.
///
/// The agent ID.
/// The agent properties.
API_FUNCTION() void SetAgentProperties(int32 id, const NavAgentProperties& properties);
///
/// Updates the agent movement target position.
///
/// The agent ID.
/// The agent target position.
API_FUNCTION() void SetAgentMoveTarget(int32 id, const Vector3& position);
///
/// Updates the agent movement target velocity (direction * speed).
///
/// The agent ID.
/// The agent target velocity (direction * speed).
API_FUNCTION() void SetAgentMoveVelocity(int32 id, const Vector3& velocity);
///
/// Resets any movement request for the specified agent.
///
/// The agent ID.
API_FUNCTION() void ResetAgentMove(int32 id);
///
/// Removes the agent of the given ID.
///
API_FUNCTION() void RemoveAgent(int32 id);
///
/// Updates the steering and positions of all agents.
///
/// The simulation update delta time (in seconds).
API_FUNCTION() void Update(float dt);
private:
void InitCrowdAgentParams(dtCrowdAgentParams& agentParams, const NavAgentProperties& properties);
};