Compare commits
1 Commits
main
...
SP3-22-aia
Author | SHA1 | Date |
---|---|---|
Xiao Qi | 1c004c787a |
|
@ -0,0 +1,81 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHBehaviourTreeAgent.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Function definitions for Behaviour tree agent
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHBehaviourTreeAgent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Param ctor for agent to take in reference to a tree
|
||||||
|
*
|
||||||
|
* \param tree - pointer to tree data. nullptr if no trees
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent::SHBehaviourTreeAgent(std::shared_ptr<SHBehaviourTree> tree)
|
||||||
|
: treeRef{ tree }, current{ treeRef->GetRoot() }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy ctor.
|
||||||
|
*
|
||||||
|
* \param ref - agent to copy from
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent::SHBehaviourTreeAgent(SHBehaviourTreeAgent const& ref)
|
||||||
|
: treeRef{ ref.treeRef}, current{ treeRef->GetRoot() }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy assignment operator overload.
|
||||||
|
*
|
||||||
|
* \param ref - agent to copy from
|
||||||
|
* \return reference to current object
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent& SHBehaviourTreeAgent::operator=(SHBehaviourTreeAgent const& ref)
|
||||||
|
{
|
||||||
|
treeRef = ref.treeRef;
|
||||||
|
current = ref.current;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shift current node to next node.
|
||||||
|
*
|
||||||
|
* \param next - node to shift to
|
||||||
|
* \return vector of scripts that need to be run at next node
|
||||||
|
*/
|
||||||
|
MonoMVector SHBehaviourTreeAgent::Transit(SHBehaviourTree::Leaf next) noexcept
|
||||||
|
{
|
||||||
|
current = next;
|
||||||
|
return current->scripts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current Node.
|
||||||
|
*
|
||||||
|
* \return Pointer to behaviour tree leaf
|
||||||
|
*/
|
||||||
|
SHBehaviourTree::Leaf SHBehaviourTreeAgent::GetCurrent() noexcept
|
||||||
|
{
|
||||||
|
return current;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if pointer to tree is a nullptr.
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool SHBehaviourTreeAgent::isEmpty() const noexcept
|
||||||
|
{
|
||||||
|
return treeRef == nullptr;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,77 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHBehaviourTreeAgent.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Interface for behaviour tree agent. The agent traverses through
|
||||||
|
* the tree and operates based on the data. It does not make any
|
||||||
|
* changes to the tree data.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_BEHAVIOUR_TREE_AGENT_H
|
||||||
|
#define SH_BEHAVIOUR_TREE_AGENT_H
|
||||||
|
|
||||||
|
#include "Resource Types/SHBehaviourTree.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHBehaviourTreeAgent
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
std::shared_ptr<SHBehaviourTree> treeRef;
|
||||||
|
SHBehaviourTree::Leaf current;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Remove empty ctor.
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent() = delete;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Param ctor for agent to take in reference to a tree
|
||||||
|
*
|
||||||
|
* \param tree - pointer to tree data. nullptr if no trees
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent(std::shared_ptr<SHBehaviourTree> tree);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy ctor.
|
||||||
|
*
|
||||||
|
* \param ref - agent to copy from
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent(SHBehaviourTreeAgent const& ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* copy assignment operator overload.
|
||||||
|
*
|
||||||
|
* \param ref - agent to copy from
|
||||||
|
* \return reference to current object
|
||||||
|
*/
|
||||||
|
SHBehaviourTreeAgent& operator=(SHBehaviourTreeAgent const& ref);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shift current node to next node.
|
||||||
|
*
|
||||||
|
* \param next - node to shift to
|
||||||
|
* \return vector of scripts that need to be run at next node
|
||||||
|
*/
|
||||||
|
[[nodiscard]] MonoMVector Transit(SHBehaviourTree::Leaf next) noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get current Node.
|
||||||
|
*
|
||||||
|
* \return Pointer to behaviour tree leaf
|
||||||
|
*/
|
||||||
|
SHBehaviourTree::Leaf GetCurrent() noexcept;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if pointer to tree is a nullptr.
|
||||||
|
*
|
||||||
|
* \return
|
||||||
|
*/
|
||||||
|
bool isEmpty() const noexcept;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !SH_BEHAVIOUR_TREE_AGENT_H
|
|
@ -0,0 +1,83 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHBehaviourTreeLibrary.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Definitions for helper functions to load and save behaviour trees
|
||||||
|
* and generate handles for tree and tree members.
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHBehaviourTreeLibrary.h"
|
||||||
|
#include <random>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
std::vector<BehaviourTreeHandle> SHBehaviourTreeLibray::treeHandle;
|
||||||
|
std::vector<BehaviourChildHandle> SHBehaviourTreeLibray::childHandles;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Generate uint16_t handle for tree.
|
||||||
|
*
|
||||||
|
* \return BehaviourTreeHandle(uint16_t)
|
||||||
|
****************************************************************************/
|
||||||
|
BehaviourTreeHandle SHBehaviourTreeLibray::GenerateTreeHandle() noexcept
|
||||||
|
{
|
||||||
|
std::default_random_engine randEngine{
|
||||||
|
static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()) };
|
||||||
|
std::mt19937 idGen{ randEngine() };
|
||||||
|
BehaviourTreeHandle result{ 0 };
|
||||||
|
while (result == 0)
|
||||||
|
{
|
||||||
|
result = static_cast<BehaviourTreeHandle>(idGen());
|
||||||
|
for (auto const& handle : treeHandle)
|
||||||
|
{
|
||||||
|
if (handle == result)
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
treeHandle.push_back(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Generate uint32_t handle for tree. Parent handle is shifted 16 bits to the
|
||||||
|
* left and the first 16 bits will be the unique handle for the child.
|
||||||
|
*
|
||||||
|
* \param parent handle - uint16_t
|
||||||
|
* \return BehaviourChildHandle(uint32_t)
|
||||||
|
****************************************************************************/
|
||||||
|
BehaviourChildHandle SHBehaviourTreeLibray::GenerateChildHandle(BehaviourTreeHandle parent) noexcept
|
||||||
|
{
|
||||||
|
std::default_random_engine randEngine{
|
||||||
|
static_cast<unsigned int>(std::chrono::system_clock::now().time_since_epoch().count()) };
|
||||||
|
std::mt19937 idGen{ randEngine() };
|
||||||
|
BehaviourTreeHandle temp{ 0 };
|
||||||
|
BehaviourChildHandle parentShift{ parent };
|
||||||
|
parentShift <<= 16;
|
||||||
|
BehaviourChildHandle check;
|
||||||
|
while (temp == 0)
|
||||||
|
{
|
||||||
|
check = parentShift;
|
||||||
|
temp = static_cast<BehaviourTreeHandle>(idGen());
|
||||||
|
check += temp;
|
||||||
|
for (auto const& handle : childHandles)
|
||||||
|
{
|
||||||
|
if (handle == check)
|
||||||
|
{
|
||||||
|
temp = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
childHandles.push_back(check);
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,59 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAnimControlModelLoader.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 16 January 2023
|
||||||
|
* \brief
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2023 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
#include "Assets/Asset Types/Anim Controller/SHAnimControlModel.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
|
||||||
|
struct SHBehaviourLeafRW
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
BehaviourChildHandle handle;
|
||||||
|
std::vector<BehaviourChildHandle> branches;
|
||||||
|
std::vector<std::pair<MonoMethod*, uint32_t>> scripts;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHBehaviourBranchRW
|
||||||
|
{
|
||||||
|
BehaviourChildHandle handle;
|
||||||
|
BehaviourChildHandle next;
|
||||||
|
std::vector<std::pair<MonoMethod*, uint32_t>> scripts;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SHBehaviourTreeLibray
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
static std::vector<BehaviourTreeHandle> treeHandle;
|
||||||
|
static std::vector<BehaviourChildHandle> childHandles;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/****************************************************************************
|
||||||
|
* Generate uint16_t handle for tree. Checks for duplicates as well
|
||||||
|
*
|
||||||
|
* \return BehaviourTreeHandle(uint16_t)
|
||||||
|
****************************************************************************/
|
||||||
|
static BehaviourTreeHandle GenerateTreeHandle() noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Generate uint32_t handle for tree. Parent handle is shifted 16 bits to the
|
||||||
|
* left and the first 16 bits will be the unique handle for the child.
|
||||||
|
* Checks for duplicates as well
|
||||||
|
*
|
||||||
|
* \param parent handle - uint16_t
|
||||||
|
* \return BehaviourChildHandle(uint32_t)
|
||||||
|
****************************************************************************/
|
||||||
|
static BehaviourChildHandle GenerateChildHandle(BehaviourTreeHandle parent) noexcept;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,174 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAISystem.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief AI system definitions. Includes helper functions for Ai Component
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHAISystem.h"
|
||||||
|
#include "ECS_Base/System/SHComponentManager.h"
|
||||||
|
#include "Components/SHRigidBodyComponent.h"
|
||||||
|
#include "Components/SHAIComponent.h"
|
||||||
|
#include "Events/Packages/SHScriptEventPackage.h"
|
||||||
|
#include "Events/SHEventManager.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
float const DIST_EPS{ 5.0f };
|
||||||
|
float const DIST_EPS_SQ{ DIST_EPS * DIST_EPS };
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Check if entity has reached waypoint.
|
||||||
|
*
|
||||||
|
* \param transform - transform of entity
|
||||||
|
* \param agent - agent of entity
|
||||||
|
* \return bool - result of check
|
||||||
|
****************************************************************************/
|
||||||
|
bool SHAISystem::Reached(SHTransformComponent const& transform, SHWaypointAgent const& agent)
|
||||||
|
{
|
||||||
|
SHMathVec3f distanceVec{ agent.GetCurrentTarget() - transform.GetTranslation() };
|
||||||
|
float distance{ distanceVec.MagSqr() };
|
||||||
|
return distance <= (DIST_EPS * DIST_EPS);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Check if params in branch all match and whether transition is allowed.
|
||||||
|
*
|
||||||
|
* \param branch - pointer to branch
|
||||||
|
* \return bool - result of check
|
||||||
|
****************************************************************************/
|
||||||
|
bool SHAISystem::CheckBranchConditions(SHBehaviourTree::Branch branch)
|
||||||
|
{
|
||||||
|
for (auto& param : branch->checks)
|
||||||
|
{
|
||||||
|
ParamTypes type{ param->GetType() };
|
||||||
|
if (type == ParamTypes::FLOAT)
|
||||||
|
{
|
||||||
|
std::shared_ptr<SHTreeParamSpec<float>> p = std::static_pointer_cast<SHTreeParamSpec<float>>(param);
|
||||||
|
if (p->GetData() >= p->GetCheck())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == ParamTypes::BOOL)
|
||||||
|
{
|
||||||
|
std::shared_ptr<SHTreeParamSpec<bool>> p = std::static_pointer_cast<SHTreeParamSpec<bool>>(param);
|
||||||
|
if (p->GetData())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == ParamTypes::TRIGGER)
|
||||||
|
{
|
||||||
|
std::shared_ptr<SHTreeParamSpec<bool>> p = std::static_pointer_cast<SHTreeParamSpec<bool>>(param);
|
||||||
|
if (p->GetData())
|
||||||
|
{
|
||||||
|
p->GetValueRef() = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (type == ParamTypes::INT)
|
||||||
|
{
|
||||||
|
std::shared_ptr<SHTreeParamSpec<int>> p = std::static_pointer_cast<SHTreeParamSpec<int>>(param);
|
||||||
|
if (p->GetData() >= p->GetCheck())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Init function.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAISystem::Init()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Main AI system logic.
|
||||||
|
*
|
||||||
|
* \param float - delta time
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAISystem::Run(float dt)
|
||||||
|
{
|
||||||
|
(void)dt;
|
||||||
|
auto& aiSet = SHComponentManager::GetDense<SHAIComponent>();
|
||||||
|
size_t const size{ aiSet.size() };
|
||||||
|
|
||||||
|
if (size == 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i{ 0 }; i < size; ++i)
|
||||||
|
{
|
||||||
|
auto& ai{ aiSet[i] };
|
||||||
|
if (!ai.isActive)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTransformComponent* transform = SHComponentManager::GetComponent_s<SHTransformComponent>(ai.GetEID());
|
||||||
|
SHRigidBodyComponent* rigidBody = SHComponentManager::GetComponent_s<SHRigidBodyComponent>(ai.GetEID());
|
||||||
|
|
||||||
|
if (transform && rigidBody)
|
||||||
|
{
|
||||||
|
auto wpAgent{ ai.GetWaypointAgent() };
|
||||||
|
if (wpAgent.isActive && !wpAgent.Completed())
|
||||||
|
{
|
||||||
|
if (Reached(*transform, wpAgent))
|
||||||
|
{
|
||||||
|
wpAgent.NextWaypoint();
|
||||||
|
SHMathVec3f velVec{ wpAgent.GetCurrentTarget() - transform->GetTranslation() };
|
||||||
|
velVec.Normalize();
|
||||||
|
velVec *= wpAgent.GetSpeed();
|
||||||
|
rigidBody->ApplyForce({ velVec[0], velVec[1] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto behaviourAgent{ ai.GetBehaviourAgent() };
|
||||||
|
if (!behaviourAgent.isEmpty())
|
||||||
|
{
|
||||||
|
auto branches{ behaviourAgent.GetCurrent()->branches };
|
||||||
|
for (auto const& branch : branches)
|
||||||
|
{
|
||||||
|
if (CheckBranchConditions(branch))
|
||||||
|
{
|
||||||
|
auto scripts = behaviourAgent.Transit(branch->next);
|
||||||
|
|
||||||
|
for (auto const& script : branch->scripts)
|
||||||
|
{
|
||||||
|
ScriptEventPackPtr evtPack = std::make_shared<SHScriptEventPackage>(script.first, script.second);
|
||||||
|
SHEventManager::GetEventManagerInstance().CatchEvent(SHEvent(evtPack));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& script : scripts)
|
||||||
|
{
|
||||||
|
ScriptEventPackPtr evtPack = std::make_shared<SHScriptEventPackage>(script.first, script.second);
|
||||||
|
SHEventManager::GetEventManagerInstance().CatchEvent(SHEvent(evtPack));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Exit function.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void SHAISystem::Exit()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAISystem.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief AI system declaration. Includes helper functions for Ai Component
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#ifndef SH_AI_SYSTEM_H
|
||||||
|
#define SH_AI_SYSTEM_H
|
||||||
|
|
||||||
|
#include "ECS_Base/System/SHSystem.h"
|
||||||
|
#include "AI/SHWaypointAgent.h"
|
||||||
|
#include "Resource Types/SHBehaviourTree.h"
|
||||||
|
#include "Components/SHTransformComponent.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
class SHAISystem : public SHSystem
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Check if entity has reached waypoint.
|
||||||
|
*
|
||||||
|
* \param transform - transform of entity
|
||||||
|
* \param agent - agent of entity
|
||||||
|
* \return bool - result of check
|
||||||
|
****************************************************************************/
|
||||||
|
bool Reached(SHTransformComponent const& transform, SHWaypointAgent const& agent);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Check if params in branch all match and whether transition is allowed.
|
||||||
|
*
|
||||||
|
* \param branch - pointer to branch
|
||||||
|
* \return bool - result of check
|
||||||
|
****************************************************************************/
|
||||||
|
bool CheckBranchConditions(SHBehaviourTree::Branch branch);
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Init function.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void Init();
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Main AI system logic.
|
||||||
|
*
|
||||||
|
* \param float - delta time
|
||||||
|
****************************************************************************/
|
||||||
|
void Run(float);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Exit function.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
void Exit();
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif // !SH_AI_SYSTEM_H
|
|
@ -0,0 +1,150 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHBehaviourTree.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief Definition for behaviour tree class. FSM with condition checks
|
||||||
|
* to aid in transition from one state to another
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHBehaviourTree.h"
|
||||||
|
#include "Resource Libraries/SHBehaviourTreeLibrary.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
/****************************************************************************
|
||||||
|
* Default Ctor and Dtor.
|
||||||
|
****************************************************************************/
|
||||||
|
SHBehaviourTree::SHBehaviourTree() noexcept
|
||||||
|
: handle{ SHBehaviourTreeLibray::GenerateTreeHandle() },
|
||||||
|
root { new SHBehaviourLeaf }, leaves(0), branches(0)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SHBehaviourTree::~SHBehaviourTree() noexcept
|
||||||
|
{
|
||||||
|
delete root;
|
||||||
|
|
||||||
|
for (auto const& leaf : leaves)
|
||||||
|
{
|
||||||
|
delete leaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto const& branch : branches)
|
||||||
|
{
|
||||||
|
delete branch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Get root node in tree.
|
||||||
|
*
|
||||||
|
* \return pointer to node
|
||||||
|
****************************************************************************/
|
||||||
|
SHBehaviourTree::SHBehaviourLeaf* SHBehaviourTree::GetRoot() const noexcept
|
||||||
|
{
|
||||||
|
return root;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Create tree wide param to be used in transitioning
|
||||||
|
*
|
||||||
|
* \param name - std::string of param
|
||||||
|
* \param type - ParamTypes, type of param
|
||||||
|
* \return pointer to param data created
|
||||||
|
****************************************************************************/
|
||||||
|
ParamPtr SHBehaviourTree::CreateParam(std::string name, ParamTypes type) noexcept
|
||||||
|
{
|
||||||
|
ParamPtr result;
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case ParamTypes::FLOAT:
|
||||||
|
result = std::make_shared<SHTreeParamSpec<float>>(name, type);
|
||||||
|
break;
|
||||||
|
case ParamTypes::BOOL:
|
||||||
|
result = std::make_shared<SHTreeParamSpec<bool>>(name, type);
|
||||||
|
break;
|
||||||
|
case ParamTypes::TRIGGER:
|
||||||
|
result = std::make_shared<SHTreeParamSpec<bool>>(name, type);
|
||||||
|
break;
|
||||||
|
case ParamTypes::INT:
|
||||||
|
result = std::make_shared<SHTreeParamSpec<int>>(name, type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
param.push_back(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Create new branch and node from provided node.
|
||||||
|
*
|
||||||
|
* \param from - node to branch out from
|
||||||
|
* \return pointer to new branch created
|
||||||
|
****************************************************************************/
|
||||||
|
SHBehaviourTree::SHBehaviourLeaf* SHBehaviourTree::BranchOutFrom(SHBehaviourLeaf* from) noexcept
|
||||||
|
{
|
||||||
|
auto const branch = new SHBehaviourBranch;
|
||||||
|
branch->handle = SHBehaviourTreeLibray::GenerateChildHandle(handle);
|
||||||
|
|
||||||
|
auto const leaf = new SHBehaviourLeaf;
|
||||||
|
leaf->handle = SHBehaviourTreeLibray::GenerateChildHandle(handle);
|
||||||
|
|
||||||
|
branch->next = leaf;
|
||||||
|
from->branches.push_back(branch);
|
||||||
|
|
||||||
|
branches.push_back(branch);
|
||||||
|
leaves.push_back(leaf);
|
||||||
|
|
||||||
|
return leaf;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Link 2 nodes together.
|
||||||
|
*
|
||||||
|
* \param from - pointer to first node
|
||||||
|
* \param to - pointer to second node
|
||||||
|
****************************************************************************/
|
||||||
|
void SHBehaviourTree::LinkLeaves(SHBehaviourLeaf* from, SHBehaviourLeaf* to) noexcept
|
||||||
|
{
|
||||||
|
auto const branch = new SHBehaviourBranch;
|
||||||
|
branch->handle = SHBehaviourTreeLibray::GenerateChildHandle(handle);
|
||||||
|
branch->next = to;
|
||||||
|
|
||||||
|
branches.push_back(branch);
|
||||||
|
from->branches.push_back(branch);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Breaks link between 2 branches if it exists.
|
||||||
|
*
|
||||||
|
* \param from - pointer to first node
|
||||||
|
* \param to - pointer to second node
|
||||||
|
* \return result of break - bool
|
||||||
|
****************************************************************************/
|
||||||
|
bool SHBehaviourTree::BreakLink(SHBehaviourLeaf* from, SHBehaviourLeaf* to) noexcept
|
||||||
|
{
|
||||||
|
for (auto it {from->branches.begin()}; it != from->branches.end(); ++it)
|
||||||
|
{
|
||||||
|
if ((*it)->next == to)
|
||||||
|
{
|
||||||
|
for (auto branchIt {branches.begin()}; branchIt != branches.end(); ++branchIt)
|
||||||
|
{
|
||||||
|
if ((*it) == (*branchIt))
|
||||||
|
{
|
||||||
|
branches.erase(branchIt);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete *it;
|
||||||
|
from->branches.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,108 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHAnimControlModel.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 16 January 2023
|
||||||
|
* \brief
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2023 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
|
||||||
|
#include "Assets/SHAssetMacros.h"
|
||||||
|
|
||||||
|
#include "SHTreeParam.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
typedef std::shared_ptr<SHTreeParam> ParamPtr;
|
||||||
|
|
||||||
|
class SHBehaviourTree
|
||||||
|
{
|
||||||
|
struct SHBehaviourLeaf;
|
||||||
|
struct SHBehaviourBranch;
|
||||||
|
|
||||||
|
struct SHBehaviourLeaf
|
||||||
|
{
|
||||||
|
std::string name;
|
||||||
|
BehaviourChildHandle handle;
|
||||||
|
std::vector<SHBehaviourBranch*> branches;
|
||||||
|
MonoMVector scripts;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHBehaviourBranch
|
||||||
|
{
|
||||||
|
BehaviourChildHandle handle;
|
||||||
|
SHBehaviourLeaf* next;
|
||||||
|
MonoMVector scripts;
|
||||||
|
std::vector<ParamPtr> checks;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
BehaviourTreeHandle handle;
|
||||||
|
SHBehaviourLeaf* root;
|
||||||
|
std::vector<SHBehaviourLeaf*> leaves;
|
||||||
|
std::vector<SHBehaviourBranch*> branches;
|
||||||
|
std::vector<ParamPtr> param;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/****************************************************************************
|
||||||
|
* Default Ctor and Dtor.
|
||||||
|
****************************************************************************/
|
||||||
|
SHBehaviourTree() noexcept;
|
||||||
|
~SHBehaviourTree() noexcept;
|
||||||
|
|
||||||
|
// No copying of tree allowed
|
||||||
|
SHBehaviourTree(SHBehaviourTree const& ref) = delete;
|
||||||
|
SHBehaviourTree(SHBehaviourTree&& ref) = delete;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Get root node in tree.
|
||||||
|
*
|
||||||
|
* \return pointer to node
|
||||||
|
****************************************************************************/
|
||||||
|
[[nodiscard]] SHBehaviourLeaf* GetRoot() const noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Create tree wide param to be used in transitioning
|
||||||
|
*
|
||||||
|
* \param name - std::string of param
|
||||||
|
* \param type - ParamTypes, type of param
|
||||||
|
* \return pointer to param data created
|
||||||
|
****************************************************************************/
|
||||||
|
ParamPtr CreateParam(std::string name, ParamTypes type) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Create new branch and node from provided node.
|
||||||
|
*
|
||||||
|
* \param from - node to branch out from
|
||||||
|
* \return pointer to new branch created
|
||||||
|
****************************************************************************/
|
||||||
|
SHBehaviourLeaf* BranchOutFrom(SHBehaviourLeaf* from) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Link 2 nodes together.
|
||||||
|
*
|
||||||
|
* \param from - pointer to first node
|
||||||
|
* \param to - pointer to second node
|
||||||
|
****************************************************************************/
|
||||||
|
void LinkLeaves(SHBehaviourLeaf* from, SHBehaviourLeaf* to) noexcept;
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Breaks link between 2 branches if it exists.
|
||||||
|
*
|
||||||
|
* \param from - pointer to first node
|
||||||
|
* \param to - pointer to second node
|
||||||
|
* \return result of break - bool
|
||||||
|
****************************************************************************/
|
||||||
|
bool BreakLink(SHBehaviourLeaf* from, SHBehaviourLeaf* to) noexcept;
|
||||||
|
|
||||||
|
using Leaf = SHBehaviourLeaf*;
|
||||||
|
using Branch = SHBehaviourBranch*;
|
||||||
|
};
|
||||||
|
}
|
|
@ -0,0 +1,85 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHTreeParam.cpp
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \brief
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2021 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited
|
||||||
|
******************************************************************************/
|
||||||
|
#include "SHpch.h"
|
||||||
|
#include "SHTreeParam.h"
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
SHTreeParam::SHTreeParam(std::string name, ParamTypes t)
|
||||||
|
: name{ name }, type{ t }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTreeParam::SHTreeParam(SHTreeParam const& ref)
|
||||||
|
: name{ ref.name }, type{ ref.type }
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
SHTreeParam& SHTreeParam::operator=(SHTreeParam const& ref)
|
||||||
|
{
|
||||||
|
name = ref.name;
|
||||||
|
type = ref.type;
|
||||||
|
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
ParamTypes SHTreeParam::GetType() const noexcept
|
||||||
|
{
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string SHTreeParam::GetName() const noexcept
|
||||||
|
{
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SHTreeParamSpec<T>::SHTreeParamSpec(std::string name, ParamTypes t)
|
||||||
|
: SHTreeParam(name, t)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SHTreeParamSpec<T>::SHTreeParamSpec(SHTreeParamSpec const& ref)
|
||||||
|
: SHTreeParam(ref.name, ref.type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
SHTreeParamSpec<T>& SHTreeParamSpec<T>::operator=(SHTreeParamSpec const& ref)
|
||||||
|
{
|
||||||
|
SHTreeParam::operator=(ref);
|
||||||
|
data = ref.data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void SHTreeParamSpec<T>::SetCheck(T val) noexcept
|
||||||
|
{
|
||||||
|
check = val;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T SHTreeParamSpec<T>::GetCheck() const noexcept
|
||||||
|
{
|
||||||
|
return check;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T SHTreeParamSpec<T>::GetData() const noexcept
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T& SHTreeParamSpec<T>::GetValueRef() noexcept
|
||||||
|
{
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
/******************************************************************************
|
||||||
|
* \file SHTreeParam.h
|
||||||
|
* \author Loh Xiao Qi
|
||||||
|
* \date 16 January 2023
|
||||||
|
* \brief
|
||||||
|
*
|
||||||
|
* \copyright Copyright (c) 2023 Digipen Institute of Technology. Reproduction
|
||||||
|
* or disclosure of this file or its contents without the prior
|
||||||
|
* written consent of Digipen Institute of Technology is prohibited.
|
||||||
|
******************************************************************************/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace SHADE
|
||||||
|
{
|
||||||
|
enum class ParamTypes
|
||||||
|
{
|
||||||
|
FLOAT,
|
||||||
|
BOOL,
|
||||||
|
INT,
|
||||||
|
TRIGGER
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SHTreeParam
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
ParamTypes type;
|
||||||
|
std::string name;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHTreeParam() = delete;
|
||||||
|
SHTreeParam(std::string name, ParamTypes t);
|
||||||
|
SHTreeParam(SHTreeParam const& ref);
|
||||||
|
SHTreeParam& operator=(SHTreeParam const& ref);
|
||||||
|
|
||||||
|
ParamTypes GetType() const noexcept;
|
||||||
|
std::string GetName() const noexcept;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
class SHTreeParamSpec : public SHTreeParam
|
||||||
|
{
|
||||||
|
private:
|
||||||
|
T data;
|
||||||
|
T check;
|
||||||
|
|
||||||
|
public:
|
||||||
|
SHTreeParamSpec() = delete;
|
||||||
|
SHTreeParamSpec(std::string name, ParamTypes t);
|
||||||
|
SHTreeParamSpec(SHTreeParamSpec const& ref);
|
||||||
|
SHTreeParamSpec& operator=(SHTreeParamSpec const& ref);
|
||||||
|
|
||||||
|
void SetCheck(T val) noexcept;
|
||||||
|
T GetCheck() const noexcept;
|
||||||
|
|
||||||
|
T GetData() const noexcept;
|
||||||
|
T& GetValueRef() noexcept;
|
||||||
|
};
|
||||||
|
}
|
Loading…
Reference in New Issue