#include "GwNavTestFwk/GwNavTestFwk.h"
#include "GwNavTestFwk/TestEnv.h"
#include "LabEngine/utils/labengineutils.h"
namespace
{
class MyGameEntity
{
public:
MyGameEntity()
: m_startPosition(0.0f, 0.0f, 0.0f)
, m_destinationPosition(0.0f, 0.0f, 0.0f)
, m_arrivalDirection(0.0f, 0.0f)
, m_position(0.0f, 0.0f, 0.0f)
, m_velocity(0.0f, 0.0f, 0.0f)
{}
void Destroy();
void UpdateLogic(
KyFloat32 simulationStepsInSeconds);
void UpdatePhysics(
KyFloat32 simulationStepsInSeconds);
bool HasArrived();
public:
Kaim::Ptr<Kaim::Bot> m_navBot;
};
{
};
void SplineEndConstraintPathEventListObserver::OnPathEventListBuildingStageDone(
Kaim::Bot* bot,
Kaim::PathEventList& pathEventList,
KyUInt32 firstIndexOfNewEvent, FirstIntervalStatus firstIntervalStatus)
{
const Kaim::NavTag* previousNavTag =
KY_NULL;
for (
KyUInt32 eventIndex = firstIndexOfNewEvent; eventIndex < pathEventList.
GetPathEventCount(); eventIndex++)
{
if (eventIndex >= pathEventList.
GetPathEventIntervalCount())
{
if (pathEvent.
IsAtLastNodeOfPath() ==
true)
{
MyGameEntity* gameEntity = (MyGameEntity*)(bot->
GetUserData());
}
break;
}
if (previousNavTag !=
KY_NULL && previousNavTag == navTag)
continue;
if (navTag !=
KY_NULL && navTag->GetWordCount() != 0)
{
previousNavTag = navTag;
if (firstIntervalStatus == FirstIntervalIsExtensionOfPreviousLast && eventIndex == firstIndexOfNewEvent)
{
continue;
}
const Kaim::Vec3f& start = path->
GetPathEdgeStartPosition(edgeIdx);
const Kaim::Vec3f& end = path->
GetPathEdgeEndPosition(edgeIdx);
{
}
else
{
}
}
}
}
{
public:
{
if (m_splineEndConstraintPathEventListObserver ==
KY_NULL)
m_splineEndConstraintPathEventListObserver = *KY_NEW SplineEndConstraintPathEventListObserver;
return m_splineEndConstraintPathEventListObserver;
}
public:
Kaim::Ptr<SplineEndConstraintPathEventListObserver> m_splineEndConstraintPathEventListObserver;
};
{
m_position = startPosition;
m_startPosition = startPosition;
m_destinationPosition = destination;
m_arrivalDirection = arrivalDirection;
botInitConfig.
m_startPosition = m_position;
botInitConfig.
m_userData =
this;
m_navBot->Init(botInitConfig, botConfig);
m_navBot->SetNewPathNavigationProfileId(SplineEndConstraintNavigationProfile::s_navigationProfileId);
m_navBot->SetCurrentVisualDebugLOD(Kaim::VisualDebugLOD_Maximal);
m_navBot->AddToDatabase();
m_navBot->SetChannelComputerConfig(channelComputerConfig);
{
}
m_navBot->SetSplineTrajectoryConfig(splineTrajectoryConfig);
}
void MyGameEntity::Destroy()
{
m_navBot->RemoveFromDatabase();
}
{
if (m_navBot->GetFollowedPath() ==
KY_NULL && m_navBot->IsComputingNewPath() ==
false)
{
m_navBot->ComputeNewPathToDestination(m_destinationPosition);
}
if (HasArrived())
{
m_navBot->ClearFollowedPath();
m_destinationPosition = m_startPosition;
m_startPosition = swap;
m_navBot->ComputeNewPathToDestination(m_destinationPosition);
}
}
void MyGameEntity::UpdatePhysics(
KyFloat32 simulationStepsInSeconds)
{
m_velocity = m_navBot->GetBotOutput().m_outputVelocity;
m_position = m_navBot->ComputeMoveOnNavMesh(m_velocity, simulationStepsInSeconds);
m_navBot->SetPositionAndVelocityAndFrontDirection(m_position, simulationStepsInSeconds);
}
bool MyGameEntity::HasArrived()
{
KyFloat32 arrivalPrecisionRadius = m_navBot->GetConfig().m_pathProgressConfig.m_checkPointRadius;
if (m_navBot->HasReachedPosition(m_destinationPosition, arrivalPrecisionRadius))
{
return true;
}
return false;
}
class MyGameLevel
{
public:
MyGameLevel()
{
}
void UpdateLogic(float deltaTimeInSeconds);
void UpdatePhysics(float deltaTimeInSeconds);
void Destroy();
protected:
Kaim::Ptr<Kaim::NavData> m_navData;
MyGameEntity m_entityA;
MyGameEntity m_entityB;
};
{
Kaim::Ptr<Kaim::File> kaimFile;
const std::string navdataFilePath = TestSystem::Instance().InputDir() + "GeneratedNavData/opencastle/opencastle.NavData";
return false;
loadingResult = m_navData->Load(kaimFile);
kaimFile ->Close();
return false;
m_navData->AddToDatabaseImmediate();
m_entityA.Initialize(world,
m_entityB.Initialize(world,
return true;
}
void MyGameLevel::UpdateLogic(float deltaTimeInSeconds)
{
m_entityA.UpdateLogic(deltaTimeInSeconds);
m_entityB.UpdateLogic(deltaTimeInSeconds);
}
void MyGameLevel::UpdatePhysics(float deltaTimeInSeconds)
{
m_entityA.UpdatePhysics(deltaTimeInSeconds);
m_entityB.UpdatePhysics(deltaTimeInSeconds);
}
void MyGameLevel::Destroy()
{
m_entityB.Destroy();
m_entityA.Destroy();
m_navData->RemoveFromDatabaseImmediate();
}
class MyGameWorld
{
public:
MyGameWorld() : m_gameFrameIdx(0), m_navWorld(
KY_NULL) {}
bool Initialize(bool doVisualDebugTutorial);
void Update(float deltaTimeInSeconds);
void Destroy();
private:
void UpdateLogic(float deltaTimeInSeconds);
void UpdateNavigation(float deltaTimeInSeconds);
void UpdatePhysics(float deltaTimeInSeconds);
public:
Kaim::Ptr<Kaim::World> m_navWorld;
MyGameLevel m_gameLevel;
};
bool MyGameWorld::Initialize(bool doVisualDebugTutorial)
{
m_coordSystem.Setup(oneMeterInClientUnits, clientAxisForX, clientAxisForY, clientAxisForZ);
SplineEndConstraintNavigationProfile::s_navigationProfileId = m_navWorld->AddNavigationProfile(*KY_NEW SplineEndConstraintNavigationProfile);
if (SplineEndConstraintNavigationProfile::s_navigationProfileId ==
KyUInt32MAXVAL)
return false;
KY_UNUSED(doVisualDebugTutorial);
#ifndef KY_BUILD_SHIPPING
if (doVisualDebugTutorial)
{
const KyUInt32 serverPort = Kaim::VisualDebugServerConfig::DefaultServerPort();
KyResult startResult = m_navWorld->StartVisualDebug(visualDebugServerConfig);
{
return false;
}
}
#endif
return m_gameLevel.Initialize(m_navWorld);
}
void MyGameWorld::Update(float deltaTimeInSeconds)
{
if (m_navWorld->GetVisualDebugServer())
m_navWorld->GetVisualDebugServer()->NewFrame(m_gameFrameIdx);
++m_gameFrameIdx;
UpdateLogic(deltaTimeInSeconds);
UpdateNavigation(deltaTimeInSeconds);
UpdatePhysics(deltaTimeInSeconds);
}
void MyGameWorld::UpdateLogic(float deltaTimeInSeconds) { m_gameLevel.UpdateLogic(deltaTimeInSeconds); }
void MyGameWorld::UpdateNavigation(float deltaTimeInSeconds) { m_navWorld->Update(deltaTimeInSeconds); }
void MyGameWorld::UpdatePhysics(float deltaTimeInSeconds) { m_gameLevel.UpdatePhysics(deltaTimeInSeconds); }
void MyGameWorld::Destroy()
{
m_gameLevel.Destroy();
m_navWorld->StopVisualDebug();
}
class MyGame
{
public:
bool Initialize(bool doVisualDebugTutorial);
void Update(float deltaTimeInSeconds);
void Destroy();
bool HasFinished();
protected:
MyGameWorld m_world;
};
bool MyGame::Initialize(bool doVisualDebugTutorial)
{
{
return false;
}
return m_world.Initialize(doVisualDebugTutorial);
}
bool MyGame::HasFinished()
{
if (m_world.m_navWorld->GetVisualDebugServer() !=
KY_NULL)
return m_world.m_navWorld->GetVisualDebugServer()->IsConnectionEstablished() == false;
else
return m_world.m_gameFrameIdx >= 60;
}
void MyGame::Update(float deltaTimeInSeconds)
{
m_world.Update(deltaTimeInSeconds);
}
void MyGame::Destroy()
{
m_world.Destroy();
}
#define TEST_ENV_CLASS TestEnv
TEST_ENV {}
TUTORIAL
{
KT_LOG_TITLE_BEGIN("TUTORIAL - Channel Path Following");
MyGame myGame;
bool doVisualDebugTutorial = false;
CHECK(myGame.Initialize(doVisualDebugTutorial));
const KyFloat32 loopDurationInSecond = 1.0f / 60.0f;
while (myGame.HasFinished() == false)
{
myGame.Update(loopDurationInSecond);
LabEngine::Utils::TimedBusyWait(1000.0f * loopDurationInSecond);
}
myGame.Destroy();
}
}