mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-30 08:44:19 -04:00
not my code, not my code
This commit is contained in:
parent
750405202b
commit
c310c29a77
@ -24,7 +24,7 @@
|
||||
evade.h \
|
||||
flee.h \
|
||||
flock.h \
|
||||
globals.h \
|
||||
aiGlobals.h \
|
||||
meshNode.h \
|
||||
obstacleAvoidance.h \
|
||||
pathFind.h \
|
||||
@ -67,7 +67,7 @@
|
||||
evade.h \
|
||||
flee.h \
|
||||
flock.h \
|
||||
globals.h \
|
||||
aiGlobals.h \
|
||||
meshNode.h \
|
||||
obstacleAvoidance.h \
|
||||
pathFind.h \
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,33 +1,38 @@
|
||||
// Filename: aiBehaviors.h
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiBehaviors.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 8 Sep 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AIBEHAVIORS_H
|
||||
#define AIBEHAVIORS_H
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
#ifndef _AIBEHAVIORS_H
|
||||
#define _AIBEHAVIORS_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
#include "seek.h"
|
||||
#include "flee.h"
|
||||
#include "pursue.h"
|
||||
#include "evade.h"
|
||||
#include "arrival.h"
|
||||
#include "flock.h"
|
||||
#include "wander.h"
|
||||
#include "pathFollow.h"
|
||||
#include "pathFind.h"
|
||||
#include "obstacleAvoidance.h"
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : AIBehaviors
|
||||
// Description : This class implements all the steering behaviors of the AI framework, such as
|
||||
// seek, flee, pursue, evade, wander and flock. Each steering behavior has a weight which is used when more than
|
||||
// one type of steering behavior is acting on the same ai character. The weight decides the contribution of each
|
||||
// type of steering behavior. The AICharacter class has a handle to an object of this class and this allows to
|
||||
// invoke the steering behaviors via the AICharacter. This class also provides functionality such as pausing, resuming
|
||||
// and removing the AI behaviors of an AI character at anytime.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AICharacter;
|
||||
class Seek;
|
||||
@ -44,40 +49,24 @@ class ObstacleAvoidance;
|
||||
typedef list<Flee, allocator<Flee> > ListFlee;
|
||||
typedef list<Evade, allocator<Evade> > ListEvade;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AIBehaviors
|
||||
// Description : This class implements all the steering behaviors
|
||||
// of the AI framework, such as seek, flee, pursue,
|
||||
// evade, wander and flock. Each steering behavior
|
||||
// has a weight which is used when more than one type
|
||||
// of steering behavior is acting on the same AI
|
||||
// character. The weight decides the contribution of
|
||||
// each type of steering behavior. The AICharacter
|
||||
// class has a handle to an object of this class and
|
||||
// this allows to invoke the steering behaviors via
|
||||
// the AICharacter. This class also provides
|
||||
// functionality such as pausing, resuming and
|
||||
// removing the AI behaviors of an AI character at
|
||||
// any time.
|
||||
///////////////////////////////////////////////////////////////////
|
||||
class AIBehaviors {
|
||||
class EXPCL_PANDAAI AIBehaviors {
|
||||
|
||||
public:
|
||||
enum BehaviorType {
|
||||
BT_none = 0x00000,
|
||||
BT_seek = 0x00002,
|
||||
BT_flee = 0x00004,
|
||||
BT_flee_activate = 0x00100,
|
||||
BT_arrival = 0x00008,
|
||||
BT_arrival_activate = 0x01000,
|
||||
BT_wander = 0x00010,
|
||||
BT_pursue = 0x00040,
|
||||
BT_evade = 0x00080,
|
||||
BT_evade_activate = 0x00800,
|
||||
BT_flock = 0x00200,
|
||||
BT_flock_activate = 0x00400,
|
||||
BT_obstacle_avoidance = 0x02000,
|
||||
BT_obstacle_avoidance_activate = 0x04000,
|
||||
enum _behavior_type {
|
||||
_none = 0x00000,
|
||||
_seek = 0x00002,
|
||||
_flee = 0x00004,
|
||||
_flee_activate = 0x00100,
|
||||
_arrival = 0x00008,
|
||||
_arrival_activate = 0x01000,
|
||||
_wander = 0x00010,
|
||||
_pursue = 0x00040,
|
||||
_evade = 0x00080,
|
||||
_evade_activate = 0x00800,
|
||||
_flock = 0x00200,
|
||||
_flock_activate = 0x00400,
|
||||
_obstacle_avoidance = 0x02000,
|
||||
_obstacle_avoidance_activate = 0x04000
|
||||
};
|
||||
|
||||
AICharacter *_ai_char;
|
||||
@ -92,8 +81,7 @@ public:
|
||||
Flee *_flee_obj;
|
||||
LVecBase3f _flee_force;
|
||||
|
||||
// This list is used if the ai character needs to flee from
|
||||
// multiple onjects.
|
||||
//! This list is used if the ai character needs to flee from multiple onjects.
|
||||
ListFlee _flee_list;
|
||||
ListFlee::iterator _flee_itr;
|
||||
|
||||
@ -103,16 +91,14 @@ public:
|
||||
Evade *_evade_obj;
|
||||
LVecBase3f _evade_force;
|
||||
|
||||
// This list is used if the ai character needs to evade from
|
||||
// multiple onjects.
|
||||
//! This list is used if the ai character needs to evade from multiple onjects.
|
||||
ListEvade _evade_list;
|
||||
ListEvade::iterator _evade_itr;
|
||||
|
||||
Arrival *_arrival_obj;
|
||||
LVecBase3f _arrival_force;
|
||||
|
||||
// Since Flock is a collective behavior the variables are
|
||||
// declared within the AIBehaviors class.
|
||||
//! Since Flock is a collective behavior the variables are declared within the AIBehaviors class.
|
||||
float _flock_weight;
|
||||
LVecBase3f _flock_force;
|
||||
bool _flock_done;
|
||||
@ -132,11 +118,10 @@ public:
|
||||
AIBehaviors();
|
||||
~AIBehaviors();
|
||||
|
||||
bool is_on(BehaviorType bt);
|
||||
bool is_off(BehaviorType bt);
|
||||
// special cases for pathfollow and pathfinding
|
||||
bool is_on(string ai_type);
|
||||
bool is_off(string ai_type);
|
||||
bool is_on(_behavior_type bt);
|
||||
bool is_on(string ai_type); // special cases for pathfollow and pathfinding
|
||||
bool is_off(_behavior_type bt);
|
||||
bool is_off(string ai_type); // special cases for pathfollow and pathfinding
|
||||
void turn_on(string ai_type);
|
||||
void turn_off(string ai_type);
|
||||
|
||||
@ -154,34 +139,32 @@ PUBLISHED:
|
||||
void seek(NodePath target_object, float seek_wt = 1.0);
|
||||
void seek(LVecBase3f pos, float seek_wt = 1.0);
|
||||
|
||||
void flee(NodePath target_object, double panic_distance = 10.0,
|
||||
double relax_distance = 10.0, float flee_wt = 1.0);
|
||||
void flee(LVecBase3f pos, double panic_distance = 10.0,
|
||||
double relax_distance = 10.0, float flee_wt = 1.0);
|
||||
void flee(NodePath target_object, double panic_distance = 10.0, double relax_distance = 10.0, float flee_wt = 1.0);
|
||||
void flee(LVecBase3f pos, double panic_distance = 10.0, double relax_distance = 10.0, float flee_wt = 1.0);
|
||||
|
||||
void pursue(NodePath target_object, float pursue_wt = 1.0);
|
||||
|
||||
void evade(NodePath target_object, double panic_distance = 10.0,
|
||||
double relax_distance = 10.0, float evade_wt = 1.0);
|
||||
void evade(NodePath target_object, double panic_distance = 10.0, double relax_distance = 10.0, float evade_wt = 1.0);
|
||||
|
||||
void arrival(double distance = 10.0);
|
||||
|
||||
void flock(float flock_wt);
|
||||
|
||||
void wander(double wander_radius = 5.0, int flag =0,
|
||||
double aoe = 0.0, float wander_weight = 1.0);
|
||||
void wander(double wander_radius = 5.0, int flag =0, double aoe = 0.0, float wander_weight = 1.0);
|
||||
|
||||
void obstacle_avoidance(float feeler_length = 1.0);
|
||||
|
||||
void path_follow(float follow_wt = 1.0);
|
||||
void path_follow(float follow_wt);
|
||||
void add_to_path(LVecBase3f pos);
|
||||
void start_follow(string type = "normal");
|
||||
|
||||
// should have different function names.
|
||||
void init_path_find(const char* navmesh_filename);
|
||||
void path_find_to(LVecBase3f pos, string type = "normal");
|
||||
void path_find_to(NodePath target, string type = "normal");
|
||||
void add_static_obstacle(NodePath obstacle);
|
||||
void add_dynamic_obstacle(NodePath obstacle);
|
||||
//
|
||||
|
||||
void remove_ai(string ai_type);
|
||||
void pause_ai(string ai_type);
|
||||
@ -191,3 +174,14 @@ PUBLISHED:
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -1,21 +1,21 @@
|
||||
// Filename: aiCharacter.cxx
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiCharacter.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 8 Sep 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "aiCharacter.h"
|
||||
|
||||
AICharacter::AICharacter(string model_name, NodePath model_np, double mass,
|
||||
double movt_force, double max_force) {
|
||||
AICharacter::AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force) {
|
||||
_name = model_name;
|
||||
_ai_char_np = model_np;
|
||||
|
||||
@ -35,16 +35,18 @@ AICharacter::AICharacter(string model_name, NodePath model_np, double mass,
|
||||
AICharacter::~AICharacter() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: update
|
||||
// Description: Each character's update will update its ai and
|
||||
// physics based on his resultant steering force.
|
||||
// This also makes the character look in the
|
||||
// direction of the force.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : update
|
||||
// Description : Each character's update will update its ai and physics
|
||||
// based on his resultant steering force.
|
||||
// This also makes the character look at the direction of the force.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AICharacter::update() {
|
||||
|
||||
if (!_steering->is_off(_steering->BT_none)) {
|
||||
if(!_steering->is_off(_steering->_none)) {
|
||||
|
||||
LVecBase3f old_pos = _ai_char_np.get_pos();
|
||||
|
||||
@ -59,7 +61,7 @@ if (!_steering->is_off(_steering->BT_none)) {
|
||||
|
||||
_ai_char_np.set_pos(old_pos + _velocity) ;
|
||||
|
||||
if (steering_force.length() > 0) {
|
||||
if(steering_force.length() > 0) {
|
||||
_ai_char_np.look_at(old_pos + (direction * 5));
|
||||
_ai_char_np.set_h(_ai_char_np.get_h() + 180);
|
||||
_ai_char_np.set_p(-_ai_char_np.get_p());
|
||||
|
@ -1,34 +1,42 @@
|
||||
// Filename: aiCharacter.h
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiCharacter.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 8 Sep 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license along
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AICHARACTER_H
|
||||
#define AICHARACTER_H
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
|
||||
#ifndef _AICHARACTER_H
|
||||
#define _AICHARACTER_H
|
||||
|
||||
#include "aiBehaviors.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : AICharacter
|
||||
// Description : This class is used for creating the ai characters. It assigns both physics and ai
|
||||
// attributes to the character. It also has an update function which updates the physics and ai
|
||||
// of the character. This update function is called by the AIWorld update.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class AIBehaviors;
|
||||
class AIWorld;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AICharacter
|
||||
// Description : This class is used for creating the ai characters.
|
||||
// It assigns both physics and ai attributes to the
|
||||
// character. It also has an update function which
|
||||
// updates the physics and ai of the character.
|
||||
// This update function is called by the AIWorld
|
||||
// update.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class AICharacter {
|
||||
public:
|
||||
class EXPCL_PANDAAI AICharacter {
|
||||
public:
|
||||
double _mass;
|
||||
double _max_force;
|
||||
LVecBase3f _velocity;
|
||||
@ -61,12 +69,10 @@ PUBLISHED:
|
||||
|
||||
AIBehaviors * get_ai_behaviors();
|
||||
|
||||
// This function is used to enable or disable the guides
|
||||
// for path finding.
|
||||
// This function is used to enable or disable the guides for path finding.
|
||||
void set_pf_guide(bool pf_guide);
|
||||
|
||||
AICharacter(string model_name, NodePath model_np, double mass,
|
||||
double movt_force, double max_force);
|
||||
AICharacter(string model_name, NodePath model_np, double mass, double movt_force, double max_force);
|
||||
~AICharacter();
|
||||
};
|
||||
|
||||
|
@ -1,20 +1,27 @@
|
||||
// Filename: aiGlobals.h
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiGlobals.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date: 8 Sep 09
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AIGLOBALS_H
|
||||
#define AIGLOBALS_H
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
#ifndef _AI_GLOBALS_H
|
||||
#define _AI_GLOBALS_H
|
||||
|
||||
#include "config_ai.h"
|
||||
#include "pandaFramework.h"
|
||||
#include "textNode.h"
|
||||
#include "pandaSystem.h"
|
||||
|
@ -6,9 +6,9 @@
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -6,9 +6,9 @@
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
// tool makes use of this class to generate the nodes
|
||||
// on the mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class AINode {
|
||||
class EXPCL_PANDAAI AINode {
|
||||
PUBLISHED:
|
||||
// This variable specifies whether the node is an obtacle or not.
|
||||
// Used for dynamic obstacle addition to the environment.
|
||||
|
@ -1,13 +1,14 @@
|
||||
// Filename: aiPathfinder.cxx
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiPathFinder.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 10 Nov 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license along
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -21,22 +22,22 @@ PathFinder::PathFinder(NavMesh nav_mesh) {
|
||||
PathFinder::~PathFinder() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: find_path
|
||||
// Description: This function initializes the pathfinding process
|
||||
// by accepting the source and destination nodes.
|
||||
// It then calls the generate_path().
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFinder::find_path(AINode *src_node, AINode *dest_node) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : find_path
|
||||
// Description : This function initializes the pathfinding process by accepting the
|
||||
// source and destination nodes. It then calls the generate_path().
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::find_path(Node *src_node, Node *dest_node) {
|
||||
_src_node = src_node;
|
||||
_dest_node = dest_node;
|
||||
|
||||
// Add a dummy node as the first element of the open list with score
|
||||
// = -1.
|
||||
// Inorder to implement a binary heap the index of the elements
|
||||
// should never be 0.
|
||||
AINode *_dummy_node = new AINode(-1, -1, LVecBase3f(0.0, 0.0, 0.0), 0, 0, 0);
|
||||
_dummy_node->_status = _dummy_node->ST_open;
|
||||
// Add a dummy node as the first element of the open list with score = -1.
|
||||
// Inorder to implement a binary heap the index of the elements should never be 0.
|
||||
Node *_dummy_node = new Node(-1, -1, LVecBase3f(0.0, 0.0, 0.0), 0, 0, 0);
|
||||
_dummy_node->_status = _dummy_node->open;
|
||||
_dummy_node->_score = -1;
|
||||
_open_list.push_back(_dummy_node);
|
||||
|
||||
@ -47,23 +48,24 @@ void PathFinder::find_path(AINode *src_node, AINode *dest_node) {
|
||||
generate_path();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: generate_path
|
||||
// Description: This function performs the pathfinding process
|
||||
// using the A* algorithm.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : generate_path
|
||||
// Description : This function performs the pathfinding process using the A* algorithm.
|
||||
// It updates the openlist and closelist.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::generate_path() {
|
||||
// All the A* algorithm is implemented here.
|
||||
// The check is > 1 due to the existence of the dummy node.
|
||||
while (_open_list.size() > 1) {
|
||||
// The first element of the open list will always be the optimal
|
||||
// node.
|
||||
// This is because the open list is a binary heap with element
|
||||
// having the smallest score at the top of the heap.
|
||||
AINode* nxt_node = _open_list[1];
|
||||
while(_open_list.size() > 1) {
|
||||
// The first element of the open list will always be the optimal node.
|
||||
// This is because the open list is a binary heap with element having the
|
||||
// smallest score at the top of the heap.
|
||||
Node* nxt_node = _open_list[1];
|
||||
|
||||
if (nxt_node->_grid_x == _dest_node->_grid_x &&
|
||||
if(nxt_node->_grid_x == _dest_node->_grid_x &&
|
||||
nxt_node->_grid_y == _dest_node->_grid_y) {
|
||||
// Remove the optimal node from the top of the heap.
|
||||
remove_from_olist();
|
||||
@ -81,23 +83,25 @@ void PathFinder::generate_path() {
|
||||
add_to_clist(nxt_node);
|
||||
}
|
||||
}
|
||||
cout << "DESTINATION NOT REACHABLE MATE!\n";
|
||||
cout<<"DESTINATION NOT REACHABLE MATE!"<<endl;
|
||||
_closed_list.clear();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: identify_neighbors
|
||||
// Description: This function traverses through the 8 neigbors of
|
||||
// the parent node and then adds the neighbors to the
|
||||
// _open_list based on A* criteria.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFinder::identify_neighbors(AINode *parent_node) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : identify_neighbors
|
||||
// Description : This function traverses through the 8 neigbors of the parent node and
|
||||
// then adds the neighbors to the _open_list based on A* criteria.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::identify_neighbors(Node *parent_node) {
|
||||
// Remove the parent node from the open_list so that it is not considered
|
||||
// while adding new nodes to the open list heap.
|
||||
remove_from_olist();
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
if (parent_node->_neighbours[i] != NULL) {
|
||||
if (parent_node->_neighbours[i]->_status == parent_node->_neighbours[i]->ST_neutral
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
if(parent_node->_neighbours[i] != NULL) {
|
||||
if(parent_node->_neighbours[i]->_status == parent_node->_neighbours[i]->neutral
|
||||
&& parent_node->_neighbours[i]->_type == true) {
|
||||
// Link the neighbor to the parent node.
|
||||
parent_node->_neighbours[i]->_prv_node = parent_node;
|
||||
@ -110,30 +114,35 @@ void PathFinder::identify_neighbors(AINode *parent_node) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: calc_node_score
|
||||
// Description: This function calculates the score of each node.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : calc_node_score
|
||||
// Description : This function calculates the score of each node.
|
||||
// Score = Cost + Heuristics.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFinder::calc_node_score(AINode *nd) {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::calc_node_score(Node *nd) {
|
||||
nd->_cost = calc_cost_frm_src(nd);
|
||||
nd->_heuristic = calc_heuristic(nd);
|
||||
nd->_score = nd->_cost + nd->_heuristic;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: calc_cost_frm_src
|
||||
// Description: This function calculates the cost of each node by
|
||||
// finding out the number of node traversals required
|
||||
// to reach the source node.
|
||||
// Diagonal traversals have have cost = 14.
|
||||
// Horizontal / Vertical traversals have cost = 10.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PathFinder::calc_cost_frm_src(AINode *nd) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : calc_cost_frm_src
|
||||
// Description : This function calculates the cost of each node by finding out
|
||||
// the number of node traversals required to reach the source node.
|
||||
// Diagonal traversals have cost = 14.
|
||||
// Horizontal / Vertical traversals have cost = 10.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int PathFinder::calc_cost_frm_src(Node *nd) {
|
||||
int cost = 0;
|
||||
AINode *start_node = nd;
|
||||
while (start_node->_prv_node != _src_node) {
|
||||
if (is_diagonal_node(start_node)) {
|
||||
Node *start_node = nd;
|
||||
while(start_node->_prv_node != _src_node) {
|
||||
if(is_diagonal_node(start_node)) {
|
||||
cost += 14;
|
||||
}
|
||||
else {
|
||||
@ -142,7 +151,7 @@ int PathFinder::calc_cost_frm_src(AINode *nd) {
|
||||
start_node = start_node->_prv_node;
|
||||
}
|
||||
// Add the cost of traversal to the source node also.
|
||||
if (is_diagonal_node(start_node)) {
|
||||
if(is_diagonal_node(start_node)) {
|
||||
cost += 14;
|
||||
}
|
||||
else {
|
||||
@ -151,15 +160,16 @@ int PathFinder::calc_cost_frm_src(AINode *nd) {
|
||||
return cost;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: calc_heuristic
|
||||
// Description: This function calculates the heuristic of the nodes
|
||||
// using Manhattan method. All it does is predict the
|
||||
// number of node traversals required to reach the
|
||||
// target node. No diagonal traversals are allowed
|
||||
// in this technique.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int PathFinder::calc_heuristic(AINode *nd) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : calc_heuristic
|
||||
// Description : This function calculates the heuristic of the nodes using Manhattan method.
|
||||
// All it does is predict the number of node traversals required to reach the target node.
|
||||
// No diagonal traversals are allowed in this technique.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int PathFinder::calc_heuristic(Node *nd) {
|
||||
int row_diff = abs(_dest_node->_grid_x - nd->_grid_x);
|
||||
int col_diff = abs(_dest_node->_grid_y - nd->_grid_y);
|
||||
|
||||
@ -167,20 +177,20 @@ int PathFinder::calc_heuristic(AINode *nd) {
|
||||
return heuristic;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: is_diagonal_node
|
||||
// Description: This function checks if the traversal from a
|
||||
// node is diagonal.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PathFinder::is_diagonal_node(AINode *nd) {
|
||||
// Calculate the row and column differences between child and parent
|
||||
// nodes.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : is_diagonal_node
|
||||
// Description : This function checks if the traversal from a node is diagonal.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool PathFinder::is_diagonal_node(Node *nd) {
|
||||
// Calculate the row and column differences between child and parent nodes.
|
||||
float row_diff = nd->_grid_x - nd->_prv_node->_grid_x;
|
||||
float col_diff = nd->_grid_y - nd->_prv_node->_grid_y;
|
||||
|
||||
// Check if the relationship between child and parent node is
|
||||
// diagonal.
|
||||
if (row_diff == 0 || col_diff == 0) {
|
||||
// Check if the relationship between child and parent node is diagonal.
|
||||
if(row_diff == 0 || col_diff == 0) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
@ -188,35 +198,37 @@ bool PathFinder::is_diagonal_node(AINode *nd) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_to_olist
|
||||
// Description: This function adds a node to the open list heap.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_to_olist
|
||||
// Description : This function adds a node to the open list heap.
|
||||
// A binay heap is maintained to improve the search.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFinder::add_to_olist(AINode *nd) {
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void PathFinder::add_to_olist(Node *nd) {
|
||||
// Variables required to search the binary heap.
|
||||
AINode *child_node, *parent_node;
|
||||
Node *child_node, *parent_node;
|
||||
int child_idx, parent_idx;
|
||||
|
||||
// Set the status as open.
|
||||
nd->_status = nd->ST_open;
|
||||
nd->_status = nd->open;
|
||||
// Add the node to the open list.
|
||||
_open_list.push_back(nd);
|
||||
|
||||
// Find the parent and child nodes and create temporary nodes out
|
||||
// of them. In a binary heap the children of a parent node are
|
||||
// always i*2 and i*2 + 1, where i is the index of the parent node
|
||||
// in the heap. And hence, the parent of a node can be easily found
|
||||
// out by dividing by 2 and rounding it.
|
||||
// Find the parent and child nodes and create temporary nodes out of them.
|
||||
// In a binary heap the children of a parent node are always i*2 and i*2 + 1,
|
||||
// where i is the index of the parent node in the heap. And hence, the parent
|
||||
// of a node can be easily found out by dividing by 2 and rounding it.
|
||||
child_idx = _open_list.size() - 1;
|
||||
parent_idx = child_idx / 2;
|
||||
child_node = _open_list[child_idx];
|
||||
parent_node = _open_list[parent_idx];
|
||||
|
||||
// Keep traversing the heap until the lowest element in the list is
|
||||
// bubbled
|
||||
// Keep traversing the heap until the lowest element in the list is bubbled
|
||||
// to the top of the heap.
|
||||
while (_open_list[child_idx]->_score <= _open_list[parent_idx]->_score) {
|
||||
while(_open_list[child_idx]->_score <= _open_list[parent_idx]->_score) {
|
||||
// Swap the parent node and the child node.
|
||||
_open_list[parent_idx] = child_node;
|
||||
_open_list[child_idx] = parent_node;
|
||||
@ -230,53 +242,52 @@ void PathFinder::add_to_olist(AINode *nd) {
|
||||
parent_node = _open_list[parent_idx];
|
||||
}
|
||||
|
||||
// At this point the AINode with the smallest score will be at the
|
||||
// top of the heap.
|
||||
// At this point the Node with the smallest score will be at the top of the heap.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: remove_from_olist
|
||||
// Description: This function removes a node from the open list.
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : remove_from_olist
|
||||
// Description : This function removes a node from the open list.
|
||||
// During the removal the binary heap is maintained.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::remove_from_olist() {
|
||||
// Variables for maintaining the binary heap.
|
||||
AINode *child_node, *child_node_1, *child_node_2;
|
||||
Node *child_node, *child_node_1, *child_node_2;
|
||||
int child_idx, child_idx_1, child_idx_2;
|
||||
|
||||
// Remove the AINode at index 1 from the open list binary heap.
|
||||
// Note: AINode at index 0 of open list is a dummy node.
|
||||
// Remove the Node at index 1 from the open list binary heap.
|
||||
// Note: Node at index 0 of open list is a dummy node.
|
||||
_open_list.erase(_open_list.begin() + 1);
|
||||
|
||||
if (_open_list.size() > 1) {
|
||||
if(_open_list.size() > 1) {
|
||||
// Store the last element in the open list to a temp_node.
|
||||
AINode *temp_node = _open_list[_open_list.size() - 1];
|
||||
Node *temp_node = _open_list[_open_list.size() - 1];
|
||||
|
||||
// Shift the elements of the open list to the right by 1 element
|
||||
// circularly, excluding element at 0 index.
|
||||
for (int i = _open_list.size() - 1; i > 1; --i) {
|
||||
// Shift the elements of the open list to the right by 1 element circularly, excluding element at 0 index.
|
||||
for(int i = _open_list.size() - 1; i > 1; --i) {
|
||||
_open_list[i] = _open_list[i - 1];
|
||||
}
|
||||
|
||||
// Assign the temp_node to 1st element in the open list.
|
||||
_open_list[1] = temp_node;
|
||||
|
||||
// Set the iterator for traversing the node from index 1 in
|
||||
// the heap.
|
||||
// Set the iterator for traversing the node from index 1 in the heap.
|
||||
unsigned int k = 1;
|
||||
|
||||
// This loop traverses down the open list till the node reaches
|
||||
// the correct position in the binary heap.
|
||||
while (true) {
|
||||
if ((k * 2 + 1) < _open_list.size()) {
|
||||
// This loop traverses down the open list till the node reaches the correct position in the binary heap.
|
||||
while(true) {
|
||||
if((k * 2 + 1) < _open_list.size()) {
|
||||
// Two children exists for the parent node.
|
||||
child_idx_1 = k * 2;
|
||||
child_idx_2 = k * 2 + 1;
|
||||
child_node_1 = _open_list[child_idx_1];
|
||||
child_node_2 = _open_list[child_idx_2];
|
||||
|
||||
if (_open_list[child_idx_1]->_score < _open_list[child_idx_2]->_score) {
|
||||
if (_open_list[k]->_score > _open_list[child_idx_1]->_score) {
|
||||
if(_open_list[child_idx_1]->_score < _open_list[child_idx_2]->_score) {
|
||||
if(_open_list[k]->_score > _open_list[child_idx_1]->_score) {
|
||||
// Swap the parent node and the child node.
|
||||
_open_list[child_idx_1] = _open_list[k];
|
||||
_open_list[k] = child_node_1;
|
||||
@ -289,7 +300,7 @@ void PathFinder::remove_from_olist() {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (_open_list[k]->_score > _open_list[child_idx_2]->_score) {
|
||||
if(_open_list[k]->_score > _open_list[child_idx_2]->_score) {
|
||||
// Swap the parent node and the child node.
|
||||
_open_list[child_idx_2] = _open_list[k];
|
||||
_open_list[k] = child_node_2;
|
||||
@ -302,12 +313,12 @@ void PathFinder::remove_from_olist() {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((k * 2) < _open_list.size()) {
|
||||
else if((k * 2) < _open_list.size()) {
|
||||
// Only one child exists for the parent node.
|
||||
child_idx = k * 2;
|
||||
child_node = _open_list[child_idx];
|
||||
|
||||
if (_open_list[k]->_score > _open_list[child_idx]->_score) {
|
||||
if(_open_list[k]->_score > _open_list[child_idx]->_score) {
|
||||
// Swap the parent node and the child node.
|
||||
_open_list[child_idx] = _open_list[k];
|
||||
_open_list[k] = child_node;
|
||||
@ -326,50 +337,57 @@ void PathFinder::remove_from_olist() {
|
||||
}
|
||||
}
|
||||
|
||||
// At this point the AINode was successfully removed and the binary
|
||||
// heap re-arranged.
|
||||
// At this point the Node was succesfully removed and the binary heap re-arranged.
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_to_clist
|
||||
// Description: This function adds a node to the closed list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFinder::add_to_clist(AINode *nd) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_to_clist
|
||||
// Description : This function adds a node to the closed list.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::add_to_clist(Node *nd) {
|
||||
// Set the status as closed.
|
||||
nd->_status = nd->ST_close;
|
||||
nd->_status = nd->close;
|
||||
// Add the node to the close list.
|
||||
_closed_list.push_back(nd);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: remove_from_clist
|
||||
// Description: This function removes a node from the closed list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : remove_from_clist
|
||||
// Description : This function removes a node from the closed list.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFinder::remove_from_clist(int r, int c) {
|
||||
for (unsigned int i = 0; i < _closed_list.size(); ++i) {
|
||||
if (_closed_list[i]->_grid_x == r && _closed_list[i]->_grid_y == c) {
|
||||
for(unsigned int i = 0; i < _closed_list.size(); ++i) {
|
||||
if(_closed_list[i]->_grid_x == r && _closed_list[i]->_grid_y == c) {
|
||||
_closed_list.erase(_closed_list.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: find_in_mesh
|
||||
// Description: This function allows the user to pass a position
|
||||
// and it returns the corresponding node on the
|
||||
// navigation mesh. A very useful function as it allows
|
||||
// for dynamic updation of the mesh based on position.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
AINode* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size) {
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : find_in_mesh
|
||||
// Description : This function allows the user to pass a position and it returns the
|
||||
// corresponding node on the navigation mesh. A very useful function as
|
||||
// it allows for dynamic updation of the mesh based on position.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Node* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size) {
|
||||
int size = grid_size;
|
||||
float x = pos[0];
|
||||
float y = pos[1];
|
||||
|
||||
for (int i = 0; i < size; ++i) {
|
||||
for (int j = 0; j < size; ++j) {
|
||||
if (nav_mesh[i][j] != NULL && nav_mesh[i][j]->contains(x, y)) {
|
||||
return (nav_mesh[i][j]);
|
||||
for(int i = 0; i < size; ++i) {
|
||||
for(int j = 0; j < size; ++j) {
|
||||
if(nav_mesh[i][j] != NULL && nav_mesh[i][j]->contains(x, y)) {
|
||||
return(nav_mesh[i][j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,61 +1,64 @@
|
||||
// Filename: aiPathfinder.h
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiPathFinder.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 10 Nov 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license along
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PATHFINDER_H
|
||||
#define PATHFINDER_H
|
||||
#ifndef _PATHFINDER_H
|
||||
#define _PATHFINDER_H
|
||||
|
||||
#include "aiNode.h"
|
||||
#include "meshNode.h"
|
||||
#include "cmath.h"
|
||||
#include "lineSegs.h"
|
||||
|
||||
typedef vector<AINode *> NodeArray;
|
||||
typedef vector<Node *> NodeArray;
|
||||
typedef vector<NodeArray> NavMesh;
|
||||
|
||||
AINode* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size);
|
||||
Node* find_in_mesh(NavMesh nav_mesh, LVecBase3f pos, int grid_size);
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PathFinder
|
||||
// Description : This class implements pathfinding using the A*
|
||||
// algorithm. It also uses a Binary Heap search to
|
||||
// search the open list. The heuristics are
|
||||
// calculated using the manhattan method.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class PathFinder {
|
||||
PUBLISHED:
|
||||
AINode *_src_node;
|
||||
AINode *_dest_node;
|
||||
vector<AINode*> _open_list;
|
||||
vector<AINode*> _closed_list;
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : PathFinder
|
||||
// Description : This class implements pathfinding using A* algorithm. It also uses a Binary Heap search to
|
||||
// search the open list. The heuristics are calculated using the manhattan method.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDAAI PathFinder {
|
||||
public:
|
||||
Node *_src_node;
|
||||
Node *_dest_node;
|
||||
vector<Node*> _open_list;
|
||||
vector<Node*> _closed_list;
|
||||
|
||||
NavMesh _grid;
|
||||
|
||||
void identify_neighbors(AINode *nd);
|
||||
int calc_cost_frm_src(AINode *nd);
|
||||
int calc_heuristic(AINode *nd);
|
||||
void calc_node_score(AINode *nd);
|
||||
bool is_diagonal_node(AINode *nd);
|
||||
void identify_neighbors(Node *nd);
|
||||
int calc_cost_frm_src(Node *nd);
|
||||
int calc_heuristic(Node *nd);
|
||||
void calc_node_score(Node *nd);
|
||||
bool is_diagonal_node(Node *nd);
|
||||
|
||||
void add_to_olist(AINode *nd);
|
||||
void add_to_olist(Node *nd);
|
||||
void remove_from_olist();
|
||||
|
||||
void add_to_clist(AINode *nd);
|
||||
void add_to_clist(Node *nd);
|
||||
void remove_from_clist(int r, int c);
|
||||
|
||||
void generate_path();
|
||||
void find_path(AINode *src_node, AINode *dest_node);
|
||||
void find_path(Node *src_node, Node *dest_node);
|
||||
PathFinder(NavMesh nav_mesh);
|
||||
~PathFinder();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: aiWorld.cxx
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiWorld.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 8 Sep 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -36,11 +37,11 @@ void AIWorld::remove_ai_char(string name) {
|
||||
void AIWorld::remove_ai_char_from_flock(string name) {
|
||||
AICharPool::node *ai_pool;
|
||||
ai_pool = _ai_char_pool->_head;
|
||||
while ((ai_pool) != NULL) {
|
||||
for (unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if (ai_pool->_ai_char->_ai_char_flock_id == _flock_pool[i]->get_id()) {
|
||||
for (unsigned int j = 0; j<_flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
if (_flock_pool[i]->_ai_char_list[j]->_name == name) {
|
||||
while((ai_pool) != NULL) {
|
||||
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if(ai_pool->_ai_char->_ai_char_flock_id == _flock_pool[i]->get_id()) {
|
||||
for(unsigned int j = 0; j<_flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
if(_flock_pool[i]->_ai_char_list[j]->_name == name) {
|
||||
_flock_pool[i]->_ai_char_list.erase(_flock_pool[i]->_ai_char_list.begin() + j);
|
||||
return;
|
||||
}
|
||||
@ -55,47 +56,51 @@ void AIWorld::print_list() {
|
||||
_ai_char_pool->print_list();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: update
|
||||
// Description: The AIWorld update function calls the update
|
||||
// function of all the AI characters which have been
|
||||
// added to the AIWorld.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Function : update
|
||||
// Description : The AIWorld update function calls the update function of all the
|
||||
// AI characters which have been added to the AIWorld.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::update() {
|
||||
AICharPool::node *ai_pool;
|
||||
ai_pool = _ai_char_pool->_head;
|
||||
|
||||
while ((ai_pool)!=NULL) {
|
||||
while((ai_pool)!=NULL) {
|
||||
ai_pool->_ai_char->update();
|
||||
ai_pool = ai_pool->_next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_flock
|
||||
// Description: This function adds all the AI characters in the
|
||||
// Flock object to the AICharPool. This function
|
||||
// allows adding the AI characetrs as part of a flock.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_flock
|
||||
// Description : This function adds all the AI characters in the Flock object to
|
||||
// the AICharPool. This function allows adding the AI characetrs as
|
||||
// part of a flock.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::add_flock(Flock *flock) {
|
||||
// Add all the ai_characters in the flock to the AIWorld.
|
||||
for (unsigned int i = 0; i < flock->_ai_char_list.size(); ++i) {
|
||||
for(unsigned int i = 0; i < flock->_ai_char_list.size(); ++i) {
|
||||
this->add_ai_char(flock->_ai_char_list[i]);
|
||||
}
|
||||
// Add the flock to the flock pool.
|
||||
_flock_pool.push_back(flock);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function: get_flock
|
||||
// Description: This function returns a handle to the Flock whose
|
||||
// id is passed.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function : get_flock
|
||||
// Description : This function returns a handle to the Flock whose id is passed.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Flock AIWorld::get_flock(unsigned int flock_id) {
|
||||
for (unsigned int i=0; i < _flock_pool.size(); ++i) {
|
||||
if (_flock_pool[i]->get_id() == flock_id) {
|
||||
for(unsigned int i=0; i < _flock_pool.size(); ++i) {
|
||||
if(_flock_pool[i]->get_id() == flock_id) {
|
||||
return *_flock_pool[i];
|
||||
}
|
||||
}
|
||||
@ -103,52 +108,61 @@ Flock AIWorld::get_flock(unsigned int flock_id) {
|
||||
return *null_flock;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: remove_flock
|
||||
// Description: This function removes the flock behavior completely.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AIWorld::remove_flock(unsigned int flock_id) {
|
||||
for (unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if (_flock_pool[i]->get_id() == flock_id) {
|
||||
for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate");
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock");
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->_flock_group = NULL;
|
||||
}
|
||||
_flock_pool.erase(_flock_pool.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : remove_flock
|
||||
// Description : This function removes the flock behavior completely.
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flock_off
|
||||
// Description: This function turns off the flock behavior
|
||||
// temporarily. Similar to pausing the behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void AIWorld::flock_off(unsigned int flock_id) {
|
||||
for (unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if (_flock_pool[i]->get_id() == flock_id) {
|
||||
for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::remove_flock(unsigned int flock_id) {
|
||||
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if(_flock_pool[i]->get_id() == flock_id) {
|
||||
for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate");
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock");
|
||||
}
|
||||
break;
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->_flock_group = NULL;
|
||||
}
|
||||
_flock_pool.erase(_flock_pool.begin() + i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flock_on
|
||||
// Description: This function turns on the flock behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : flock_off
|
||||
// Description : This function turns off the flock behavior temporarily. Similar to
|
||||
// pausing the behavior.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::flock_off(unsigned int flock_id) {
|
||||
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if(_flock_pool[i]->get_id() == flock_id) {
|
||||
for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock_activate");
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_off("flock");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : flock_on
|
||||
// Description : This function turns on the flock behavior.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::flock_on(unsigned int flock_id) {
|
||||
for (unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if (_flock_pool[i]->get_id() == flock_id) {
|
||||
for (unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_on("flock_activate");
|
||||
}
|
||||
break;
|
||||
for(unsigned int i = 0; i < _flock_pool.size(); ++i) {
|
||||
if(_flock_pool[i]->get_id() == flock_id) {
|
||||
for(unsigned int j = 0; j < _flock_pool[i]->_ai_char_list.size(); ++j) {
|
||||
_flock_pool[i]->_ai_char_list[j]->get_ai_behaviors()->turn_on("flock_activate");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -164,7 +178,7 @@ void AICharPool::append(AICharacter *ai_ch) {
|
||||
node *q;
|
||||
node *t;
|
||||
|
||||
if (_head == NULL) {
|
||||
if(_head == NULL) {
|
||||
q = new node();
|
||||
q->_ai_char = ai_ch;
|
||||
q->_next = NULL;
|
||||
@ -172,7 +186,7 @@ void AICharPool::append(AICharacter *ai_ch) {
|
||||
}
|
||||
else {
|
||||
q = _head;
|
||||
while ( q->_next != NULL) {
|
||||
while( q->_next != NULL) {
|
||||
q = q->_next;
|
||||
}
|
||||
|
||||
@ -188,13 +202,13 @@ void AICharPool::del(string name) {
|
||||
node *r;
|
||||
q = _head;
|
||||
|
||||
if (_head == NULL) {
|
||||
if(_head==NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Only one node in the linked list
|
||||
if (q->_next == NULL) {
|
||||
if (q->_ai_char->_name == name) {
|
||||
if(q->_next == NULL) {
|
||||
if(q->_ai_char->_name == name) {
|
||||
_head = NULL;
|
||||
delete q;
|
||||
}
|
||||
@ -202,10 +216,10 @@ void AICharPool::del(string name) {
|
||||
}
|
||||
|
||||
r = q;
|
||||
while ( q != NULL) {
|
||||
if ( q->_ai_char->_name == name) {
|
||||
while( q != NULL) {
|
||||
if( q->_ai_char->_name == name) {
|
||||
// Special case
|
||||
if (q == _head) {
|
||||
if(q == _head) {
|
||||
_head = q->_next;
|
||||
delete q;
|
||||
return;
|
||||
@ -220,38 +234,46 @@ void AICharPool::del(string name) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: print_list
|
||||
// Description: This function prints the ai characters in the
|
||||
// AICharPool. Used for debugging purposes.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : print_list
|
||||
// Description : This function prints the ai characters in the AICharPool. Used for
|
||||
// debugging purposes.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AICharPool::print_list() {
|
||||
node* q;
|
||||
q = _head;
|
||||
while (q != NULL) {
|
||||
cout << q->_ai_char->_name << "\n";
|
||||
while(q != NULL) {
|
||||
cout<<q->_ai_char->_name<<endl;
|
||||
q = q->_next;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_obstacle
|
||||
// Description: This function adds the nodepath as an obstacle that
|
||||
// is needed by the obstacle avoidance behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_obstacle
|
||||
// Description : This function adds the nodepath as an obstacle that is needed
|
||||
// by the obstacle avoidance behavior.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::add_obstacle(NodePath obstacle) {
|
||||
_obstacles.push_back(obstacle);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: remove_obstacle
|
||||
// Description: This function removes the nodepath from the
|
||||
// obstacles list that is needed by the obstacle
|
||||
// avoidance behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : remove_obstacle
|
||||
// Description : This function removes the nodepath from the obstacles list that is needed
|
||||
// by the obstacle avoidance behavior.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void AIWorld::remove_obstacle(NodePath obstacle) {
|
||||
for (unsigned int i = 0; i <= _obstacles.size(); ++i) {
|
||||
if (_obstacles[i] == obstacle) {
|
||||
for(unsigned int i = 0; i <= _obstacles.size(); ++i) {
|
||||
if(_obstacles[i] == obstacle) {
|
||||
_obstacles.erase(_obstacles.begin() + i);
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,25 @@
|
||||
// Filename: aiWorld.h
|
||||
// Created by: Deepak, John, Navin (08Sep09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : aiWorld.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 8 Sep 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license along
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef AIWORLD_H
|
||||
#define AIWORLD_H
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning(disable:4275)
|
||||
|
||||
|
||||
#ifndef _AIWORLD_H
|
||||
#define _AIWORLD_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
@ -22,66 +28,81 @@
|
||||
class AICharacter;
|
||||
class Flock;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AICharPool
|
||||
// Description : This class implements a linked list of AI
|
||||
// Characters allowing the user to add and delete
|
||||
// characters from the linked list.
|
||||
// This will be used in the AIWorld class.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class AICharPool {
|
||||
public:
|
||||
struct node {
|
||||
AICharacter * _ai_char;
|
||||
node * _next;
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : AICharPool
|
||||
// Description : This class implements a linked list of AI Characters allowing
|
||||
// the user to add and delete characters from the linked list.
|
||||
// This will be used in the AIWorld class.
|
||||
|
||||
node* _head;
|
||||
AICharPool();
|
||||
~AICharPool();
|
||||
void append(AICharacter *ai_ch);
|
||||
void del(string name);
|
||||
void print_list();
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class EXPCL_PANDAAI AICharPool {
|
||||
public:
|
||||
struct node {
|
||||
AICharacter * _ai_char;
|
||||
node * _next;
|
||||
} ;
|
||||
|
||||
node* _head;
|
||||
AICharPool();
|
||||
~AICharPool();
|
||||
void append(AICharacter *ai_ch);
|
||||
void del(string name);
|
||||
void print_list();
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : AIWorld
|
||||
// Description : A class that implements the virtual AI world which
|
||||
// keeps track of the AI characters active at any
|
||||
// given time. It contains a linked list of AI
|
||||
// characters, obstactle data and unique name for each
|
||||
// character. It also updates each characters state.
|
||||
// The AI characters can also be added to the world
|
||||
// as flocks.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class AIWorld {
|
||||
private:
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : AIWorld
|
||||
// Description : A class that implements the virtual AI world which keeps track
|
||||
// of the AI characters active at any given time. It contains a linked
|
||||
// list of AI characters, obstactle data and unique name for each
|
||||
// character. It also updates each characters state. The AI characters
|
||||
// can also be added to the world as flocks.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
class EXPCL_PANDAAI AIWorld {
|
||||
private:
|
||||
AICharPool * _ai_char_pool;
|
||||
NodePath _render;
|
||||
public:
|
||||
vector<NodePath> _obstacles;
|
||||
typedef std::vector<Flock*> FlockPool;
|
||||
FlockPool _flock_pool;
|
||||
void remove_ai_char_from_flock(string name);
|
||||
public:
|
||||
vector<NodePath> _obstacles;
|
||||
typedef std::vector<Flock*> FlockPool;
|
||||
FlockPool _flock_pool;
|
||||
void remove_ai_char_from_flock(string name);
|
||||
|
||||
PUBLISHED:
|
||||
AIWorld(NodePath render);
|
||||
~AIWorld();
|
||||
AIWorld(NodePath render);
|
||||
~AIWorld();
|
||||
|
||||
void add_ai_char(AICharacter *ai_ch);
|
||||
void remove_ai_char(string name);
|
||||
void add_ai_char(AICharacter *ai_ch);
|
||||
void remove_ai_char(string name);
|
||||
|
||||
void add_flock(Flock *flock);
|
||||
void flock_off(unsigned int flock_id);
|
||||
void flock_on(unsigned int flock_id);
|
||||
void remove_flock(unsigned int flock_id);
|
||||
Flock get_flock(unsigned int flock_id);
|
||||
void add_flock(Flock *flock);
|
||||
void flock_off(unsigned int flock_id);
|
||||
void flock_on(unsigned int flock_id);
|
||||
void remove_flock(unsigned int flock_id);
|
||||
Flock get_flock(unsigned int flock_id);
|
||||
|
||||
void add_obstacle(NodePath obstacle);
|
||||
void remove_obstacle(NodePath obstacle);
|
||||
void add_obstacle(NodePath obstacle);
|
||||
void remove_obstacle(NodePath obstacle);
|
||||
|
||||
void print_list();
|
||||
void update();
|
||||
void print_list();
|
||||
void update();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -18,3 +18,4 @@
|
||||
#include "aiNode.cxx"
|
||||
|
||||
#include "aiPathFinder.cxx"
|
||||
#include "meshNode.cxx"
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: arrival.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : arrival.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -24,42 +25,42 @@ Arrival::Arrival(AICharacter *ai_ch, double distance) {
|
||||
Arrival::~Arrival() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_arrival
|
||||
// Description: This function performs the arrival and returns an
|
||||
// arrival force which is used in the
|
||||
// calculate_prioritized function. In case the steering
|
||||
// force is zero, it resets to arrival_activate. The
|
||||
// arrival behavior works only when seek or pursue is
|
||||
// active. This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_arrival
|
||||
// Description : This function performs the arrival and returns an arrival force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// In case the steering force = 0, it resets to arrival_activate.
|
||||
// The arrival behavior works only when seek or pursue is active.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Arrival::do_arrival() {
|
||||
LVecBase3f direction_to_target;
|
||||
double distance;
|
||||
|
||||
if (_arrival_type) {
|
||||
direction_to_target = _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render)
|
||||
- _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
if(_arrival_type) {
|
||||
direction_to_target = _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render) - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
}
|
||||
else {
|
||||
direction_to_target = _ai_char->get_ai_behaviors()->_seek_obj->_seek_position
|
||||
- _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
direction_to_target = _ai_char->get_ai_behaviors()->_seek_obj->_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
}
|
||||
distance = direction_to_target.length();
|
||||
|
||||
_arrival_direction = direction_to_target;
|
||||
_arrival_direction.normalize();
|
||||
|
||||
if (int(distance) == 0) {
|
||||
if(int(distance) == 0) {
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
_ai_char->_steering->_arrival_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
|
||||
if (_ai_char->_steering->_seek_obj != NULL) {
|
||||
if(_ai_char->_steering->_seek_obj != NULL) {
|
||||
_ai_char->_steering->turn_off("arrival");
|
||||
_ai_char->_steering->turn_on("arrival_activate");
|
||||
}
|
||||
_arrival_done = true;
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
_arrival_done = false;
|
||||
@ -68,36 +69,37 @@ LVecBase3f Arrival::do_arrival() {
|
||||
double u = _ai_char->get_velocity().length();
|
||||
LVecBase3f desired_force = ((u * u) / (2 * distance)) * _ai_char->get_mass();
|
||||
|
||||
if (_ai_char->_steering->_seek_obj != NULL) {
|
||||
return (desired_force);
|
||||
if(_ai_char->_steering->_seek_obj != NULL) {
|
||||
return(desired_force);
|
||||
}
|
||||
|
||||
if (_ai_char->_steering->_pursue_obj != NULL) {
|
||||
if(_ai_char->_steering->_pursue_obj != NULL) {
|
||||
|
||||
if (distance > _arrival_distance) {
|
||||
if(distance > _arrival_distance) {
|
||||
_ai_char->_steering->turn_off("arrival");
|
||||
_ai_char->_steering->turn_on("arrival_activate");
|
||||
_ai_char->_steering->resume_ai("pursue");
|
||||
}
|
||||
|
||||
return (desired_force);
|
||||
return(desired_force);
|
||||
}
|
||||
|
||||
cout << "Arrival works only with seek and pursue\n";
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
cout<<"Arrival works only with seek and pursue"<<endl;
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: arrival_activate
|
||||
// Description: This function checks for whether the target is
|
||||
// within the arrival distance. When this is true,
|
||||
// it calls the do_arrival function and sets the
|
||||
// arrival direction.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : arrival_activate
|
||||
// Description : This function checks for whether the target is within the arrival distance.
|
||||
// When this is true, it calls the do_arrival function and sets the arrival direction.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Arrival::arrival_activate() {
|
||||
LVecBase3f dirn;
|
||||
if (_arrival_type) {
|
||||
if(_arrival_type) {
|
||||
dirn = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _ai_char->get_ai_behaviors()->_pursue_obj->_pursue_target.get_pos(_ai_char->_window_render));
|
||||
}
|
||||
else {
|
||||
@ -105,15 +107,15 @@ void Arrival::arrival_activate() {
|
||||
}
|
||||
double distance = dirn.length();
|
||||
|
||||
if (distance < _arrival_distance && _ai_char->_steering->_steering_force.length() > 0) {
|
||||
if(distance < _arrival_distance && _ai_char->_steering->_steering_force.length() > 0) {
|
||||
_ai_char->_steering->turn_off("arrival_activate");
|
||||
_ai_char->_steering->turn_on("arrival");
|
||||
|
||||
if (_ai_char->_steering->is_on(_ai_char->_steering->BT_seek)) {
|
||||
if(_ai_char->_steering->is_on(_ai_char->_steering->_seek)) {
|
||||
_ai_char->_steering->turn_off("seek");
|
||||
}
|
||||
|
||||
if (_ai_char->_steering->is_on(_ai_char->_steering->BT_pursue)) {
|
||||
if(_ai_char->_steering->is_on(_ai_char->_steering->_pursue)) {
|
||||
_ai_char->_steering->pause_ai("pursue");
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,27 @@
|
||||
// Filename: arrival.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : arrival.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef ARRIVAL_H
|
||||
#define ARRIVAL_H
|
||||
|
||||
#ifndef _ARRIVAL_H
|
||||
#define _ARRIVAL_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Arrival
|
||||
// Description : This class handles all calls to the arrival behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Arrival {
|
||||
class EXPCL_PANDAAI Arrival {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
@ -34,8 +32,7 @@ public:
|
||||
LVecBase3f _arrival_direction;
|
||||
bool _arrival_done;
|
||||
|
||||
// This flag specifies if the arrival behavior is being used with
|
||||
// seek or pursue behavior.
|
||||
// This flag specifies if the arrival behavior is being used with seek or pursue behavior.
|
||||
// True = used with pursue.
|
||||
// False = used with seek.
|
||||
bool _arrival_type;
|
||||
|
@ -1,22 +1,22 @@
|
||||
// Filename: evade.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : evade.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "evade.h"
|
||||
|
||||
Evade::
|
||||
Evade(AICharacter *ai_ch, NodePath target_object,
|
||||
double panic_distance, double relax_distance, float evade_wt) {
|
||||
Evade::Evade(AICharacter *ai_ch, NodePath target_object, double panic_distance,
|
||||
double relax_distance, float evade_wt) {
|
||||
_ai_char = ai_ch;
|
||||
|
||||
_evade_target = target_object;
|
||||
@ -31,56 +31,58 @@ Evade(AICharacter *ai_ch, NodePath target_object,
|
||||
Evade::~Evade() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_evade
|
||||
// Description: This function performs the evade and returns an
|
||||
// evade force which is used in the
|
||||
// calculate_prioritized function. In case the
|
||||
// AICharacter is past the (panic + relax) distance,
|
||||
// it resets to evade_activate. This function is not
|
||||
// to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_evade
|
||||
// Description : This function performs the evade and returns an evade force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// In case the AICharacter is past the (panic + relax) distance,
|
||||
// it resets to evade_activate.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Evade::do_evade() {
|
||||
assert(_evade_target && "evade target not assigned");
|
||||
|
||||
_evade_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)
|
||||
- _evade_target.get_pos(_ai_char->_window_render);
|
||||
_evade_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render);
|
||||
double distance = _evade_direction.length();
|
||||
|
||||
_evade_direction.normalize();
|
||||
LVecBase3f desired_force = _evade_direction * _ai_char->_movt_force;
|
||||
|
||||
if (distance > (_evade_distance + _evade_relax_distance)) {
|
||||
if ((_ai_char->_steering->_behaviors_flags |
|
||||
_ai_char->_steering->BT_evade) == _ai_char->_steering->BT_evade) {
|
||||
if(distance > (_evade_distance + _evade_relax_distance)) {
|
||||
if((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->_evade) == _ai_char->_steering->_evade) {
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
}
|
||||
_ai_char->_steering->turn_off("evade");
|
||||
_ai_char->_steering->turn_on("evade_activate");
|
||||
_evade_done = true;
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
} else {
|
||||
_evade_done = false;
|
||||
return (desired_force);
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
_evade_done = false;
|
||||
return(desired_force);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: evade_activate
|
||||
// Description: This function checks for whether the target is
|
||||
// within the panic distance.
|
||||
// When this is true, it calls the do_evade function
|
||||
// and sets the evade direction.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : evade_activate
|
||||
// Description : This function checks for whether the target is within the panic distance.
|
||||
// When this is true, it calls the do_evade function and sets the evade direction.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Evade::evade_activate() {
|
||||
_evade_direction = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render));
|
||||
_evade_direction = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _evade_target.get_pos(_ai_char->_window_render));
|
||||
double distance = _evade_direction.length();
|
||||
_evade_activate_done = false;
|
||||
|
||||
if (distance < _evade_distance) {
|
||||
_ai_char->_steering->turn_off("evade_activate");
|
||||
_ai_char->_steering->turn_on("evade");
|
||||
_evade_activate_done = true;
|
||||
if(distance < _evade_distance) {
|
||||
_ai_char->_steering->turn_off("evade_activate");
|
||||
_ai_char->_steering->turn_on("evade");
|
||||
_evade_activate_done = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,27 @@
|
||||
// Filename: evade.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : evade.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef EVADE_H
|
||||
#define EVADE_H
|
||||
#ifndef _EVADE_H
|
||||
#define _EVADE_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Evade
|
||||
// Description : This class handles all calls to the evade behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Evade {
|
||||
class EXPCL_PANDAAI Evade {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: flee.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : flee.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -31,7 +32,7 @@ Flee::Flee(AICharacter *ai_ch, NodePath target_object, double panic_distance,
|
||||
Flee::Flee(AICharacter *ai_ch, LVecBase3f pos, double panic_distance,
|
||||
double relax_distance, float flee_wt){
|
||||
|
||||
_ai_char = ai_ch;
|
||||
_ai_char = ai_ch;
|
||||
|
||||
_flee_position = pos;
|
||||
_flee_distance = panic_distance;
|
||||
@ -45,14 +46,17 @@ Flee::Flee(AICharacter *ai_ch, LVecBase3f pos, double panic_distance,
|
||||
Flee::~Flee() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_flee
|
||||
// Description: This function performs the flee and returns a flee
|
||||
// force which is used in the calculate_prioritized
|
||||
// function. In case the AICharacter is past the
|
||||
// (panic + relax) distance, it resets to flee_activate.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_flee
|
||||
// Description : This function performs the flee and returns a flee force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// In case the AICharacter is past the (panic + relax) distance,
|
||||
// it resets to flee_activate.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Flee::do_flee() {
|
||||
LVecBase3f dirn;
|
||||
double distance;
|
||||
@ -62,28 +66,29 @@ LVecBase3f Flee::do_flee() {
|
||||
distance = dirn.length();
|
||||
desired_force = _flee_direction * _ai_char->_movt_force;
|
||||
|
||||
if (distance > (_flee_distance + _flee_relax_distance)) {
|
||||
if ((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->BT_flee) == _ai_char->_steering->BT_flee) {
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
if(distance > (_flee_distance + _flee_relax_distance)) {
|
||||
if((_ai_char->_steering->_behaviors_flags | _ai_char->_steering->_flee) == _ai_char->_steering->_flee) {
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
}
|
||||
_flee_done = true;
|
||||
_ai_char->_steering->turn_off("flee");
|
||||
_ai_char->_steering->turn_on("flee_activate");
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
return (desired_force);
|
||||
return(desired_force);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: flee_activate
|
||||
// Description: This function checks for whether the target is
|
||||
// within the panic distance. When this is true,
|
||||
// it calls the do_flee function and sets the flee
|
||||
// direction.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : flee_activate
|
||||
// Description : This function checks for whether the target is within the panic distance.
|
||||
// When this is true, it calls the do_flee function and sets the flee direction.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Flee::flee_activate() {
|
||||
LVecBase3f dirn;
|
||||
double distance;
|
||||
@ -93,12 +98,12 @@ void Flee::flee_activate() {
|
||||
dirn = (_ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position);
|
||||
distance = dirn.length();
|
||||
|
||||
if (distance < _flee_distance) {
|
||||
_flee_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position;
|
||||
_flee_direction.normalize();
|
||||
_flee_present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_ai_char->_steering->turn_off("flee_activate");
|
||||
_ai_char->_steering->turn_on("flee");
|
||||
_flee_activate_done = true;
|
||||
if(distance < _flee_distance) {
|
||||
_flee_direction = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render) - _flee_position;
|
||||
_flee_direction.normalize();
|
||||
_flee_present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_ai_char->_steering->turn_off("flee_activate");
|
||||
_ai_char->_steering->turn_on("flee");
|
||||
_flee_activate_done = true;
|
||||
}
|
||||
}
|
||||
|
@ -1,30 +1,27 @@
|
||||
// Filename: flee.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : flee.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FLEE_H
|
||||
#define FLEE_H
|
||||
#ifndef _FLEE_H
|
||||
#define _FLEE_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Flee
|
||||
// Description : This class handles all calls to the flee behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Flee {
|
||||
class EXPCL_PANDAAI Flee {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Filename: flock.cxx
|
||||
// Created by: Deepak, John, Navin (12Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : flock.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 12 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
@ -27,10 +28,13 @@ Flock::Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, uns
|
||||
Flock::~Flock() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_ai_char
|
||||
// Description: This function adds AI characters to the flock.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_ai_char
|
||||
// Description : This function adds AI characters to the flock.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Flock::add_ai_char(AICharacter *ai_char) {
|
||||
ai_char->_ai_char_flock_id = _flock_id;
|
||||
ai_char->_steering->_flock_group = this;
|
||||
|
@ -1,55 +1,56 @@
|
||||
// Filename: flock.h
|
||||
// Created by: Deepak, John, Navin (12Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : flock.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 12 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef FLOCK_H
|
||||
#define FLOCK_H
|
||||
#ifndef _FLOCK_H
|
||||
#define _FLOCK_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Flock
|
||||
// Description : This class is used to define the flock attributes
|
||||
// and the AI characters which are part of the flock.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Flock {
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : Flock
|
||||
// Description : This class is used to define the flock attributes and the AI characters
|
||||
// which are part of the flock.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDAAI Flock {
|
||||
private:
|
||||
unsigned int _flock_id;
|
||||
|
||||
public:
|
||||
// Variables which will hold the parameters of the ai character's
|
||||
// visibility cone.
|
||||
// Variables which will hold the parameters of the ai character's visibilty cone.
|
||||
double _flock_vcone_angle;
|
||||
double _flock_vcone_radius;
|
||||
|
||||
// Variables to specify weights of separation, cohesion and
|
||||
// alignment behaviors and thus create variable flock behavior.
|
||||
// Variables to specify weights of separation, cohesion and alignment behaviors and thus
|
||||
// create variable flock behavior.
|
||||
unsigned int _separation_wt;
|
||||
unsigned int _cohesion_wt;
|
||||
unsigned int _alignment_wt;
|
||||
|
||||
// This vector will hold all the ai characters which belong to
|
||||
// this flock.
|
||||
// This vector will hold all the ai characters which belong to this flock.
|
||||
typedef std::vector<AICharacter*> AICharList;
|
||||
AICharList _ai_char_list;
|
||||
|
||||
PUBLISHED:
|
||||
Flock(unsigned int flock_id, double vcone_angle, double vcone_radius,
|
||||
unsigned int separation_wt = 2, unsigned int cohesion_wt = 4,
|
||||
unsigned int alignment_wt = 1);
|
||||
Flock(unsigned int flock_id, double vcone_angle, double vcone_radius, unsigned int separation_wt = 2,
|
||||
unsigned int cohesion_wt = 4, unsigned int alignment_wt = 1);
|
||||
~Flock();
|
||||
|
||||
// Function to add the ai characters to _ai_char_list.
|
||||
|
@ -1,32 +0,0 @@
|
||||
// Filename: globals.h
|
||||
// Created by: Deepak, John, Navin (26Apr10)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma warning (disable:4996)
|
||||
#pragma warning (disable:4005)
|
||||
#pragma warning (disable:4275)
|
||||
|
||||
#ifndef _GLOBALS_H
|
||||
#define _GLOBALS_H
|
||||
|
||||
#include "pandaFramework.h"
|
||||
#include "textNode.h"
|
||||
#include "pandaSystem.h"
|
||||
|
||||
#include "lvecBase3.h"
|
||||
#include "nodePath.h"
|
||||
|
||||
#include "genericAsyncTask.h"
|
||||
#include "asyncTaskManager.h"
|
||||
|
||||
#endif
|
@ -2,42 +2,42 @@
|
||||
#include "meshNode.h"
|
||||
|
||||
Node::Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h) {
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
_neighbours[i] = NULL;
|
||||
}
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
_neighbours[i] = NULL;
|
||||
}
|
||||
|
||||
_position = pos;
|
||||
_width = w;
|
||||
_length = l;
|
||||
_height = h;
|
||||
_grid_x = grid_x;
|
||||
_grid_y = grid_y;
|
||||
_position = pos;
|
||||
_width = w;
|
||||
_length = l;
|
||||
_height = h;
|
||||
_grid_x = grid_x;
|
||||
_grid_y = grid_y;
|
||||
_status = neutral;
|
||||
_type = true;
|
||||
_score = 0;
|
||||
_cost = 0;
|
||||
_heuristic = 0;
|
||||
_type = true;
|
||||
_score = 0;
|
||||
_cost = 0;
|
||||
_heuristic = 0;
|
||||
_next = NULL;
|
||||
_prv_node = NULL;
|
||||
_prv_node = NULL;
|
||||
}
|
||||
|
||||
Node::~Node() {
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//!
|
||||
//! Function : contains
|
||||
//! Description : This is a handy function which returns true if the passed position is
|
||||
//! within the node's dimensions.
|
||||
//
|
||||
// Function : contains
|
||||
// Description : This is a handy function which returns true if the passed position is
|
||||
// within the node's dimensions.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Node::contains(float x, float y) {
|
||||
if(_position.get_x() - _width / 2 <= x && _position.get_x() + _width / 2 >= x &&
|
||||
_position.get_y() - _length / 2 <= y && _position.get_y() + _length / 2 >= y) {
|
||||
return true;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
return false;
|
||||
}
|
||||
}
|
@ -2,66 +2,66 @@
|
||||
#ifndef _MESHNODE_H
|
||||
#define _MESHNODE_H
|
||||
|
||||
#include "globals.h"
|
||||
#include "aiGlobals.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Node
|
||||
// Description : This class is used to assign the nodes on the mesh.
|
||||
// It holds all the data necessary to compute A*
|
||||
// algorithm. It also maintains a lot of vital
|
||||
// information such as the neighbor nodes of each
|
||||
// node and also its position on the mesh.
|
||||
// Note: the Mesh Generator which is a stand alone
|
||||
// tool makes use of this class to generate the nodes
|
||||
// on the mesh.
|
||||
///////////////////////////////////////////////////////////////////
|
||||
class Node {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : Node
|
||||
// Description : This class is used to assign the nodes on the mesh. It holds all the data necessary to
|
||||
// compute A* algorithm. It also maintains a lot of vital information such as the neighbor
|
||||
// nodes of each node and also its position on the mesh.
|
||||
// Note: The Mesh Generator which is a stand alone tool makes use of this class to generate the nodes on the
|
||||
// mesh.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDAAI Node {
|
||||
public:
|
||||
// This variable specifies whether the node is an obtacle or not.
|
||||
// Used for dynamic obstacle addition to the environment.
|
||||
// obstacle = false
|
||||
// navigational = true
|
||||
bool _type;
|
||||
// This variable specifies whether the node is an obtacle or not.
|
||||
// Used for dynamic obstacle addition to the environment.
|
||||
// obstacle = false
|
||||
// navigational = true
|
||||
bool _type;
|
||||
|
||||
// This variable specifies the node status whether open, close or neutral.
|
||||
// open = belongs to _open_list.
|
||||
// close = belongs to _closed_list.
|
||||
// neutral = unexamined node.
|
||||
enum Status {
|
||||
open,
|
||||
close,
|
||||
neutral
|
||||
};
|
||||
Status _status;
|
||||
// This variable specifies the node status whether open, close or neutral.
|
||||
// open = belongs to _open_list.
|
||||
// close = belongs to _closed_list.
|
||||
// neutral = unexamined node.
|
||||
enum Status {
|
||||
open,
|
||||
close,
|
||||
neutral
|
||||
};
|
||||
Status _status;
|
||||
|
||||
// The score is used to compute the traversal expense to nodes when using A*.
|
||||
// _score = _cost + heuristic
|
||||
int _score;
|
||||
int _cost;
|
||||
int _heuristic;
|
||||
// The score is used to compute the traversal expense to nodes when using A*.
|
||||
// _score = _cost + heuristic
|
||||
int _score;
|
||||
int _cost;
|
||||
int _heuristic;
|
||||
|
||||
// Used to trace back the path after it is generated using A*.
|
||||
Node *_prv_node;
|
||||
// Used to trace back the path after it is generated using A*.
|
||||
Node *_prv_node;
|
||||
|
||||
// Position of the node in the 2d grid.
|
||||
int _grid_x, _grid_y;
|
||||
// Position of the node in the 2d grid.
|
||||
int _grid_x, _grid_y;
|
||||
|
||||
// Position of the node in 3D space.
|
||||
LVecBase3f _position;
|
||||
// Position of the node in 3D space.
|
||||
LVecBase3f _position;
|
||||
|
||||
// Dimensions of each face / cell on the mesh.
|
||||
// Height is given in case of expansion to a 3d mesh. Currently not used.
|
||||
float _width, _length ,_height;
|
||||
Node *_neighbours[8]; // anti-clockwise from top left corner.
|
||||
// Dimensions of each face / cell on the mesh.
|
||||
// Height is given in case of expansion to a 3d mesh. Currently not used.
|
||||
float _width, _length ,_height;
|
||||
Node *_neighbours[8]; // anti-clockwise from top left corner.
|
||||
|
||||
// The _next pointer is used for traversal during mesh generation from the model.
|
||||
// Note: The data in this member is discarded when mesh data is written into navmesh.csv file.
|
||||
Node *_next;
|
||||
// The _next pointer is used for traversal during mesh generation from the model.
|
||||
// Note: The data in this member is discarded when mesh data is written into navmesh.csv file.
|
||||
Node *_next;
|
||||
|
||||
Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h);
|
||||
~Node();
|
||||
Node(int grid_x, int grid_y, LVecBase3f pos, float w, float l, float h);
|
||||
~Node();
|
||||
|
||||
bool contains(float x, float y);
|
||||
bool contains(float x, float y);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: obstacleAvoidance.cxx
|
||||
// Created by: Deepak, John, Navin (10Nov09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : obstacleAvoidance.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 10 Nov 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -22,12 +23,14 @@ ObstacleAvoidance::ObstacleAvoidance(AICharacter *ai_char, float feeler_length)
|
||||
ObstacleAvoidance::~ObstacleAvoidance() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: obstacle_detection
|
||||
// Description: This function checks if an obstacle is near to the
|
||||
// AICharacter and if an obstacle is detected returns
|
||||
// true.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : obstacle_detection
|
||||
// Description : This function checks if an obstacle is near to the AICharacter and
|
||||
// if an obstacle is detected returns true
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool ObstacleAvoidance::obstacle_detection() {
|
||||
// Calculate the volume of the AICharacter with respect to render
|
||||
PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
|
||||
@ -37,15 +40,12 @@ bool ObstacleAvoidance::obstacle_detection() {
|
||||
double expanded_radius;
|
||||
LVecBase3f to_obstacle;
|
||||
LVecBase3f prev_avoidance;
|
||||
for (unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
|
||||
for(unsigned int i = 0; i < _ai_char->_world->_obstacles.size(); ++i) {
|
||||
PT(BoundingVolume) bounds = _ai_char->_world->_obstacles[i].get_bounds();
|
||||
CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
|
||||
LVecBase3f near_obstacle = _ai_char->_world->_obstacles[i].get_pos()
|
||||
- _ai_char->get_node_path().get_pos();
|
||||
// Check if it's the nearest obstacle, If so initialize as the nearest
|
||||
// obstacle
|
||||
if ((near_obstacle.length() < distance) &&
|
||||
(_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().get_pos())) {
|
||||
LVecBase3f near_obstacle = _ai_char->_world->_obstacles[i].get_pos() - _ai_char->get_node_path().get_pos();
|
||||
// Check if it's the nearest obstacle, If so initialize as the nearest obstacle
|
||||
if((near_obstacle.length() < distance) && (_ai_char->_world->_obstacles[i].get_pos() != _ai_char->get_node_path().get_pos())) {
|
||||
_nearest_obstacle = _ai_char->_world->_obstacles[i];
|
||||
distance = near_obstacle.length();
|
||||
expanded_radius = bsphere->get_radius() + np_sphere->get_radius();
|
||||
@ -58,59 +58,56 @@ bool ObstacleAvoidance::obstacle_detection() {
|
||||
LVector3f line_vector = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward());
|
||||
LVecBase3f project = (to_obstacle.dot(line_vector) * line_vector) / line_vector.length_squared();
|
||||
LVecBase3f perp = project - to_obstacle;
|
||||
// If the nearest obstacle will collide with our AICharacter then
|
||||
// send obstacle detection as true
|
||||
if ((_nearest_obstacle) &&
|
||||
(perp.length() < expanded_radius - np_sphere->get_radius()) &&
|
||||
(project.length() < feeler.length())) {
|
||||
// If the nearest obstacle will collide with our AICharacter then send obstacle detection as true
|
||||
if((_nearest_obstacle) && (perp.length() < expanded_radius - np_sphere->get_radius()) && (project.length() < feeler.length())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: obstacle_avoidance_activate
|
||||
// Description: This function activates obstacle_avoidance if an
|
||||
// obstacle is detected
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : obstacle_avoidance_activate
|
||||
// Description : This function activates obstacle_avoidance if a obstacle
|
||||
// is detected
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void ObstacleAvoidance::obstacle_avoidance_activate() {
|
||||
if (obstacle_detection()) {
|
||||
if(obstacle_detection()) {
|
||||
_ai_char->_steering->turn_off("obstacle_avoidance_activate");
|
||||
_ai_char->_steering->turn_on("obstacle_avoidance");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_obstacle_avoidance
|
||||
// Description: This function returns the force necessary by the
|
||||
// AICharacter to avoid the nearest obstacle detected
|
||||
// by obstacle_detection function
|
||||
// NOTE : This assumes the obstacles are spherical
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_obstacle_avoidance
|
||||
// Description : This function returns the force necessary by the AICharacter to
|
||||
// avoid the nearest obstacle detected by obstacle_detection
|
||||
// function
|
||||
// NOTE : This assumes the obstacles are spherical
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f ObstacleAvoidance::do_obstacle_avoidance() {
|
||||
LVecBase3f offset = _ai_char->get_node_path().get_pos()
|
||||
- _nearest_obstacle.get_pos();
|
||||
LVecBase3f offset = _ai_char->get_node_path().get_pos() - _nearest_obstacle.get_pos();
|
||||
PT(BoundingVolume) bounds =_nearest_obstacle.get_bounds();
|
||||
CPT(BoundingSphere) bsphere = bounds->as_bounding_sphere();
|
||||
PT(BoundingVolume) np_bounds = _ai_char->get_node_path().get_bounds();
|
||||
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
|
||||
double distance_needed = offset.length() - bsphere->get_radius()
|
||||
- np_sphere->get_radius();
|
||||
|
||||
if (obstacle_detection()) {
|
||||
LVecBase3f direction = _ai_char->get_char_render().get_relative_vector(
|
||||
_ai_char->get_node_path(), LVector3f::forward());
|
||||
double distance_needed = offset.length() - bsphere->get_radius() - np_sphere->get_radius();
|
||||
if((obstacle_detection())) {
|
||||
LVecBase3f direction = _ai_char->get_char_render().get_relative_vector(_ai_char->get_node_path(), LVector3f::forward());
|
||||
direction.normalize();
|
||||
float forward_component = offset.dot(direction);
|
||||
LVecBase3f projection = forward_component * direction;
|
||||
LVecBase3f perpendicular_component = offset - projection;
|
||||
double p = perpendicular_component.length();
|
||||
perpendicular_component.normalize();
|
||||
LVecBase3f avoidance = perpendicular_component;
|
||||
|
||||
// The closer the obstacle, the more force it generates
|
||||
avoidance = (avoidance * _ai_char->get_max_force() *
|
||||
_ai_char->_movt_force) / (p + 0.01);
|
||||
LVecBase3f avoidance = perpendicular_component;
|
||||
// The more closer the obstacle, the more force it generates
|
||||
avoidance = (avoidance * _ai_char->get_max_force() * _ai_char->_movt_force) / (p + 0.01);
|
||||
return avoidance;
|
||||
}
|
||||
_ai_char->_steering->turn_on("obstacle_avoidance_activate");
|
||||
|
@ -1,30 +1,27 @@
|
||||
// Filename: obstacleAvoidance.h
|
||||
// Created by: Deepak, John, Navin (10Nov2009)
|
||||
//
|
||||
#ifndef OBSTACLE_AVOIDANCE_H
|
||||
#define OBSTACLE_AVOIDANCE_H
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : obstacleAvoidance.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 10 Nov 2009
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef OBSTACLE_AVOIDANCE_H
|
||||
#define OBSTACLE_AVOIDANCE_H
|
||||
|
||||
#include "aiCharacter.h"
|
||||
#include "boundingSphere.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ObstacleAvoidance
|
||||
// Description : This class handles all calls to the obstacle
|
||||
// avoidance behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ObstacleAvoidance {
|
||||
class EXPCL_PANDAAI ObstacleAvoidance {
|
||||
public :
|
||||
AICharacter *_ai_char;
|
||||
float _obstacle_avoidance_weight;
|
||||
|
@ -1,19 +1,5 @@
|
||||
// Filename: pathFind.cxx
|
||||
// Created by: Deepak, John, Navin (12Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pathFind.h"
|
||||
#include "pstrtod.h"
|
||||
|
||||
PathFind::PathFind(AICharacter *ai_ch) {
|
||||
_ai_char = ai_ch;
|
||||
@ -21,7 +7,7 @@ PathFind::PathFind(AICharacter *ai_ch) {
|
||||
_parent = new GeomNode("parent");
|
||||
_ai_char->_window_render.attach_new_node(_parent);
|
||||
|
||||
_pen = new LineSegs("pen");
|
||||
_pen = new LineSegs("pen");
|
||||
_pen->set_color(1.0, 0.0, 0.0);
|
||||
_pen->set_thickness(2.0);
|
||||
|
||||
@ -32,11 +18,13 @@ PathFind::PathFind(AICharacter *ai_ch) {
|
||||
PathFind::~PathFind() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: create_nav_mesh
|
||||
// Description: This function recreates the navigation mesh from
|
||||
// the .csv file.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : create_nav_mesh
|
||||
// Description : This function recreates the navigation mesh from the .csv file
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::create_nav_mesh(const char* navmesh_filename) {
|
||||
// Stage variables.
|
||||
int grid_x, grid_y;
|
||||
@ -46,23 +34,22 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) {
|
||||
// Variable to hold line data read from file.
|
||||
string line;
|
||||
|
||||
// Array for storing data members obtained from each line of the
|
||||
// file.
|
||||
// Array for storing data members obtained from each line of the file.
|
||||
string fields[10];
|
||||
|
||||
// Open data file for reading.
|
||||
ifstream nav_mesh_file (navmesh_filename);
|
||||
|
||||
if (nav_mesh_file.is_open()) {
|
||||
if(nav_mesh_file.is_open()) {
|
||||
// Capture the grid size from the file.
|
||||
getline(nav_mesh_file, line);
|
||||
int pos = line.find(",");
|
||||
_grid_size = atoi((line.substr(pos + 1)).c_str());
|
||||
|
||||
// Initialize the stage mesh with NULL nodes.
|
||||
for (int r = 0; r < _grid_size; ++r) {
|
||||
_nav_mesh.push_back(vector<AINode*>());
|
||||
for (int c = 0; c < _grid_size; ++c) {
|
||||
for(int r = 0; r < _grid_size; ++r) {
|
||||
_nav_mesh.push_back(vector<Node*>());
|
||||
for(int c = 0; c < _grid_size; ++c) {
|
||||
_nav_mesh[r].push_back(NULL);
|
||||
}
|
||||
}
|
||||
@ -71,51 +58,52 @@ void PathFind::create_nav_mesh(const char* navmesh_filename) {
|
||||
getline(nav_mesh_file, line);
|
||||
|
||||
// Begin reading data from the file.
|
||||
while (!nav_mesh_file.eof()) {
|
||||
while(!nav_mesh_file.eof()) {
|
||||
getline(nav_mesh_file, line);
|
||||
stringstream linestream (line);
|
||||
|
||||
// Stores all the data members in the line to the array.
|
||||
// Data structure: NULL,NodeType,GridX,GridY,Length,Width,
|
||||
// Height,PosX,PosY,PosZ
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
// Data structure: NULL,NodeType,GridX,GridY,Length,Width,Height,PosX,PosY,PosZ
|
||||
for(int i = 0; i < 10; ++i) {
|
||||
getline(linestream, fields[i], ',');
|
||||
}
|
||||
|
||||
// Populate the main nodes into stage mesh.
|
||||
if (fields[0] == "0" && fields[1] == "0") {
|
||||
if(fields[0] == "0" && fields[1] == "0") {
|
||||
grid_x = atoi(fields[2].c_str());
|
||||
grid_y = atoi(fields[3].c_str());
|
||||
l = patof(fields[4].c_str());
|
||||
w = patof(fields[5].c_str());
|
||||
h = patof(fields[6].c_str());
|
||||
position = LVecBase3f(patof(fields[7].c_str()),
|
||||
patof(fields[8].c_str()), patof(fields[9].c_str()));
|
||||
l = atof(fields[4].c_str());
|
||||
w = atof(fields[5].c_str());
|
||||
h = atof(fields[6].c_str());
|
||||
position = LVecBase3f(atof(fields[7].c_str()), atof(fields[8].c_str()), atof(fields[9].c_str()));
|
||||
|
||||
Node *stage_node = new Node(grid_x, grid_y, position, w, l, h);
|
||||
|
||||
AINode *stage_node = new AINode(grid_x, grid_y, position, w, l, h);
|
||||
|
||||
_nav_mesh[grid_y][grid_x] = stage_node;
|
||||
}
|
||||
else if (fields[0] == "") {
|
||||
else if(fields[0] == "") {
|
||||
// End of file reached at this point.
|
||||
nav_mesh_file.close();
|
||||
|
||||
// Assign the neighbor nodes for each of the main nodes
|
||||
// that just got populated into the stage mesh.
|
||||
// Assign the neighbor nodes for each of the main nodes that just got populated into the stage mesh.
|
||||
assign_neighbor_nodes(navmesh_filename);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << "error opening navmesh.csv file!\n";
|
||||
cout<<"error opening navmesh.csv file!"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: assign_neighbor_nodes
|
||||
// Description: This function assigns the neighbor nodes for each
|
||||
// main node present in _nav_mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : assign_neighbor_nodes
|
||||
// Description : This function assigns the neighbor nodes for each main node present in
|
||||
// _nav_mesh.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::assign_neighbor_nodes(const char* navmesh_filename){
|
||||
ifstream nav_mesh_file (navmesh_filename);
|
||||
|
||||
@ -125,70 +113,73 @@ void PathFind::assign_neighbor_nodes(const char* navmesh_filename){
|
||||
string fields[10];
|
||||
string fields_n[10];
|
||||
|
||||
if (nav_mesh_file.is_open()) {
|
||||
if(nav_mesh_file.is_open()) {
|
||||
getline(nav_mesh_file, ln); // Get rid of grid size line.
|
||||
getline(nav_mesh_file, ln); // Get rid of the header.
|
||||
|
||||
while (!nav_mesh_file.eof()) {
|
||||
while(!nav_mesh_file.eof()) {
|
||||
getline(nav_mesh_file, ln); // Gets main node data only. No neighbor nodes.
|
||||
stringstream linestream (ln);
|
||||
for (int i = 0; i < 10; ++i) {
|
||||
for(int i = 0; i < 10; ++i) {
|
||||
getline(linestream, fields[i], ',');
|
||||
}
|
||||
if (fields[0] == "0" && fields[1] == "0") {
|
||||
if(fields[0] == "0" && fields[1] == "0") {
|
||||
// Usable main node.
|
||||
gd_x = atoi(fields[2].c_str());
|
||||
gd_y = atoi(fields[3].c_str());
|
||||
for (int i = 0; i < 8; ++i) {
|
||||
for(int i = 0; i < 8; ++i) {
|
||||
getline(nav_mesh_file, ln); // Gets neighbor node data only. No main nodes.
|
||||
stringstream linestream_n (ln);
|
||||
for (int j = 0; j < 10; ++j) {
|
||||
for(int j = 0; j < 10; ++j) {
|
||||
getline(linestream_n, fields_n[j], ',');
|
||||
}
|
||||
gd_xn = atoi(fields_n[2].c_str());
|
||||
gd_yn = atoi(fields_n[3].c_str());
|
||||
|
||||
if (fields_n[0] == "0" && fields_n[1] == "1") {
|
||||
if(fields_n[0] == "0" && fields_n[1] == "1") {
|
||||
// Usable neighbor for main node.
|
||||
// Note: The indices of the vector are inverted
|
||||
// when compared to the values of the nodes on actual grid.
|
||||
// TODO: The indices of the vector are inverted when compared to the values of the nodes on actual grid. Fix this!
|
||||
_nav_mesh[gd_y][gd_x]->_neighbours[i] = _nav_mesh[gd_yn][gd_xn];
|
||||
}
|
||||
else if (fields_n[0] == "1" && fields_n[1] == "1") {
|
||||
else if(fields_n[0] == "1" && fields_n[1] == "1") {
|
||||
// NULL neighbor.
|
||||
_nav_mesh[gd_y][gd_x]->_neighbours[i] = NULL;
|
||||
}
|
||||
else {
|
||||
cout << "Warning: Corrupt data!\n";
|
||||
cout<<"Warning: Corrupt data!"<<endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fields[0] == "") {
|
||||
else if(fields[0] == "") {
|
||||
// End of file reached at this point.
|
||||
nav_mesh_file.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
cout << "error opening navmesh.csv file!\n";
|
||||
cout<<"error opening navmesh.csv file!"<<endl;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: set_path_find
|
||||
// Description: This function starts the path finding process after
|
||||
// reading the given navigation mesh.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : set_path_find
|
||||
// Description : This function starts the path finding process after reading the given
|
||||
// navigation mesh.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void PathFind::set_path_find(const char* navmesh_filename) {
|
||||
create_nav_mesh(navmesh_filename);
|
||||
|
||||
if (_ai_char->_steering->_path_follow_obj) {
|
||||
if(_ai_char->_steering->_path_follow_obj) {
|
||||
_ai_char->_steering->remove_ai("pathfollow");
|
||||
}
|
||||
|
||||
_ai_char->_steering->path_follow(1.0f);
|
||||
|
||||
if (_path_finder_obj) {
|
||||
if(_path_finder_obj) {
|
||||
delete _path_finder_obj;
|
||||
_path_finder_obj = NULL;
|
||||
}
|
||||
@ -196,17 +187,19 @@ void PathFind::set_path_find(const char* navmesh_filename) {
|
||||
_path_finder_obj = new PathFinder(_nav_mesh);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: path_find (for pathfinding towards a static position)
|
||||
// Description: This function checks for the source and target in
|
||||
// the navigation mesh for its availability and then
|
||||
// finds the best path via the A* algorithm Then it
|
||||
// calls the path follower to make the object follow
|
||||
// the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : path_find (for pathfinding towards a static position)
|
||||
// Description : This function checks for the source and target in the navigation mesh
|
||||
// for its availability and then finds the best path via the A* algorithm
|
||||
// Then it calls the path follower to make the object follow the path.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
void PathFind::path_find(LVecBase3f pos, string type) {
|
||||
if (type == "addPath") {
|
||||
if (_ai_char->_steering->_path_follow_obj) {
|
||||
if(type == "addPath") {
|
||||
if(_ai_char->_steering->_path_follow_obj) {
|
||||
_ai_char->_steering->remove_ai("pathfollow");
|
||||
}
|
||||
|
||||
@ -215,41 +208,40 @@ void PathFind::path_find(LVecBase3f pos, string type) {
|
||||
|
||||
clear_path();
|
||||
|
||||
AINode* src = find_in_mesh(_nav_mesh,
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size);
|
||||
Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size);
|
||||
|
||||
if (src == NULL) {
|
||||
cout << "couldnt find source\n";
|
||||
if(src == NULL) {
|
||||
cout<<"couldnt find source"<<endl;
|
||||
}
|
||||
|
||||
AINode* dst = find_in_mesh(_nav_mesh, pos, _grid_size);
|
||||
Node* dst = find_in_mesh(_nav_mesh, pos, _grid_size);
|
||||
|
||||
if (dst == NULL) {
|
||||
cout << "couldnt find destination\n";
|
||||
if(dst == NULL) {
|
||||
cout<<"couldnt find destination"<<endl;
|
||||
}
|
||||
|
||||
if (src != NULL && dst != NULL) {
|
||||
if(src != NULL && dst != NULL) {
|
||||
_path_finder_obj->find_path(src, dst);
|
||||
trace_path(src);
|
||||
}
|
||||
|
||||
if (!_ai_char->_steering->_path_follow_obj->_start) {
|
||||
if(!_ai_char->_steering->_path_follow_obj->_start) {
|
||||
_ai_char->_steering->start_follow();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: path_find (for pathfinding towards a moving target
|
||||
// (a NodePath))
|
||||
// Description: This function checks for the source and target in
|
||||
// the navigation mesh for its availability and then
|
||||
// finds the best path via the A* algorithm
|
||||
// Then it calls the path follower to make the object
|
||||
// follow the path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : path_find (for pathfinding towards a moving target (a NodePath))
|
||||
// Description : This function checks for the source and target in the navigation mesh
|
||||
// for its availability and then finds the best path via the A* algorithm
|
||||
// Then it calls the path follower to make the object follow the path.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::path_find(NodePath target, string type) {
|
||||
if (type == "addPath") {
|
||||
if (_ai_char->_steering->_path_follow_obj) {
|
||||
if(type == "addPath") {
|
||||
if(_ai_char->_steering->_path_follow_obj) {
|
||||
_ai_char->_steering->remove_ai("pathfollow");
|
||||
}
|
||||
|
||||
@ -261,42 +253,43 @@ void PathFind::path_find(NodePath target, string type) {
|
||||
_path_find_target = target;
|
||||
_prev_position = target.get_pos(_ai_char->_window_render);
|
||||
|
||||
AINode* src = find_in_mesh(_nav_mesh,
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size);
|
||||
Node* src = find_in_mesh(_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _grid_size);
|
||||
|
||||
if (src == NULL) {
|
||||
cout << "couldnt find source\n";
|
||||
if(src == NULL) {
|
||||
cout<<"couldnt find source"<<endl;
|
||||
}
|
||||
|
||||
AINode* dst = find_in_mesh(_nav_mesh, _prev_position, _grid_size);
|
||||
Node* dst = find_in_mesh(_nav_mesh, _prev_position, _grid_size);
|
||||
|
||||
if (dst == NULL) {
|
||||
cout << "couldnt find destination\n";
|
||||
if(dst == NULL) {
|
||||
cout<<"couldnt find destination"<<endl;
|
||||
}
|
||||
|
||||
if (src != NULL && dst != NULL) {
|
||||
if(src != NULL && dst != NULL) {
|
||||
_path_finder_obj->find_path(src, dst);
|
||||
trace_path(src);
|
||||
}
|
||||
|
||||
if (_ai_char->_steering->_path_follow_obj!=NULL) {
|
||||
if (!_ai_char->_steering->_path_follow_obj->_start) {
|
||||
if(_ai_char->_steering->_path_follow_obj!=NULL) {
|
||||
if(!_ai_char->_steering->_path_follow_obj->_start) {
|
||||
_ai_char->_steering->start_follow("pathfind");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: clear_path
|
||||
// Description: Helper function to restore the path and mesh
|
||||
// to its initial state
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : clear_path
|
||||
// Description : Helper function to restore the path and mesh to its initial state
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::clear_path() {
|
||||
// Initialize to zero
|
||||
for (int i = 0; i < _grid_size; ++i) {
|
||||
for (int j = 0; j < _grid_size; ++j) {
|
||||
if (_nav_mesh[i][j] != NULL) {
|
||||
_nav_mesh[i][j]->_status = _nav_mesh[i][j]->ST_neutral;
|
||||
for(int i = 0; i < _grid_size; ++i) {
|
||||
for(int j = 0; j < _grid_size; ++j) {
|
||||
if(_nav_mesh[i][j] != NULL) {
|
||||
_nav_mesh[i][j]->_status = _nav_mesh[i][j]->neutral;
|
||||
_nav_mesh[i][j]->_cost = 0;
|
||||
_nav_mesh[i][j]->_heuristic = 0;
|
||||
_nav_mesh[i][j]->_score = 0;
|
||||
@ -305,34 +298,35 @@ void PathFind::clear_path() {
|
||||
}
|
||||
}
|
||||
|
||||
if (_path_finder_obj) {
|
||||
if(_path_finder_obj) {
|
||||
_path_finder_obj->_open_list.clear();
|
||||
_path_finder_obj->_closed_list.clear();
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: trace_path
|
||||
// Description: This function is the function which sends the path
|
||||
// information one by one to the path follower so that
|
||||
// it can store the path needed to be
|
||||
// traversed by the pathfinding object
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void PathFind::trace_path(AINode* src) {
|
||||
if (_ai_char->_pf_guide) {
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : trace_path
|
||||
// Description : This function is the function which sends the path information one by
|
||||
// one to the path follower so that it can store the path needed to be
|
||||
// traversed by the pathfinding object
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::trace_path(Node* src) {
|
||||
if(_ai_char->_pf_guide) {
|
||||
_parent->remove_all_children();
|
||||
}
|
||||
else {
|
||||
_parent->remove_all_children();
|
||||
}
|
||||
|
||||
if (_path_finder_obj->_closed_list.size() > 0) {
|
||||
AINode *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5];
|
||||
while (traversor != src) {
|
||||
if (_ai_char->_pf_guide) {
|
||||
if(_path_finder_obj->_closed_list.size() > 0) {
|
||||
Node *traversor = _path_finder_obj->_closed_list[_path_finder_obj->_closed_list.size() - 0.5];
|
||||
while(traversor != src) {
|
||||
if(_ai_char->_pf_guide) {
|
||||
_pen->move_to(traversor->_position.get_x(), traversor->_position.get_y(), 1);
|
||||
_pen->draw_to(traversor->_prv_node->_position.get_x(),
|
||||
traversor->_prv_node->_position.get_y(), 0.5);
|
||||
_pen->draw_to(traversor->_prv_node->_position.get_x(), traversor->_prv_node->_position.get_y(), 0.5);
|
||||
PT(GeomNode) gnode = _pen->create();
|
||||
_parent->add_child(gnode);
|
||||
}
|
||||
@ -342,32 +336,33 @@ void PathFind::trace_path(AINode* src) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_obstacle_to_mesh
|
||||
// Description: This function allows the user to dynamically add
|
||||
// obstacles to the game environment. The function
|
||||
// will update the nodes within the
|
||||
// bounding volume of the obstacle as non-traversable.
|
||||
// Hence will not be considered by the pathfinding
|
||||
// algorithm.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_obstacle_to_mesh
|
||||
// Description : This function allows the user to dynamically add obstacles to the
|
||||
// game environment. The function will update the nodes within the
|
||||
// bounding volume of the obstacle as non-traversable. Hence will not be
|
||||
// considered by the pathfinding algorithm.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::add_obstacle_to_mesh(NodePath obstacle) {
|
||||
PT(BoundingVolume) np_bounds = obstacle.get_bounds();
|
||||
CPT(BoundingSphere) np_sphere = np_bounds->as_bounding_sphere();
|
||||
|
||||
AINode* temp = find_in_mesh(_nav_mesh, obstacle.get_pos(), _grid_size);
|
||||
Node* temp = find_in_mesh(_nav_mesh, obstacle.get_pos(), _grid_size);
|
||||
|
||||
if (temp != NULL) {
|
||||
if(temp != NULL) {
|
||||
float left = temp->_position.get_x() - np_sphere->get_radius();
|
||||
float right = temp->_position.get_x() + np_sphere->get_radius();
|
||||
float top = temp->_position.get_y() + np_sphere->get_radius();
|
||||
float down = temp->_position.get_y() - np_sphere->get_radius();
|
||||
|
||||
for (int i = 0; i < _grid_size; ++i) {
|
||||
for (int j = 0; j < _grid_size; ++j) {
|
||||
if (_nav_mesh[i][j] != NULL && _nav_mesh[i][j]->_type == true) {
|
||||
if (_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right &&
|
||||
_nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) {
|
||||
for(int i = 0; i < _grid_size; ++i) {
|
||||
for(int j = 0; j < _grid_size; ++j) {
|
||||
if(_nav_mesh[i][j] != NULL && _nav_mesh[i][j]->_type == true) {
|
||||
if(_nav_mesh[i][j]->_position.get_x() >= left && _nav_mesh[i][j]->_position.get_x() <= right &&
|
||||
_nav_mesh[i][j]->_position.get_y() >= down && _nav_mesh[i][j]->_position.get_y() <= top) {
|
||||
_nav_mesh[i][j]->_type = false;
|
||||
_previous_obstacles.insert(_previous_obstacles.end(), i);
|
||||
_previous_obstacles.insert(_previous_obstacles.end(), j);
|
||||
@ -378,35 +373,44 @@ void PathFind::add_obstacle_to_mesh(NodePath obstacle) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_dynamic_avoid()
|
||||
// Description: This function does the updation of the collisions to
|
||||
// the mesh based on the new positions of the obstacles.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_dynamic_avoid()
|
||||
// Description : This function does the updation of the collisions to the mesh based
|
||||
// on the new positions of the obstacles.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::do_dynamic_avoid() {
|
||||
clear_previous_obstacles();
|
||||
_previous_obstacles.clear();
|
||||
for (unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) {
|
||||
for(unsigned int i = 0; i < _dynamic_obstacle.size(); ++i) {
|
||||
add_obstacle_to_mesh(_dynamic_obstacle[i]);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: clear_previous_obstacles()
|
||||
// Description: Helper function to reset the collisions if the
|
||||
// obstacle is not on the node anymore.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : clear_previous_obstacles()
|
||||
// Description : Helper function to reset the collisions if the obstacle is not on the
|
||||
// node anymore
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::clear_previous_obstacles(){
|
||||
for (unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) {
|
||||
for(unsigned int i = 0; i < _previous_obstacles.size(); i = i + 2) {
|
||||
_nav_mesh[_previous_obstacles[i]][_previous_obstacles[i + 1]]->_type = true;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: dynamic_avoid
|
||||
// Description: This function starts the pathfinding obstacle
|
||||
// navigation for the passed in obstacle.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : dynamic_avoid
|
||||
// Description : This function starts the pathfinding obstacle navigation for the
|
||||
// passed in obstacle.
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFind::dynamic_avoid(NodePath obstacle) {
|
||||
_dynamic_avoid = true;
|
||||
_dynamic_obstacle.insert(_dynamic_obstacle.end(), obstacle);
|
||||
|
@ -1,19 +1,21 @@
|
||||
// Filename: pathFind.h
|
||||
// Created by: Deepak, John, Navin (12Oct09)
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : pathFind.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 12 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PATHFIND_H
|
||||
#define PATHFIND_H
|
||||
#ifndef _PATHFIND_H
|
||||
#define _PATHFIND_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
@ -22,16 +24,16 @@
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PathFind
|
||||
// Description : This class contains all the members and functions
|
||||
// that are required to form an interface between
|
||||
// the AIBehaviors class and the PathFinder class.
|
||||
// An object (pointer) of this class is provided in
|
||||
// the AIBehaviors class. It is only via this object
|
||||
// that the user can activate pathfinding.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class PathFind {
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Class : PathFind
|
||||
// Description : This class contains all the members and functions that are required to form an interface between
|
||||
// the AIBehaviors class and the PathFinder class. An object (pointer) of this class is provided in the
|
||||
// AIBehaviors class. It is only via this object that the user can activate pathfinding.
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class EXPCL_PANDAAI PathFind {
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
PathFinder *_path_finder_obj;
|
||||
@ -52,7 +54,7 @@ public:
|
||||
~PathFind();
|
||||
|
||||
void clear_path();
|
||||
void trace_path(AINode* src);
|
||||
void trace_path(Node* src);
|
||||
|
||||
void create_nav_mesh(const char* navmesh_filename);
|
||||
void assign_neighbor_nodes(const char* navmesh_filename);
|
||||
|
@ -1,16 +1,3 @@
|
||||
// Filename: pathFollow.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "pathFollow.h"
|
||||
|
||||
@ -25,24 +12,29 @@ PathFollow::PathFollow(AICharacter *ai_ch, float follow_wt) {
|
||||
PathFollow::~PathFollow() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: add_to_path
|
||||
// Description: This function adds the positions generated from a
|
||||
// pathfind or a simple path follow behavior to the
|
||||
// _path list.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : add_to_path
|
||||
// Description : This function adds the positions generated from a pathfind or a simple
|
||||
// path follow behavior to the _path list.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFollow::add_to_path(LVecBase3f pos) {
|
||||
_path.push_back(pos);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: start
|
||||
// Description: This function initiates the path follow behavior.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : start
|
||||
// Description : This function initiates the path follow behavior.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFollow::start(string type) {
|
||||
_type = type;
|
||||
_start = true;
|
||||
if (_path.size() > 0) {
|
||||
if(_path.size() > 0) {
|
||||
_curr_path_waypoint = _path.size() - 1;
|
||||
_dummy = _ai_char->_window_render.attach_new_node("dummy");
|
||||
_dummy.set_pos(_path[_curr_path_waypoint]);
|
||||
@ -51,32 +43,31 @@ void PathFollow::start(string type) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_follow
|
||||
// Description: This function allows continuous path finding by AI
|
||||
// chars. There are 2 ways in which this is implemented.
|
||||
// 1. The character re-calculates the optimal path
|
||||
// everytime the target changes its position.
|
||||
// Less computationally expensive.
|
||||
// 2. The character continuosly re-calculates its
|
||||
// optimal path to the target. This is used in a
|
||||
// scenario where the ai chars have to avoid other AI
|
||||
// chars. More computationally expensive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_follow
|
||||
// Description : This function allows continuous path finding by ai chars. There are 2
|
||||
// ways in which this is implemented.
|
||||
// 1. The character re-calculates the optimal path everytime the target
|
||||
// changes its position. Less computationally expensive.
|
||||
// 2. The character continuosly re-calculates its optimal path to the
|
||||
// target. This is used in a scenario where the ai chars have to avoid
|
||||
// other ai chars. More computationally expensive.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PathFollow::do_follow() {
|
||||
if ((_myClock->get_real_time() - _time) > 0.5) {
|
||||
if (_type == "pathfind") {
|
||||
// This 'if' statement when 'true' causes the path to be
|
||||
// re-calculated irrespective of target position.
|
||||
// This is done when _dynamice_avoid is active. More
|
||||
// computationally expensive.
|
||||
if (_ai_char->_steering->_path_find_obj->_dynamic_avoid) {
|
||||
if((_myClock->get_real_time() - _time) > 0.5) {
|
||||
if(_type=="pathfind") {
|
||||
// This 'if' statement when 'true' causes the path to be re-calculated irrespective of target position.
|
||||
// This is done when _dynamice_avoid is active. More computationally expensive.
|
||||
if(_ai_char->_steering->_path_find_obj->_dynamic_avoid) {
|
||||
_ai_char->_steering->_path_find_obj->do_dynamic_avoid();
|
||||
if (check_if_possible()) {
|
||||
if(check_if_possible()) {
|
||||
_path.clear();
|
||||
_ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
|
||||
// Ensure that the path size is not 0.
|
||||
if (_path.size() > 0) {
|
||||
if(_path.size() > 0) {
|
||||
_curr_path_waypoint = _path.size() - 1;
|
||||
_dummy.set_pos(_path[_curr_path_waypoint]);
|
||||
}
|
||||
@ -86,16 +77,15 @@ void PathFollow::do_follow() {
|
||||
}
|
||||
}
|
||||
}
|
||||
// This 'if' statement causes the path to be re-calculated only
|
||||
// when there is a change in target position.
|
||||
// This 'if' statement causes the path to be re-calculated only when there is a change in target position.
|
||||
// Less computationally expensive.
|
||||
else if (_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render)
|
||||
else if(_ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render)
|
||||
!= _ai_char->_steering->_path_find_obj->_prev_position) {
|
||||
if (check_if_possible()) {
|
||||
if(check_if_possible()) {
|
||||
_path.clear();
|
||||
_ai_char->_steering->_path_find_obj->path_find(_ai_char->_steering->_path_find_obj->_path_find_target);
|
||||
// Ensure that the path size is not 0.
|
||||
if (_path.size() > 0) {
|
||||
if(_path.size() > 0) {
|
||||
_curr_path_waypoint = _path.size() - 1;
|
||||
_dummy.set_pos(_path[_curr_path_waypoint]);
|
||||
}
|
||||
@ -107,32 +97,35 @@ void PathFollow::do_follow() {
|
||||
}
|
||||
_time = _myClock->get_real_time();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_curr_path_waypoint > 0) {
|
||||
double distance = (_path[_curr_path_waypoint] -
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
|
||||
if(_curr_path_waypoint > 0) {
|
||||
double distance = (_path[_curr_path_waypoint] - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
|
||||
|
||||
if (distance < 5) {
|
||||
if(distance < 5) {
|
||||
_curr_path_waypoint--;
|
||||
_dummy.set_pos(_path[_curr_path_waypoint]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: check_if_possible
|
||||
// Description: This function checks if the current positions of
|
||||
// the ai char and the target char can be used to
|
||||
// generate an optimal path.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool PathFollow::check_if_possible() {
|
||||
AINode* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh,
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render),
|
||||
_ai_char->_steering->_path_find_obj->_grid_size);
|
||||
LVecBase3f _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render);
|
||||
AINode* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh,
|
||||
_prev_position, _ai_char->_steering->_path_find_obj->_grid_size);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : check_if_possible
|
||||
// Description : This function checks if the current positions of the ai char and the
|
||||
// target char can be used to generate an optimal path.
|
||||
|
||||
return (src && dst);
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool PathFollow::check_if_possible() {
|
||||
Node* src = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _ai_char->_ai_char_np.get_pos(_ai_char->_window_render), _ai_char->_steering->_path_find_obj->_grid_size);
|
||||
LVecBase3f _prev_position = _ai_char->_steering->_path_find_obj->_path_find_target.get_pos(_ai_char->_window_render);
|
||||
Node* dst = find_in_mesh(_ai_char->_steering->_path_find_obj->_nav_mesh, _prev_position, _ai_char->_steering->_path_find_obj->_grid_size);
|
||||
|
||||
if(src && dst) {
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -1,32 +1,14 @@
|
||||
// Filename: pathFollow.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PATHFOLLOW_H
|
||||
#define PATHFOLLOW_H
|
||||
#ifndef _PATHFOLLOW_H
|
||||
#define _PATHFOLLOW_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
#include "aiNode.h"
|
||||
#include "meshNode.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : PathFollow
|
||||
// Description : This class handles all calls to the path follow
|
||||
// behavior and has functions to handle pathfinding
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class PathFollow {
|
||||
class EXPCL_PANDAAI PathFollow {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: pursue.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : pursue.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -26,27 +27,27 @@ Pursue::Pursue(AICharacter *ai_ch, NodePath target_object, float pursue_wt) {
|
||||
Pursue::~Pursue() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_pursue
|
||||
// Description: This function performs the pursue and returns a
|
||||
// pursue force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// In case the target has been reached it resets the
|
||||
// forces to 0 so that the character stops.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_pursue
|
||||
// Description : This function performs the pursue and returns a pursue force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// In case the target has been reached it resets the forces to 0 so that the character stops.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Pursue::do_pursue() {
|
||||
assert(_pursue_target && "pursue target not assigned");
|
||||
|
||||
LVecBase3f present_pos = _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
double target_distance = (_pursue_target.get_pos(_ai_char->_window_render) -
|
||||
present_pos).length();
|
||||
double target_distance = (_pursue_target.get_pos(_ai_char->_window_render) - present_pos).length();
|
||||
|
||||
if (int(target_distance) == 0) {
|
||||
if(int(target_distance) == 0) {
|
||||
_pursue_done = true;
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
_ai_char->_steering->_pursue_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
else {
|
||||
_pursue_done = false;
|
||||
@ -56,5 +57,5 @@ LVecBase3f Pursue::do_pursue() {
|
||||
_pursue_direction.normalize();
|
||||
|
||||
LVecBase3f desired_force = _pursue_direction * _ai_char->_movt_force;
|
||||
return (desired_force);
|
||||
return(desired_force);
|
||||
}
|
||||
|
@ -1,31 +1,27 @@
|
||||
// Filename: pursue.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : pursue.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef PURSUE_H
|
||||
#define PURSUE_H
|
||||
#ifndef _PURSUE_H
|
||||
#define _PURSUE_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Pursue
|
||||
// Description : This class handles all calls to the pursue
|
||||
// behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Pursue {
|
||||
class EXPCL_PANDAAI Pursue {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
@ -39,4 +35,5 @@ public:
|
||||
~Pursue();
|
||||
LVecBase3f do_pursue();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -1,14 +1,15 @@
|
||||
// Filename: seek.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : seek.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -20,21 +21,19 @@ Seek::Seek(AICharacter *ai_ch, NodePath target_object, float seek_wt) {
|
||||
_seek_position = target_object.get_pos(_ai_char->_window_render);
|
||||
_seek_weight = seek_wt;
|
||||
|
||||
_seek_direction = _seek_position -
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_seek_direction = _seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_seek_direction.normalize();
|
||||
|
||||
_seek_done = false;
|
||||
}
|
||||
|
||||
Seek::Seek(AICharacter *ai_ch, LVecBase3f pos, float seek_wt) {
|
||||
_ai_char = ai_ch;
|
||||
_ai_char = ai_ch;
|
||||
|
||||
_seek_position = pos;
|
||||
_seek_weight = seek_wt;
|
||||
|
||||
_seek_direction = _seek_position -
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_seek_direction = _seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render);
|
||||
_seek_direction.normalize();
|
||||
|
||||
_seek_done = false;
|
||||
@ -43,24 +42,25 @@ Seek::Seek(AICharacter *ai_ch, LVecBase3f pos, float seek_wt) {
|
||||
Seek::~Seek() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_seek
|
||||
// Description: This function performs the seek and returns a seek
|
||||
// force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
LVecBase3f Seek::do_seek() {
|
||||
double target_distance = (_seek_position -
|
||||
_ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_seek
|
||||
// Description : This function performs the seek and returns a seek force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// This function is not to be used by the user.
|
||||
|
||||
if (int(target_distance) == 0) {
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Seek::do_seek() {
|
||||
double target_distance = (_seek_position - _ai_char->_ai_char_np.get_pos(_ai_char->_window_render)).length();
|
||||
|
||||
if(int(target_distance) == 0) {
|
||||
_seek_done = true;
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
_ai_char->_steering->turn_off("seek");
|
||||
return (LVecBase3f(0.0, 0.0, 0.0));
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
_ai_char->_steering->turn_off("seek");
|
||||
return(LVecBase3f(0.0, 0.0, 0.0));
|
||||
}
|
||||
|
||||
LVecBase3f desired_force = _seek_direction * _ai_char->_movt_force;
|
||||
return (desired_force);
|
||||
return(desired_force);
|
||||
}
|
||||
|
@ -1,30 +1,27 @@
|
||||
// Filename: seek.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : seek.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef SEEK_H
|
||||
#define SEEK_H
|
||||
#ifndef _SEEK_H
|
||||
#define _SEEK_H
|
||||
|
||||
#include "aiGlobals.h"
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Seek
|
||||
// Description : This class handles all calls to the seek behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Seek {
|
||||
class EXPCL_PANDAAI Seek {
|
||||
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
|
@ -1,39 +1,45 @@
|
||||
// Filename: wander.cxx
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : wander.cxx
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "wander.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: rand_float
|
||||
// Description: This function creates a random float point number
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : rand_float
|
||||
// Description : This function creates a random float point number
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double rand_float() {
|
||||
const static double rand_max = 0x7fff;
|
||||
return ((rand()) / (rand_max + 1.0));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: random_clamped
|
||||
// Description: This function returns a random floating point number
|
||||
// in the range -1 to 1.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : random_clamped
|
||||
// Description : This function returns a random floating point number in the range
|
||||
// -1 to 1.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double random_clamped() {
|
||||
return (rand_float() - rand_float());
|
||||
return (rand_float() - rand_float());
|
||||
}
|
||||
|
||||
Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag,
|
||||
double aoe, float wander_weight) {
|
||||
Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag, double aoe, float wander_weight) {
|
||||
_ai_char = ai_ch;
|
||||
_wander_radius = wander_radius ;
|
||||
_wander_weight = wander_weight;
|
||||
@ -49,30 +55,25 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag,
|
||||
// Value 2 - XZ axes wander
|
||||
// Value 3 - XYZ axes wander
|
||||
// default is XY axes
|
||||
switch (_flag) {
|
||||
switch(_flag) {
|
||||
case 0: {
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta),
|
||||
_wander_radius * sin(theta),0);
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
|
||||
break;
|
||||
}
|
||||
case 1: {
|
||||
_wander_target = LVecBase3f(0, _wander_radius * cos(theta),
|
||||
_wander_radius * sin(theta));
|
||||
_wander_target = LVecBase3f(0, _wander_radius * cos(theta), _wander_radius * sin(theta));
|
||||
break;
|
||||
}
|
||||
case 2: {
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta), 0,
|
||||
_wander_radius * sin(theta));
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta), 0, _wander_radius * sin(theta));
|
||||
break;
|
||||
}
|
||||
case 3: {
|
||||
_wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si),
|
||||
_wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta));
|
||||
_wander_target = LVecBase3f(_wander_radius * sin(theta) * cos(si), _wander_radius * sin(theta) * sin(si), _wander_radius * cos(theta));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta),
|
||||
_wander_radius * sin(theta),0);
|
||||
_wander_target = LVecBase3f(_wander_radius * cos(theta), _wander_radius * sin(theta),0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -81,21 +82,22 @@ Wander::Wander(AICharacter *ai_ch, double wander_radius,int flag,
|
||||
Wander::~Wander() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: do_wander
|
||||
// Description: This function performs the wander and returns the
|
||||
// wander force which is used
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Function : do_wander
|
||||
// Description : This function performs the wander and returns the wander force which is used
|
||||
// in the calculate_prioritized function.
|
||||
// This function is not to be used by the user.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LVecBase3f Wander::do_wander() {
|
||||
LVecBase3f present_pos = _ai_char->get_node_path().get_pos(_ai_char->get_char_render());
|
||||
// Create the random slices to enable random movement of wander
|
||||
// for x,y,z respectively
|
||||
// Create the random slices to enable random movement of wander for x,y,z respectively
|
||||
double time_slice_1 = random_clamped() * 1.5;
|
||||
double time_slice_2 = random_clamped() * 1.5;
|
||||
double time_slice_3 = random_clamped() * 1.5;
|
||||
switch (_flag) {
|
||||
switch(_flag) {
|
||||
case 0: {
|
||||
_wander_target += LVecBase3f(time_slice_1, time_slice_2, 0);
|
||||
break;
|
||||
@ -128,13 +130,13 @@ LVecBase3f Wander::do_wander() {
|
||||
desired_force.normalize();
|
||||
desired_force *= _ai_char->_movt_force;
|
||||
double distance = (present_pos - _init_pos).length();
|
||||
if (_area_of_effect > 0 && distance > _area_of_effect) {
|
||||
LVecBase3f direction = present_pos - _init_pos;
|
||||
direction.normalize();
|
||||
desired_force = - direction * _ai_char->_movt_force;
|
||||
LVecBase3f dirn = _ai_char->_steering->_steering_force;
|
||||
dirn.normalize();
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
if(_area_of_effect > 0 && distance > _area_of_effect) {
|
||||
LVecBase3f direction = present_pos - _init_pos;
|
||||
direction.normalize();
|
||||
desired_force = - direction * _ai_char->_movt_force;
|
||||
LVecBase3f dirn = _ai_char->_steering->_steering_force;
|
||||
dirn.normalize();
|
||||
_ai_char->_steering->_steering_force = LVecBase3f(0.0, 0.0, 0.0);
|
||||
}
|
||||
return desired_force;
|
||||
}
|
||||
|
@ -1,40 +1,38 @@
|
||||
// Filename: wander.h
|
||||
// Created by: Deepak, John, Navin (24Oct09)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////
|
||||
// Filename : wander.h
|
||||
// Created by : Deepak, John, Navin
|
||||
// Date : 24 Oct 09
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised
|
||||
// BSD license. You should have received a copy of this license
|
||||
// along with this source code in a file named "LICENSE."
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
#ifndef WANDER_H
|
||||
#define WANDER_H
|
||||
|
||||
#ifndef _WANDER_H
|
||||
#define _WANDER_H
|
||||
|
||||
#include "aiCharacter.h"
|
||||
|
||||
class AICharacter;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : Wander
|
||||
// Description : This class handles all calls to the wander behavior
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class Wander {
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
double _wander_radius;
|
||||
LVecBase3f _wander_target;
|
||||
float _wander_weight;
|
||||
int _flag;
|
||||
LVecBase3f _init_pos;
|
||||
double _area_of_effect;
|
||||
class EXPCL_PANDAAI Wander {
|
||||
public:
|
||||
AICharacter *_ai_char;
|
||||
double _wander_radius;
|
||||
LVecBase3f _wander_target;
|
||||
float _wander_weight;
|
||||
int _flag;
|
||||
LVecBase3f _init_pos;
|
||||
double _area_of_effect;
|
||||
|
||||
Wander(AICharacter *ai_ch, double wander_radius, int flag, double aoe, float wander_weight);
|
||||
LVecBase3f do_wander();
|
||||
~Wander();
|
||||
Wander(AICharacter *ai_ch, double wander_radius, int flag, double aoe, float wander_weight);
|
||||
LVecBase3f do_wander();
|
||||
~Wander();
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user