Planeshift

pathfind.h

Go to the documentation of this file.
00001 /*
00002 * pathfind.h
00003 *
00004 * Copyright (C) 2005 Atomic Blue ([email protected], http://www.atomicblue.org)
00005 *
00006 * This program is free software; you can redistribute it and/or
00007 * modify it under the terms of the GNU General Public License
00008 * as published by the Free Software Foundation (version 2
00009 * of the License).
00010 * This program is distributed in the hope that it will be useful,
00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00013 * GNU General Public License for more details.
00014 * You should have received a copy of the GNU General Public License
00015 * along with this program; if not, write to the Free Software
00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017 */
00018 
00019 #ifndef ___PATHFIND_HEADER___
00020 #define ___PATHFIND_HEADER___
00021 
00022 #ifdef USE_WALKPOLY
00023 
00024 //=============================================================================
00025 // Crystal Space Includes
00026 //=============================================================================
00027 #include <csgeom/vector3.h>
00028 #include <csgeom/box.h>
00029 #include <csutil/hash.h>
00030 #include <iutil/objreg.h>
00031 #include <csutil/array.h>
00032 #include <csutil/csstring.h>
00033 #include <csutil/list.h>
00034 
00039 class psANode;
00040 class psWalkPoly;
00041 class psWalkPolyMap;
00042 class psAMap;
00043 struct iVFS;
00044 struct iSector;
00045 struct iCollection;
00046 struct iEngine;
00047 struct iDocumentNode;
00048 
00049 /***************************************************************************/
00052 class psPFMap
00053 {
00054 public:
00055     csString name;
00056     iCollection* region;
00057     psWalkPolyMap* wpMap;
00058     psAMap* aMap;
00059 };
00060 
00061 /***************************************************************************/
00064 class psPFMaps
00065 {
00066 public:
00067     psPFMaps(iObjectRegistry* objReg);
00068     psPFMap* GetRegionBySector(const csString &sectorName);
00069     psPFMap* GetRegionBySector(iSector* sector);
00070     psPFMap* FindRegionByName(const csString &regionName);
00071 
00072 protected:
00073     iCollection* GetCSRegionOfSector(const csString &sectorName);
00074 
00075     csList<psPFMap*> regions;
00076 
00078     csHash<psPFMap*, csString> regionMap;
00079 
00080     iObjectRegistry* objReg;
00081     csRef<iEngine> engine;
00082 };
00083 
00084 /***************************************************************************/
00089 class psAEdge
00090 {
00091 public:
00092     psAEdge(psANode* neighbour, float cost);
00093     psANode* neighbour;
00094     float cost;    
00096 };
00097 
00098 /* Empty subclass that unites psACluster and psAHierarchyNode
00099 class psAHierarchyNode
00100 {
00101 };*/
00102 
00103 /*************************************************************/
00107 class psACluster
00108 {
00109 public:
00110     bool Contains(psANode* node);
00111     bool AddNode(psANode* node);
00112     void DeleteNode(psANode* node);
00113 
00114     void GrowClusterFrom(psANode* start, int level, csList <psANode*> &unassigned);
00115 
00116 protected:
00117 
00118     int CalcFreeBorderSize(int level);
00119 
00120     csList <psANode*> parts;
00121     csList <psANode*> exits;
00122 };
00123 
00124 /*******************************************************************************/
00130 enum psAState {AState_open, AState_closed, AState_unknown};
00131 
00132 
00133 /************************************************************************/
00141 class psANode
00142 {
00143 public:
00144     psANode();
00145     ~psANode();
00146     psANode(const csVector3 &point);
00147     psANode(const csVector3 &point, iSector* sector);
00148 
00151     void EnsureNodeIsInited(int currARunNum);
00152 
00153     void SetBestPrev(psANode* bestPrev, float cost);
00154     void CalcHeur(psANode* goal);
00155     void AddEdge(psANode* neighbour, float cost, int level, bool bidirectional=true);
00156     void DeleteEdges(psANode* neighbour);
00157 
00158     void ConnectToPoly(psWalkPoly* poly, bool bidirectional);
00159 
00160     bool ShouldBePruned(psAMap &map);
00161 
00162     void SaveToString(csString &str);
00163 
00164     //wpMap can be NULL
00165     void LoadBasicsFromXML(iDocumentNode* node, psWalkPolyMap* wpMap, iEngine* engine);
00166     void LoadEdgesFromXML(iDocumentNode* node, psAMap &map);
00167 
00168     void DumpJS();
00169 
00170     psWalkPoly* GetSomePoly();
00171 
00172     //works on 0th level only !
00173     void DeleteConnectionsFromNeighbours();
00174     void RestoreConnectionsFromNeighbours();
00175 
00176     //on 0th level
00177     float GetEdgeCost(psANode* neighbour);
00178 
00179     csVector3 point;
00180     iSector* sector;
00181     csArray<csArray<psAEdge> > edges;
00182     psACluster* cluster;
00183 
00184     int id;
00185     psWalkPoly* poly1, * poly2;
00186     static int nextID;
00187 
00188     /* The following variables are temporary A* state valid for one A* run only */
00189     int ARunNum;          
00190     psAState state;
00191     psANode* prevInOpen, * nextInOpen;   
00192     psANode* bestPrev;
00193     float bestCost;
00194     float heur;
00195     float total;
00196 };
00197 
00198 class psAPath
00199 {
00200 public:
00201     psAPath();
00202     psAPath(psPFMaps* regions);
00203 
00204     void SetMaps(psPFMaps* maps);
00205 
00206     void AddNodeToFront(psANode* node);
00207 
00208     // resets
00209     void SetDest(const csVector3 &dest);
00210     csVector3 GetDest()
00211     {
00212         return dest;
00213     }
00214 
00215     void CalcLocalDest(const csVector3 &currPoint, iSector* currSector, csVector3 &localDest);
00216 
00217     void Dump();
00218     void ResetNodes();
00219 
00221     float CalcCost();
00222 
00223 protected:
00224 
00225     csList<psANode*>::Iterator FindDirectNode(const csVector3 &currPoint);
00226     void InsertSubpath(psAPath &subpath);
00227     csString GetRegionNameOfSector(const csString &sectorName);
00228     psANode* GetNthNode(int n);
00229     void RandomizeFirst(const csVector3 &currPoint);
00230 
00231     bool CalcLocalDestFromLocalPath(const csVector3 &currPoint, csVector3 &localDest);
00232 
00233     psANode* FindNearbyANode(const csVector3 &pos, iSector* sector);
00234 
00235     csVector3 dest;
00236     csList<psANode*> nodes;
00237     psPFMaps* maps;
00238 };
00239 
00241 class psAMap
00242 {
00243 public:
00244     psAMap(iObjectRegistry* objReg);
00245     psAMap();
00246 
00247     void SetObjReg(iObjectRegistry* objReg)
00248     {
00249         this->objReg=objReg;
00250     }
00251     void AddNode(psANode* node);
00252 
00253     void PruneSuperfluous();
00254 
00257     void BuildHierarchy();
00258 
00262     bool RunA(psANode* start, psANode* goal, int level, int maxExpands, psAPath &path);
00263 
00264     void DumpJS();
00265 
00266     bool LoadFromString(const csString &str, psWalkPolyMap* wpMap);
00267     bool LoadFromFile(const csString &path, psWalkPolyMap* wpMap);
00268     void SaveToString(csString &str);
00269     bool SaveToFile(const csString &path);
00270 
00271     psANode* FindNode(int id);
00272 
00273 protected:
00274     csList <psANode*> nodes;
00275     csList <psACluster*> clusters;
00276     iObjectRegistry* objReg;
00277     csRef<iVFS> vfs;
00278 };
00279 
00282 #endif
00283 
00284 #endif