From 04427bda76f805a8609fe876f5a96c913b463138 Mon Sep 17 00:00:00 2001 From: Mordred Date: Fri, 19 Apr 2019 02:15:18 +0200 Subject: [PATCH] Crowd avoidance works. Roaming and following a player, not so much --- src/world/Actor/BNpc.cpp | 20 +++++++---- src/world/Navi/NaviProvider.cpp | 59 +++++++++++++++++++++++++++++---- src/world/Navi/NaviProvider.h | 3 ++ src/world/Territory/Zone.cpp | 2 +- 4 files changed, 70 insertions(+), 14 deletions(-) diff --git a/src/world/Actor/BNpc.cpp b/src/world/Actor/BNpc.cpp index e41f08f1..bb5e8d4e 100644 --- a/src/world/Actor/BNpc.cpp +++ b/src/world/Actor/BNpc.cpp @@ -232,7 +232,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) { // Reached destination m_naviLastPath.clear(); - return true; + // return true; } auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); @@ -246,7 +246,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) return false; } - auto path = pNaviProvider->findFollowPath( m_pos, pos ); + /*auto path = pNaviProvider->findFollowPath( m_pos, pos ); if( !path.empty() ) { @@ -283,12 +283,17 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos ) } } - step(); + step();*/ + + //pNaviProvider->setMoveTarget( *this, pos ); auto pos1 = pNaviProvider->getMovePos( *this ); - Logger::debug( "{} {} {}", pos1.x, pos1.y, pos1.z ); - setPos( pos1 ); + //Logger::debug( "{} {} {}", pos1.x, pos1.y, pos1.z ); + m_pCurrentZone->updateActorPosition( *this ); + face( pos1 ); + setPos( pos1 ); + sendPositionUpdate(); return false; } @@ -477,9 +482,10 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount ) auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); auto pNaviProvider = pNaviMgr->getNaviProvider( m_pCurrentZone->getBgPath() ); - if( !pNaviProvider ) + if( pNaviProvider ) { - pNaviProvider->setMoveTarget( *this, m_roamPos ); + //if( !pNaviProvider->isAgentActive( *this ) ) + pNaviProvider->setMoveTarget( *this, m_roamPos ); } if( moveTo( m_roamPos ) ) diff --git a/src/world/Navi/NaviProvider.cpp b/src/world/Navi/NaviProvider.cpp index edcbabe3..f17b7f5e 100644 --- a/src/world/Navi/NaviProvider.cpp +++ b/src/world/Navi/NaviProvider.cpp @@ -48,6 +48,42 @@ bool Sapphire::World::Navi::NaviProvider::init() if( !m_pCrowd->init( 1000, 10.f, m_naviMesh ) ) return false; + dtObstacleAvoidanceParams params; + // Use mostly default settings, copy from dtCrowd. + memcpy(¶ms, m_pCrowd->getObstacleAvoidanceParams(0), sizeof(dtObstacleAvoidanceParams)); + + // Low (11) + params.velBias = 0.5f; + params.adaptiveDivs = 5; + params.adaptiveRings = 2; + params.adaptiveDepth = 1; + m_pCrowd->setObstacleAvoidanceParams(0, ¶ms); + + // Medium (22) + params.velBias = 0.5f; + params.adaptiveDivs = 5; + params.adaptiveRings = 2; + params.adaptiveDepth = 2; + m_pCrowd->setObstacleAvoidanceParams(1, ¶ms); + + // Good (45) + params.velBias = 0.5f; + params.adaptiveDivs = 7; + params.adaptiveRings = 2; + params.adaptiveDepth = 3; + m_pCrowd->setObstacleAvoidanceParams(2, ¶ms); + + // High (66) + params.velBias = 0.5f; + params.adaptiveDivs = 7; + params.adaptiveRings = 3; + params.adaptiveDepth = 3; + + m_pCrowd->setObstacleAvoidanceParams(3, ¶ms); + + m_vod = dtAllocObstacleAvoidanceDebugData(); + m_vod->init( 2048 ); + initQuery(); return true; @@ -535,19 +571,23 @@ int32_t Sapphire::World::Navi::NaviProvider::addAgent( Entity::Chara& chara ) dtCrowdAgentParams params; std::memset( ¶ms, 0, sizeof( params ) ); params.height = 7.f; - params.maxAcceleration = 8.f; - params.maxSpeed = 3.5f; - params.radius = 5.f; + params.maxAcceleration = 16.f; + params.maxSpeed = 13.5f; + params.radius = 2.f; params.collisionQueryRange = params.radius * 12.0f; params.pathOptimizationRange = params.radius * 30.0f; - + params.updateFlags = 0; + //params.updateFlags |= DT_CROWD_OBSTACLE_AVOIDANCE; float position[] = { chara.getPos().x, chara.getPos().y, chara.getPos().z }; return m_pCrowd->addAgent( position, ¶ms ); } void Sapphire::World::Navi::NaviProvider::updateCrowd( float timeInSeconds ) { + dtCrowdAgentDebugInfo info; + info.idx = -1; + info.vod = m_vod; m_pCrowd->update( timeInSeconds, &info ); } @@ -574,7 +614,7 @@ void Sapphire::World::Navi::NaviProvider::setMoveTarget( Entity::Chara& chara, const float* halfExtents = m_pCrowd->getQueryExtents(); float vel[ 3 ]; - float p[ 3 ] = { chara.getPos().x, chara.getPos().y, chara.getPos().z }; + float p[ 3 ] = { endPos.x, endPos.y, endPos.z }; const dtCrowdAgent* ag = m_pCrowd->getAgent( chara.getAgentId() ); if( ag && ag->active ) @@ -590,4 +630,11 @@ Sapphire::Common::FFXIVARR_POSITION3 Sapphire::World::Navi::NaviProvider::getMov if( !ag ) return { 0.f, 0.f, 0.f }; return { ag->npos[ 0 ], ag->npos[ 1 ], ag->npos[ 2 ] }; -} \ No newline at end of file +} + +bool Sapphire::World::Navi::NaviProvider::isAgentActive( Entity::Chara& chara ) const +{ + const dtCrowdAgent* ag = m_pCrowd->getAgent( chara.getAgentId() ); + return ag && ag->active; + +} diff --git a/src/world/Navi/NaviProvider.h b/src/world/Navi/NaviProvider.h index 2ad60cf2..9053dcd0 100644 --- a/src/world/Navi/NaviProvider.h +++ b/src/world/Navi/NaviProvider.h @@ -60,11 +60,14 @@ namespace Sapphire::World::Navi Common::FFXIVARR_POSITION3 getMovePos( Entity::Chara& chara ); + bool isAgentActive( Entity::Chara& chara ) const; + protected: std::string m_internalName; dtNavMesh* m_naviMesh; dtNavMeshQuery* m_naviMeshQuery; + dtObstacleAvoidanceDebugData* m_vod; std::unique_ptr< dtCrowd > m_pCrowd; float m_polyFindRange[ 3 ]; diff --git a/src/world/Territory/Zone.cpp b/src/world/Territory/Zone.cpp index 94c780cd..ee52d012 100644 --- a/src/world/Territory/Zone.cpp +++ b/src/world/Territory/Zone.cpp @@ -474,7 +474,7 @@ bool Sapphire::Zone::update( uint64_t tickCount ) bool changedWeather = checkWeather(); if( m_pNaviProvider ) - m_pNaviProvider->updateCrowd( 0.001f * tickCount ); + m_pNaviProvider->updateCrowd( 0.02f ); updateSessions( tickCount, changedWeather ); onUpdate( tickCount );