1
Fork 0
mirror of https://github.com/SapphireServer/Sapphire.git synced 2025-04-28 07:07:45 +00:00

Crowd avoidance works. Roaming and following a player, not so much

This commit is contained in:
Mordred 2019-04-19 02:15:18 +02:00
parent 61e0b0c013
commit 04427bda76
4 changed files with 70 additions and 14 deletions

View file

@ -232,7 +232,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
{ {
// Reached destination // Reached destination
m_naviLastPath.clear(); m_naviLastPath.clear();
return true; // return true;
} }
auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >();
@ -246,7 +246,7 @@ bool Sapphire::Entity::BNpc::moveTo( const FFXIVARR_POSITION3& pos )
return false; return false;
} }
auto path = pNaviProvider->findFollowPath( m_pos, pos ); /*auto path = pNaviProvider->findFollowPath( m_pos, pos );
if( !path.empty() ) 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 ); auto pos1 = pNaviProvider->getMovePos( *this );
Logger::debug( "{} {} {}", pos1.x, pos1.y, pos1.z ); //Logger::debug( "{} {} {}", pos1.x, pos1.y, pos1.z );
setPos( pos1 );
m_pCurrentZone->updateActorPosition( *this ); m_pCurrentZone->updateActorPosition( *this );
face( pos1 );
setPos( pos1 );
sendPositionUpdate();
return false; return false;
} }
@ -477,8 +482,9 @@ void Sapphire::Entity::BNpc::update( uint64_t tickCount )
auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >(); auto pNaviMgr = m_pFw->get< World::Manager::NaviMgr >();
auto pNaviProvider = pNaviMgr->getNaviProvider( m_pCurrentZone->getBgPath() ); auto pNaviProvider = pNaviMgr->getNaviProvider( m_pCurrentZone->getBgPath() );
if( !pNaviProvider ) if( pNaviProvider )
{ {
//if( !pNaviProvider->isAgentActive( *this ) )
pNaviProvider->setMoveTarget( *this, m_roamPos ); pNaviProvider->setMoveTarget( *this, m_roamPos );
} }

View file

@ -48,6 +48,42 @@ bool Sapphire::World::Navi::NaviProvider::init()
if( !m_pCrowd->init( 1000, 10.f, m_naviMesh ) ) if( !m_pCrowd->init( 1000, 10.f, m_naviMesh ) )
return false; return false;
dtObstacleAvoidanceParams params;
// Use mostly default settings, copy from dtCrowd.
memcpy(&params, 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, &params);
// Medium (22)
params.velBias = 0.5f;
params.adaptiveDivs = 5;
params.adaptiveRings = 2;
params.adaptiveDepth = 2;
m_pCrowd->setObstacleAvoidanceParams(1, &params);
// Good (45)
params.velBias = 0.5f;
params.adaptiveDivs = 7;
params.adaptiveRings = 2;
params.adaptiveDepth = 3;
m_pCrowd->setObstacleAvoidanceParams(2, &params);
// High (66)
params.velBias = 0.5f;
params.adaptiveDivs = 7;
params.adaptiveRings = 3;
params.adaptiveDepth = 3;
m_pCrowd->setObstacleAvoidanceParams(3, &params);
m_vod = dtAllocObstacleAvoidanceDebugData();
m_vod->init( 2048 );
initQuery(); initQuery();
return true; return true;
@ -535,19 +571,23 @@ int32_t Sapphire::World::Navi::NaviProvider::addAgent( Entity::Chara& chara )
dtCrowdAgentParams params; dtCrowdAgentParams params;
std::memset( &params, 0, sizeof( params ) ); std::memset( &params, 0, sizeof( params ) );
params.height = 7.f; params.height = 7.f;
params.maxAcceleration = 8.f; params.maxAcceleration = 16.f;
params.maxSpeed = 3.5f; params.maxSpeed = 13.5f;
params.radius = 5.f; params.radius = 2.f;
params.collisionQueryRange = params.radius * 12.0f; params.collisionQueryRange = params.radius * 12.0f;
params.pathOptimizationRange = params.radius * 30.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 }; float position[] = { chara.getPos().x, chara.getPos().y, chara.getPos().z };
return m_pCrowd->addAgent( position, &params ); return m_pCrowd->addAgent( position, &params );
} }
void Sapphire::World::Navi::NaviProvider::updateCrowd( float timeInSeconds ) void Sapphire::World::Navi::NaviProvider::updateCrowd( float timeInSeconds )
{ {
dtCrowdAgentDebugInfo info; dtCrowdAgentDebugInfo info;
info.idx = -1;
info.vod = m_vod;
m_pCrowd->update( timeInSeconds, &info ); m_pCrowd->update( timeInSeconds, &info );
} }
@ -574,7 +614,7 @@ void Sapphire::World::Navi::NaviProvider::setMoveTarget( Entity::Chara& chara,
const float* halfExtents = m_pCrowd->getQueryExtents(); const float* halfExtents = m_pCrowd->getQueryExtents();
float vel[ 3 ]; 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() ); const dtCrowdAgent* ag = m_pCrowd->getAgent( chara.getAgentId() );
if( ag && ag->active ) if( ag && ag->active )
@ -591,3 +631,10 @@ Sapphire::Common::FFXIVARR_POSITION3 Sapphire::World::Navi::NaviProvider::getMov
return { 0.f, 0.f, 0.f }; return { 0.f, 0.f, 0.f };
return { ag->npos[ 0 ], ag->npos[ 1 ], ag->npos[ 2 ] }; return { ag->npos[ 0 ], ag->npos[ 1 ], ag->npos[ 2 ] };
} }
bool Sapphire::World::Navi::NaviProvider::isAgentActive( Entity::Chara& chara ) const
{
const dtCrowdAgent* ag = m_pCrowd->getAgent( chara.getAgentId() );
return ag && ag->active;
}

View file

@ -60,11 +60,14 @@ namespace Sapphire::World::Navi
Common::FFXIVARR_POSITION3 getMovePos( Entity::Chara& chara ); Common::FFXIVARR_POSITION3 getMovePos( Entity::Chara& chara );
bool isAgentActive( Entity::Chara& chara ) const;
protected: protected:
std::string m_internalName; std::string m_internalName;
dtNavMesh* m_naviMesh; dtNavMesh* m_naviMesh;
dtNavMeshQuery* m_naviMeshQuery; dtNavMeshQuery* m_naviMeshQuery;
dtObstacleAvoidanceDebugData* m_vod;
std::unique_ptr< dtCrowd > m_pCrowd; std::unique_ptr< dtCrowd > m_pCrowd;
float m_polyFindRange[ 3 ]; float m_polyFindRange[ 3 ];

View file

@ -474,7 +474,7 @@ bool Sapphire::Zone::update( uint64_t tickCount )
bool changedWeather = checkWeather(); bool changedWeather = checkWeather();
if( m_pNaviProvider ) if( m_pNaviProvider )
m_pNaviProvider->updateCrowd( 0.001f * tickCount ); m_pNaviProvider->updateCrowd( 0.02f );
updateSessions( tickCount, changedWeather ); updateSessions( tickCount, changedWeather );
onUpdate( tickCount ); onUpdate( tickCount );