Added serverPathfinding library

This commit is contained in:
Anonymous
2014-01-15 09:54:09 -07:00
parent 7d149b2784
commit cd99b53a31
43 changed files with 5888 additions and 2 deletions
@@ -0,0 +1,558 @@
// ======================================================================
//
// CityPathNode.cpp
// copyright (c) 2001 Sony Online Entertainment
//
// ======================================================================
#include "serverPathfinding/FirstServerPathfinding.h"
#include "serverPathfinding/CityPathNode.h"
#include "serverGame/ServerObject.h"
#include "serverGame/ServerWorld.h"
#include "serverPathfinding/CityPathGraph.h"
#include "serverPathfinding/ServerPathfindingConstants.h"
#include "sharedCollision/CollisionWorld.h"
#include "sharedCollision/CollisionUtils.h"
#include "sharedFoundation/DynamicVariable.h"
#include "sharedFoundation/DynamicVariableList.h"
#include "sharedFoundation/NetworkId.h"
#include "sharedObject/CellProperty.h"
#include "sharedObject/NetworkIdManager.h"
#include "sharedPathfinding/PathEdge.h"
#include "sharedTerrain/TerrainObject.h"
#include <vector>
typedef std::vector<NetworkId> NetworkIdList;
namespace CityPathNodeNamespace
{
int gs_debugIdCounter = 0;
};
using namespace CityPathNodeNamespace;
// ======================================================================
CityPathNode::CityPathNode ( Vector const & position_w, NetworkId const & sourceId )
: DynamicPathNode(position_w),
m_source(sourceId),
m_creator(),
m_relativePosition_o(Vector::zero),
m_spatialHandle(NULL),
m_debugId( gs_debugIdCounter++ )
{
snapToTerrain();
}
// ----------
CityPathNode::CityPathNode ( Vector const & position_w, NetworkId const & sourceId, NetworkId const & creatorId )
: DynamicPathNode(position_w),
m_source(sourceId),
m_creator(creatorId),
m_relativePosition_o(Vector::zero),
m_spatialHandle(NULL),
m_debugId( gs_debugIdCounter++ )
{
updateRelativePosition();
snapToTerrain();
}
// ----------
CityPathNode::~CityPathNode()
{
}
// ----------------------------------------------------------------------
void CityPathNode::clearEdges ( void )
{
ServerObject * sourceObject = getSourceObject();
if(sourceObject)
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES);
}
DynamicPathNode::clearEdges();
}
// ----------------------------------------------------------------------
CellProperty const * CityPathNode::getCell ( void ) const
{
ServerObject const * sourceObject = getSourceObject();
if(sourceObject)
{
return sourceObject->getParentCell();
}
else
{
return CellProperty::getWorldCellProperty();
}
}
// ----------------------------------------------------------------------
Vector CityPathNode::getPosition_w ( void ) const
{
return CollisionUtils::transformToWorld(getCell(),getPosition_p());
}
// ----------------------------------------------------------------------
void CityPathNode::setPosition_p ( Vector const & newPosition_p )
{
DynamicPathNode::setPosition_p(newPosition_p);
updateRelativePosition();
snapToTerrain();
}
// ----------------------------------------------------------------------
void CityPathNode::setPosition_w ( Vector const & newPosition_w )
{
Vector newPosition_p = CollisionUtils::transformFromWorld(newPosition_w,getCell());
setPosition_p(newPosition_p);
}
// ----------------------------------------------------------------------
void CityPathNode::updateRelativePosition ( void )
{
ServerObject const * sourceObject = getSourceObject();
ServerObject const * creatorObject = getCreatorObject();
if(sourceObject && creatorObject)
{
m_relativePosition_o = creatorObject->rotateTranslate_w2o(sourceObject->getPosition_w());
}
}
// ----------------------------------------------------------------------
void CityPathNode::loadFromObjvars ( void )
{
loadInfoFromObjvars();
loadEdgesFromObjvars();
}
// ----------------------------------------------------------------------
void CityPathNode::loadInfoFromObjvars ( void )
{
ServerObject const * sourceObject = getSourceObject();
if(sourceObject == NULL) return;
const DynamicVariableList & objvars = sourceObject->getObjVars();
// ----------
m_creator = NetworkId::cms_invalid;
m_key = -1;
m_name.clear();
m_type = PNT_Invalid;
NetworkId creatorId;
if (objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR,creatorId))
m_creator = creatorId;
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_KEY, m_key);
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_NAME, m_name);
int typeInt;
if(objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE, typeInt))
m_type = static_cast<PathNodeType>(typeInt);
}
// ----------------------------------------------------------------------
void CityPathNode::loadEdgesFromObjvars ( void )
{
ServerObject const * sourceObject = getSourceObject();
if(sourceObject == NULL) return;
DynamicVariableList const & objvars = sourceObject->getObjVars();
// ----------
NetworkIdList idList;
if(objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList))
{
int idCount = idList.size();
for(int i = 0; i < idCount; i++)
{
ServerObject * serverObject = ServerWorld::findObjectByNetworkId( idList[i] );
if(serverObject == NULL) continue;
CityPathNode * otherNode = _getGraph()->findNodeForObject(*serverObject);
if(otherNode == NULL) continue;
addEdge(otherNode->getIndex());
otherNode->addEdge(getIndex());
}
}
else
{
DEBUG_WARNING(true,("CityPathNode::loadEdgesFromObjvars - Source object has no edge list objvar\n"));
}
}
// ----------------------------------------------------------------------
void CityPathNode::saveToObjvars ( void )
{
saveInfoToObjvars();
saveEdgesToObjvars();
}
// ----------------------------------------------------------------------
void CityPathNode::saveInfoToObjvars ( void )
{
ServerObject * sourceObject = getSourceObject();
if(sourceObject == NULL) return;
// ----------
NetworkId const & creatorId = getCreatorId();
if(creatorId.isValid())
{
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR, creatorId);
}
else
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_CREATOR);
}
if(m_key != -1)
{
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_KEY,static_cast<int>(m_key));
}
else
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_KEY);
}
if(!m_name.empty())
{
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_NAME,m_name);
}
else
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_NAME);
}
if(m_type != PNT_Invalid)
{
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE,static_cast<int>(m_type));
}
else
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE);
}
}
// ----------------------------------------------------------------------
void CityPathNode::saveEdgesToObjvars ( void )
{
ServerObject * sourceObject = getSourceObject();
// ----------
NetworkIdList idList;
int edgeCount = getEdgeCount();
for(int i = 0; i < edgeCount; i++)
{
int neighborIndex = getNeighbor(i);
CityPathNode * neighborNode = _getGraph()->_getNode(neighborIndex);
if(neighborNode == NULL) continue;
NetworkId const & neighborSourceId = neighborNode->getSourceId();
if(neighborSourceId.isValid())
{
idList.push_back(neighborSourceId);
}
}
if(!idList.empty())
{
sourceObject->setObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList);
}
else
{
sourceObject->removeObjVarItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES);
}
}
// ----------------------------------------------------------------------
void CityPathNode::saveNeighbors ( void )
{
int edgeCount = getEdgeCount();
for(int i = 0; i < edgeCount; i++)
{
int neighborIndex = getNeighbor(i);
CityPathNode * neighborNode = _getGraph()->_getNode(neighborIndex);
if(neighborNode == NULL) continue;
neighborNode->saveToObjvars();
}
}
// ----------------------------------------------------------------------
void CityPathNode::saveAllData ( void )
{
saveToObjvars();
saveNeighbors();
}
// ----------------------------------------------------------------------
ServerObject * CityPathNode::getSourceObject ( void )
{
return safe_cast<ServerObject*>(m_source.getObject());
}
ServerObject const * CityPathNode::getSourceObject ( void ) const
{
return safe_cast<ServerObject const *>(m_source.getObject());
}
NetworkId const & CityPathNode::getSourceId ( void ) const
{
return m_source;
}
// ----------
ServerObject * CityPathNode::getCreatorObject ( void )
{
return safe_cast<ServerObject *>(m_creator.getObject());
}
ServerObject const * CityPathNode::getCreatorObject ( void ) const
{
return safe_cast<ServerObject const *>(m_creator.getObject());
}
NetworkId const & CityPathNode::getCreatorId ( void ) const
{
return m_creator;
}
// ----------
void CityPathNode::setCreator ( NetworkId const & creatorId )
{
m_creator = creatorId;
updateRelativePosition();
}
// ----------------------------------------------------------------------
CityPathGraph * CityPathNode::_getGraph ( void )
{
return safe_cast<CityPathGraph *>(getGraph());
}
CityPathGraph const * CityPathNode::_getGraph ( void ) const
{
return safe_cast<CityPathGraph const *>(getGraph());
}
// ----------------------------------------------------------------------
int CityPathNode::getDebugId ( void ) const
{
return m_debugId;
}
// ----------------------------------------------------------------------
bool CityPathNode::sanityCheck ( bool doWarnings ) const
{
UNREF(doWarnings); //for release build
int insaneCount = 0;
int edgeCount = getEdgeCount();
int i;
for(i = 0; i < edgeCount; i++)
{
int neighborIndex = getNeighbor(i);
CityPathNode const * neighborNode = _getGraph()->_getNode(neighborIndex);
if(neighborNode == NULL)
{
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has an edge to a non-existent node\n"));
insaneCount++;
}
if(!neighborNode->hasEdge(getIndex()))
{
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a one-way edge to another node\n"));
insaneCount++;
}
}
NetworkIdList idList;
ServerObject const * sourceObject = getSourceObject();
if(sourceObject && sourceObject->getObjVars().getItem(OBJVAR_PATHFINDING_WAYPOINT_EDGES,idList))
{
int idCount = idList.size();
for(int i = 0; i < idCount; i++)
{
if(!hasEdgeTo(idList[i]))
{
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a link in its objvar list that's not present in the edge list\n"));
insaneCount++;
}
}
}
if(getType() != PNT_CityBuilding)
{
for(i = 0; i < edgeCount; i++)
{
CityPathNode const * nodeA = this;
CityPathNode const * nodeB = _getGraph()->_getNode(getNeighbor(i));
if(nodeB == NULL) continue;
if(nodeB->getType() == PNT_CityBuilding) continue;
Vector posA = nodeA->getPosition_p();
Vector posB = nodeB->getPosition_p();
bool moveAB = (CollisionWorld::canMove( CellProperty::getWorldCellProperty(), posA, posB, 0.0f, true, true, false ) == CMR_MoveOK);
if(!moveAB)
{
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has a link that's not traversable\n"));
insaneCount++;
}
}
}
int redundantCount = markRedundantEdges();
if(redundantCount > 0)
{
DEBUG_WARNING(doWarnings,("CityPathNode::sanityCheck - Node has %d redundant edges\n",redundantCount));
insaneCount++;
}
return insaneCount == 0;
}
// ----------------------------------------------------------------------
// Reload the parts of the node data that are set up by designers
void CityPathNode::reload ( void )
{
ServerObject const * sourceObject = getSourceObject();
if(sourceObject == NULL) return;
// ----------
DynamicVariableList const & objvars = sourceObject->getObjVars();
// ----------
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_NAME,m_name);
int pathNodeTypeInt;
objvars.getItem(OBJVAR_PATHFINDING_WAYPOINT_TYPE,pathNodeTypeInt);
m_type = static_cast<PathNodeType>(pathNodeTypeInt);
}
// ----------------------------------------------------------------------
bool CityPathNode::hasEdgeTo ( NetworkId const & neighborId ) const
{
if(!neighborId.isValid()) return false;
int edgeCount = getEdgeCount();
for(int i = 0; i < edgeCount; i++)
{
int neighborIndex = getNeighbor(i);
CityPathNode const * neighborNode = _getGraph()->_getNode(neighborIndex);
if(neighborNode == NULL) continue;
if(neighborNode->getSourceId() == neighborId) return true;
}
return false;
}
// ----------------------------------------------------------------------
void CityPathNode::snapToTerrain ( void )
{
CellProperty const * cell = getCell();
if((cell == NULL) || (cell == CellProperty::getWorldCellProperty()))
{
Vector pos_w = getPosition_w();
float height = 0.0f;
if(TerrainObject::getConstInstance ()->getHeightForceChunkCreation(pos_w,height))
{
if(height > pos_w.y)
{
pos_w.y = height;
Vector pos_p = CollisionUtils::transformFromWorld(pos_w,getCell());
DynamicPathNode::setPosition_p(pos_p);
}
}
}
}
// ----------------------------------------------------------------------