1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 18:32:44 +01:00

Improved AI and Vehicle Behaviour

This commit is contained in:
Daniel Evans 2013-09-19 01:46:36 +01:00
parent 3520d19306
commit 2b0952557a
8 changed files with 52 additions and 35 deletions

View File

@ -11,11 +11,11 @@ void GTADefaultAIController::update(float dt)
? GTAAINode::Vehicle : GTAAINode::Pedestrian;
float d = std::numeric_limits< float >::max();
auto oldTarget = targetNode;
for( auto n = character->engine->ainodes.begin();
n != character->engine->ainodes.end();
++n ) {
if( (*n)->type != currentType ) continue;
if( (*n) == lastNode ) continue;
float ld = glm::length( (*n)->position - character->getPosition() );
if( ld > nodeMargin && ld < d ) {
d = ld;
@ -40,8 +40,20 @@ void GTADefaultAIController::update(float dt)
}
}
else if( glm::length(targetNode->position - character->getPosition()) < nodeMargin ) {
targetNode = nullptr;
character->changeAction(GTACharacter::Idle);
if(targetNode->connections.size() > 0) {
std::uniform_int_distribution<int> uniform(0, targetNode->connections.size()-1);
GTAAINode* nextNode = nullptr; size_t i = 0;
do
{
nextNode = targetNode->connections[uniform(character->engine->randomEngine)];
} while(i++ < targetNode->connections.size() && nextNode == lastNode);
lastNode = targetNode;
targetNode = nextNode;
}
else {
targetNode = nullptr;
character->changeAction(GTACharacter::Idle);
}
}
}

View File

@ -81,19 +81,7 @@ GTAInstance::GTAInstance(
ainode->nextIndex = node.next >= 0 ? startIndex + node.next : -1;
ainode->flags = GTAAINode::None;
ainode->position = position + (rotation * node.position);
if( node.type == LoaderIDE::EXTERNAL ) {
ainode->flags |= GTAAINode::External;
for( size_t rn = 0; rn < engine->ainodes.size(); ++rn ) {
if( (engine->ainodes[rn]->flags & GTAAINode::External) == GTAAINode::External ) {
auto d = glm::length(engine->ainodes[rn]->position - ainode->position);
if( d < 1.f ) {
ainode->connections.push_back(engine->ainodes[rn]);
engine->ainodes[rn]->connections.push_back(ainode);
}
}
}
}
ainode->external = node.type == LoaderIDE::EXTERNAL;
if( ainode->nextIndex < engine->ainodes.size() ) {
ainode->connections.push_back(engine->ainodes[ainode->nextIndex]);
@ -107,6 +95,16 @@ GTAInstance::GTAInstance(
}
}
if( ainode->external ) {
for( size_t rn = 0; rn < engine->ainodes.size(); ++rn ) {
auto d = glm::length(engine->ainodes[rn]->position - ainode->position);
if( d < 1.f ) {
ainode->connections.push_back(engine->ainodes[rn]);
engine->ainodes[rn]->connections.push_back(ainode);
}
}
}
engine->ainodes.push_back(ainode);
}

View File

@ -33,22 +33,14 @@ void GTAPlayerAIController::update(float dt)
}
if( character->getCurrentVehicle() ) {
glm::vec3 dir = glm::length(direction) > 0.001f ? direction : glm::vec3(0.f, 1.f, 0.f);
glm::vec3 vehicleDir = character->getCurrentVehicle()->getRotation() * dir;
float a = -atan2(vehicleDir.x, vehicleDir.y);
character->getCurrentVehicle()->setSteeringAngle(a);
character->getCurrentVehicle()->setSteeringAngle(-direction.x * 3.131f);
}
else if( glm::length(direction) > 0.001f ) {
character->rotation = cameraRotation * glm::quat(glm::vec3(0.f, 0.f, -atan2(direction.x, direction.y)));
}
// TODO what is handbraking.
if( direction.y > 0.f ) {
character->getCurrentVehicle()->setThrottle(direction.y);
}
else if( direction.y < 0.f ) {
character->getCurrentVehicle()->setBraking(-direction.y);
}
character->getCurrentVehicle()->setThrottle(direction.y);
}
glm::vec3 GTAPlayerAIController::getTargetPosition()

View File

@ -565,11 +565,21 @@ void GTARenderer::renderPaths()
if( start->type == GTAAINode::Pedestrian ) {
pedlines.push_back(start->position);
pedlines.push_back(start->position+glm::vec3(0.f, 0.f, 1.f));
if( start->external ) {
pedlines.push_back(start->position+glm::vec3(0.f, 0.f, 2.f));
}
else {
pedlines.push_back(start->position+glm::vec3(0.f, 0.f, 1.f));
}
}
else {
carlines.push_back(start->position);
carlines.push_back(start->position+glm::vec3(0.f, 0.f, 1.f));
if( start->external ) {
carlines.push_back(start->position+glm::vec3(0.f, 0.f, 2.f));
}
else {
carlines.push_back(start->position+glm::vec3(0.f, 0.f, 1.f));
}
}
for( size_t c = 0; c < start->connections.size(); ++c ) {

View File

@ -69,7 +69,7 @@ GTAVehicle::GTAVehicle(GTAEngine* engine, const glm::vec3& pos, const glm::quat&
btRaycastVehicle::btVehicleTuning tuning;
float travel = info.handling.suspensionUpperLimit - info.handling.suspensionLowerLimit;
tuning.m_frictionSlip = 0.8f;
tuning.m_frictionSlip = 1.8f;
tuning.m_maxSuspensionTravelCm = travel * 100.f;
physVehicle = new btRaycastVehicle(tuning, physBody, physRaycaster);

View File

@ -193,10 +193,10 @@ bool LoaderIDE::load(const std::string &filename)
case 0:
node.type = EMPTY;
break;
case 1:
case 2:
node.type = INTERNAL;
break;
case 2:
case 1:
node.type = EXTERNAL;
break;
}

View File

@ -14,13 +14,13 @@ struct GTAAINode
enum {
None = 0,
External = 1, /// Node can connect to external nodes.
CrossesRoad = 4 /// No documentation for other flags yet, but this is mentioned.
CrossesRoad = 1 /// No documentation for other flags yet, but this is mentioned.
};
NodeType type;
glm::vec3 position;
uint32_t flags;
bool external;
uint8_t flags;
int32_t nextIndex;

View File

@ -15,13 +15,18 @@ class GTADefaultAIController : public GTAAIController
Action action;
GTAAINode* targetNode;
GTAAINode* lastNode;
float nodeMargin; /// Minimum distance away to "reach" node.
public:
GTADefaultAIController(GTACharacter* character)
: GTAAIController(character), action(Wander), targetNode(nullptr), nodeMargin(0.f) {}
: GTAAIController(character),
action(Wander),
targetNode(nullptr),
lastNode(nullptr),
nodeMargin(0.f) {}
void update(float dt);