mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-09 12:22:34 +01:00
Initial Traffic wandering algorithm (pedestrians only)
This commit is contained in:
parent
fe4926e5d6
commit
7f2c5a4645
@ -5,6 +5,7 @@
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <string>
|
||||
|
||||
struct AIGraphNode;
|
||||
class CharacterObject;
|
||||
class VehicleObject;
|
||||
|
||||
@ -40,7 +41,11 @@ public:
|
||||
/**
|
||||
* Keep close to leader character
|
||||
*/
|
||||
FollowLeader
|
||||
FollowLeader,
|
||||
/**
|
||||
* Wander randomly around the map
|
||||
*/
|
||||
TrafficWander
|
||||
};
|
||||
|
||||
protected:
|
||||
@ -65,6 +70,7 @@ protected:
|
||||
// Goal related variables
|
||||
Goal currentGoal;
|
||||
CharacterObject* leader;
|
||||
AIGraphNode* targetNode;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -28,7 +28,7 @@ void CharacterController::setActivity(CharacterController::Activity* activity)
|
||||
|
||||
CharacterController::CharacterController(CharacterObject* character)
|
||||
: character(character), _currentActivity(nullptr), _nextActivity(nullptr), running(false),
|
||||
vehicleIdle(0.f), currentGoal(None), leader(nullptr)
|
||||
vehicleIdle(0.f), currentGoal(None), leader(nullptr), targetNode(nullptr)
|
||||
{
|
||||
character->controller = this;
|
||||
}
|
||||
|
@ -55,6 +55,45 @@ void DefaultAIController::update(float dt)
|
||||
}
|
||||
}
|
||||
break;
|
||||
case TrafficWander:
|
||||
{
|
||||
if( targetNode )
|
||||
{
|
||||
auto targetDistance = glm::vec2(character->getPosition() - targetNode->position);
|
||||
if( glm::length(targetDistance) <= 0.1f )
|
||||
{
|
||||
// Assign the next target node
|
||||
auto lastTarget = targetNode;
|
||||
std::random_device rd;
|
||||
std::default_random_engine re(rd());
|
||||
std::uniform_int_distribution<> d(0, lastTarget->connections.size()-1);
|
||||
targetNode = lastTarget->connections.at(d(re));
|
||||
setNextActivity(new Activities::GoTo(targetNode->position));
|
||||
}
|
||||
else if ( getCurrentActivity() == nullptr )
|
||||
{
|
||||
setNextActivity(new Activities::GoTo(targetNode->position));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need to pick an initial node
|
||||
auto& graph = getCharacter()->engine->aigraph;
|
||||
AIGraphNode* node = nullptr;
|
||||
float mindist = std::numeric_limits<float>::max();
|
||||
for( auto n : graph.nodes )
|
||||
{
|
||||
float d = glm::distance( n->position, getCharacter()->getPosition() );
|
||||
if( d < mindist )
|
||||
{
|
||||
node = n;
|
||||
mindist = d;
|
||||
}
|
||||
}
|
||||
targetNode = node;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include "ai/TrafficDirector.hpp"
|
||||
#include <ai/AIGraphNode.hpp>
|
||||
#include <ai/CharacterController.hpp>
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <engine/GameObject.hpp>
|
||||
#include <objects/CharacterObject.hpp>
|
||||
@ -18,8 +19,8 @@ std::vector< AIGraphNode* > TrafficDirector::findAvailableNodes(AIGraphNode::Nod
|
||||
|
||||
for ( AIGraphNode* node : graph->nodes )
|
||||
{
|
||||
if ( node->type != type ) continue;
|
||||
if ( ! node->external ) continue;
|
||||
if ( node->type != type ) continue;
|
||||
if ( glm::distance( near, node->position ) < radius )
|
||||
{
|
||||
available.push_back( node );
|
||||
@ -75,6 +76,13 @@ std::vector<GameObject*> TrafficDirector::populateNearby(const glm::vec3& center
|
||||
auto type = AIGraphNode::Pedestrian;
|
||||
auto available = findAvailableNodes(type, center, radius);
|
||||
|
||||
/// Hardcoded cop Pedestrian
|
||||
std::vector<uint16_t> validPeds = { 1 };
|
||||
validPeds.insert(validPeds.end(), {20, 11, 19, 5});
|
||||
std::random_device rd;
|
||||
std::default_random_engine re(rd());
|
||||
std::uniform_int_distribution<> d(0, validPeds.size()-1);
|
||||
|
||||
for ( AIGraphNode* spawn : available )
|
||||
{
|
||||
if ( maxPopulation > -1 )
|
||||
@ -86,10 +94,11 @@ std::vector<GameObject*> TrafficDirector::populateNearby(const glm::vec3& center
|
||||
maxPopulation --;
|
||||
}
|
||||
|
||||
// spawn a cop
|
||||
auto cop = world->createPedestrian(1, spawn->position + glm::vec3( 0.f, 0.f, 1.f ) );
|
||||
cop->setLifetime(GameObject::TrafficLifetime);
|
||||
created.push_back( cop );
|
||||
// Spawn a pedestrian from the available pool
|
||||
auto ped = world->createPedestrian(validPeds[d(re)], spawn->position + glm::vec3( 0.f, 0.f, 1.f ) );
|
||||
ped->setLifetime(GameObject::TrafficLifetime);
|
||||
ped->controller->setGoal(CharacterController::TrafficWander);
|
||||
created.push_back( ped );
|
||||
}
|
||||
|
||||
// Find places it's legal to spawn things
|
||||
|
Loading…
Reference in New Issue
Block a user