@ -5,16 +5,16 @@
# include "../mwbase/world.hpp"
# include "../mwbase/world.hpp"
# include "../mwbase/environment.hpp"
# include "../mwbase/environment.hpp"
# include "../mwworld/esmstore.hpp"
# include "../mwworld/cellstore.hpp"
# include "../mwworld/cellstore.hpp"
# include "pathgrid.hpp"
# include "coordinateconverter.hpp"
# include "coordinateconverter.hpp"
namespace
namespace
{
{
// Chooses a reachable end pathgrid point. start is assumed reachable.
// Chooses a reachable end pathgrid point. start is assumed reachable.
std : : pair < int , bool > getClosestReachablePoint ( const ESM : : Pathgrid * grid ,
std : : pair < int , bool > getClosestReachablePoint ( const ESM : : Pathgrid * grid ,
const MW World: : CellStore * cell ,
const MW Mechanics: : PathgridGraph * graph ,
const osg : : Vec3f & pos , int start )
const osg : : Vec3f & pos , int start )
{
{
assert ( grid & & ! grid - > mPoints . empty ( ) ) ;
assert ( grid & & ! grid - > mPoints . empty ( ) ) ;
@ -31,7 +31,7 @@ namespace
if ( potentialDistBetween < closestDistanceReachable )
if ( potentialDistBetween < closestDistanceReachable )
{
{
// found a closer one
// found a closer one
if ( cell - > isPointConnected ( start , counter ) )
if ( graph - > isPointConnected ( start , counter ) )
{
{
closestDistanceReachable = potentialDistBetween ;
closestDistanceReachable = potentialDistBetween ;
closestReachableIndex = counter ;
closestReachableIndex = counter ;
@ -45,7 +45,7 @@ namespace
}
}
// post-condition: start and endpoint must be connected
// post-condition: start and endpoint must be connected
assert ( cell - > isPointConnected ( start , closestReachableIndex ) ) ;
assert ( graph - > isPointConnected ( start , closestReachableIndex ) ) ;
// AiWander has logic that depends on whether a path was created, deleting
// AiWander has logic that depends on whether a path was created, deleting
// allowed nodes if not. Hence a path needs to be created even if the start
// allowed nodes if not. Hence a path needs to be created even if the start
@ -120,8 +120,8 @@ namespace MWMechanics
}
}
PathFinder : : PathFinder ( )
PathFinder : : PathFinder ( )
: mPathgrid ( NULL ) ,
: mPathgrid ( NULL )
mCell ( NULL )
, mCell ( NULL )
{
{
}
}
@ -169,14 +169,15 @@ namespace MWMechanics
*/
*/
void PathFinder : : buildPath ( const ESM : : Pathgrid : : Point & startPoint ,
void PathFinder : : buildPath ( const ESM : : Pathgrid : : Point & startPoint ,
const ESM : : Pathgrid : : Point & endPoint ,
const ESM : : Pathgrid : : Point & endPoint ,
const MWWorld : : CellStore * cell )
const MWWorld : : CellStore * cell , const PathgridGraph & pathgridGraph )
{
{
mPath . clear ( ) ;
mPath . clear ( ) ;
// TODO: consider removing mCell / mPathgrid in favor of mPathgridGraph
if ( mCell ! = cell | | ! mPathgrid )
if ( mCell ! = cell | | ! mPathgrid )
{
{
mCell = cell ;
mCell = cell ;
mPathgrid = MWBase: : Environment : : get ( ) . getWorld ( ) - > getStore ( ) . get < ESM : : Pathgrid > ( ) . search ( * mCell - > getCell ( ) ) ;
mPathgrid = pathgridGraph. getPathgrid ( ) ;
}
}
// Refer to AiWander reseach topic on openmw forums for some background.
// Refer to AiWander reseach topic on openmw forums for some background.
@ -200,7 +201,7 @@ namespace MWMechanics
int startNode = GetClosestPoint ( mPathgrid , startPointInLocalCoords ) ;
int startNode = GetClosestPoint ( mPathgrid , startPointInLocalCoords ) ;
osg : : Vec3f endPointInLocalCoords ( converter . toLocalVec3 ( endPoint ) ) ;
osg : : Vec3f endPointInLocalCoords ( converter . toLocalVec3 ( endPoint ) ) ;
std : : pair < int , bool > endNode = getClosestReachablePoint ( mPathgrid , cell ,
std : : pair < int , bool > endNode = getClosestReachablePoint ( mPathgrid , & pathgridGraph ,
endPointInLocalCoords ,
endPointInLocalCoords ,
startNode ) ;
startNode ) ;
@ -228,7 +229,7 @@ namespace MWMechanics
}
}
else
else
{
{
mPath = mCell- > aStarSearch ( startNode , endNode . first ) ;
mPath = pathgridGraph. aStarSearch ( startNode , endNode . first ) ;
// convert supplied path to world coordinates
// convert supplied path to world coordinates
for ( std : : list < ESM : : Pathgrid : : Point > : : iterator iter ( mPath . begin ( ) ) ; iter ! = mPath . end ( ) ; + + iter )
for ( std : : list < ESM : : Pathgrid : : Point > : : iterator iter ( mPath . begin ( ) ) ; iter ! = mPath . end ( ) ; + + iter )
@ -301,18 +302,18 @@ namespace MWMechanics
// see header for the rationale
// see header for the rationale
void PathFinder : : buildSyncedPath ( const ESM : : Pathgrid : : Point & startPoint ,
void PathFinder : : buildSyncedPath ( const ESM : : Pathgrid : : Point & startPoint ,
const ESM : : Pathgrid : : Point & endPoint ,
const ESM : : Pathgrid : : Point & endPoint ,
const MWWorld : : CellStore * cell )
const MWWorld : : CellStore * cell , const MWMechanics : : PathgridGraph & pathgridGraph )
{
{
if ( mPath . size ( ) < 2 )
if ( mPath . size ( ) < 2 )
{
{
// if path has one point, then it's the destination.
// if path has one point, then it's the destination.
// don't need to worry about bad path for this case
// don't need to worry about bad path for this case
buildPath ( startPoint , endPoint , cell );
buildPath ( startPoint , endPoint , cell , pathgridGraph );
}
}
else
else
{
{
const ESM : : Pathgrid : : Point oldStart ( * getPath ( ) . begin ( ) ) ;
const ESM : : Pathgrid : : Point oldStart ( * getPath ( ) . begin ( ) ) ;
buildPath ( startPoint , endPoint , cell );
buildPath ( startPoint , endPoint , cell , pathgridGraph );
if ( mPath . size ( ) > = 2 )
if ( mPath . size ( ) > = 2 )
{
{
// if 2nd waypoint of new path == 1st waypoint of old,
// if 2nd waypoint of new path == 1st waypoint of old,