1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-09-15 15:02:34 +02:00

Add test implementation of pedestrian spawning

This commit is contained in:
Daniel Evans 2015-02-18 15:29:39 +00:00
parent 2ccc1fc33c
commit 9407ee3135
6 changed files with 95 additions and 0 deletions

View File

@ -7,6 +7,7 @@
#include <glm/glm.hpp>
#include <vector>
class GameObject;
class GameWorld;
class TrafficDirector
@ -19,6 +20,8 @@ public:
void setDensity(AIGraphNode::NodeType type, float density);
std::vector<GameObject*> populateNearby( const glm::vec3& center, float radius, int maxPopulation = -1 );
private:
AIGraph* graph;
GameWorld* world;

View File

@ -107,6 +107,8 @@ public:
*/
bool placeItems(const std::string& name);
void createTraffic(const glm::vec3& near);
/**
* Creates an instance
*/

View File

@ -2,6 +2,8 @@
#include <ai/AIGraphNode.hpp>
#include <engine/GameWorld.hpp>
#include <engine/GameObject.hpp>
#include <objects/CharacterObject.hpp>
#include <glm/gtx/string_cast.hpp>
TrafficDirector::TrafficDirector(AIGraph* graph, GameWorld* world)
@ -65,3 +67,32 @@ void TrafficDirector::setDensity(AIGraphNode::NodeType type, float density)
break;
}
}
std::vector<GameObject*> TrafficDirector::populateNearby(const glm::vec3& center, float radius, int maxPopulation)
{
std::vector<GameObject*> created;
auto type = AIGraphNode::Pedestrian;
auto available = findAvailableNodes(type, center, radius);
for ( AIGraphNode* spawn : available )
{
if ( maxPopulation > -1 )
{
if ( maxPopulation == 0 )
{
break;
}
maxPopulation --;
}
// spawn a cop
auto cop = world->createPedestrian(1, spawn->position + glm::vec3( 0.f, 0.f, 1.f ) );
created.push_back( cop );
}
// Find places it's legal to spawn things
return created;
}

View File

@ -2,6 +2,7 @@
#include <loaders/LoaderIPL.hpp>
#include <loaders/LoaderIDE.hpp>
#include <ai/DefaultAIController.hpp>
#include <ai/TrafficDirector.hpp>
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <render/Model.hpp>
#include <data/WeaponData.hpp>
@ -291,6 +292,14 @@ InstanceObject *GameWorld::createInstance(const uint16_t id, const glm::vec3& po
return nullptr;
}
void GameWorld::createTraffic(const glm::vec3& near)
{
TrafficDirector director(&aigraph, this);
director.populateNearby( near, 100, 5 );
}
#include <strings.h>
uint16_t GameWorld::findModelDefinition(const std::string model)
{

View File

@ -203,6 +203,13 @@ void RWGame::tick(float dt)
throw;
}
}
if ( engine->state.player )
{
// Use the current camera position to spawn pedestrians.
auto p = nextCam.position;
engine->createTraffic(p);
}
}
// render() needs two cameras to smoothly interpolate between ticks.
@ -311,6 +318,20 @@ void RWGame::renderDebugStats(float time)
ss << "Frametime: " << time << " (FPS " << (1.f/time) << ")\n";
ss << "Draws: " << engine->renderer.rendered << " (" << engine->renderer.culled << " Culled)\n";
// Count the number of interesting objects.
int peds = 0, cars = 0;
for( GameObject* object : engine->objects )
{
switch ( object->type() )
{
case GameObject::Character: peds++; break;
case GameObject::Vehicle: cars++; break;
default: break;
}
}
ss << "P " << peds << " V " << cars << "\n";
if( engine->state.player ) {
ss << "Player Activity: ";
if( engine->state.player->getCurrentActivity() ) {

View File

@ -187,4 +187,33 @@ BOOST_AUTO_TEST_CASE(test_node_density)
Global::get().e->destroyObject(ped);
}
BOOST_AUTO_TEST_CASE(test_create_traffic)
{
AIGraph graph;
PathData path {
PathData::PATH_PED,
0, "",
{
{
PathNode::EXTERNAL,
1,
{ 10.f, 10.f, 0.f },
1.f, 0, 0
},
}
};
graph.createPathNodes(glm::vec3(), glm::quat(), path);
TrafficDirector director(&graph, Global::get().e);
auto created = director.populateNearby(glm::vec3(0.f, 0.f, 0.f), 20.f);
BOOST_CHECK( created.size() == 1 );
//Global::get().e->destroyObject(created[0]);
}
BOOST_AUTO_TEST_SUITE_END()