void PortalLayout::connectFloorMeshGraphs() { for (int i = 0; i < cellProperties.size(); ++i) { FloorMesh* floorMesh = getFloorMesh(i); if (floorMesh == NULL) continue; PathGraph* pathGraph = floorMesh->getPathGraph(); if (pathGraph == NULL) continue; Vector<PathNode*> globalNodes = pathGraph->getGlobalNodes(); for (int j = 0; j < globalNodes.size(); ++j) { PathNode* node = globalNodes.get(j); int globalID = node->getGlobalGraphNodeID(); for (int k = 0; k < cellProperties.size(); ++k) { if (i != k) { FloorMesh* newMesh = getFloorMesh(k); if (newMesh != NULL) { PathGraph* newPathGraph = newMesh->getPathGraph(); if (newPathGraph != NULL) { Vector<PathNode*> newGlobalNodes = newPathGraph->getGlobalNodes(); for (int l = 0; l < newGlobalNodes.size(); ++l) { PathNode* newNode = newGlobalNodes.get(l); int newGlobalID = newNode->getGlobalGraphNodeID(); if (globalID == newGlobalID) node->addChild(newNode); } } } } } } } }
Vector<WorldCoordinates>* PathFinderManager::findPathFromCellToWorld(const WorldCoordinates& pointA, const WorldCoordinates& pointB, Zone *zone) { Vector<WorldCoordinates>* path = new Vector<WorldCoordinates>(5, 1); if (path == NULL) return NULL; path->add(pointA); CellObject* ourCell = pointA.getCell(); ManagedReference<BuildingObject*> building = cast<BuildingObject*>( ourCell->getParent().get().get()); int ourCellID = ourCell->getCellNumber(); SharedObjectTemplate* templateObject = ourCell->getParent().get()->getObjectTemplate(); if (templateObject == NULL) { delete path; return NULL; } PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) { delete path; return NULL; } FloorMesh* sourceFloorMesh = portalLayout->getFloorMesh(ourCellID); if (sourceFloorMesh == NULL) { delete path; return NULL; } PathGraph* sourcePathGraph = sourceFloorMesh->getPathGraph(); if (sourcePathGraph == NULL) { delete path; return NULL; } FloorMesh* exteriorFloorMesh = portalLayout->getFloorMesh(0); if (exteriorFloorMesh == NULL) { delete path; return NULL; } PathGraph* exteriorPathGraph = exteriorFloorMesh->getPathGraph(); if (exteriorPathGraph == NULL) { delete path; return NULL; } // we need to move world position into model space Vector3 transformedPosition = transformToModelSpace(pointB.getPoint(), building); //find exit node in our cell //PathNode* exitNode = sourcePathGraph->findNearestNode(pointA.getPoint()); TriangleNode* nearestTargetNodeTriangle = CollisionManager::getTriangle(pointA.getPoint(), sourceFloorMesh); if (nearestTargetNodeTriangle == NULL) { delete path; return NULL; } PathNode* exitNode = CollisionManager::findNearestPathNode(nearestTargetNodeTriangle, sourceFloorMesh, transformedPosition);//targetPathGraph->findNearestNode(pointB.getPoint()); if (exitNode == NULL) { delete path; return NULL; } //find exterior node PathNode* exteriorNode = exteriorPathGraph->findNearestGlobalNode(transformedPosition); if (exteriorNode == NULL) { delete path; return NULL; } //find path to the exit Vector<PathNode*>* exitPath = portalLayout->getPath(exitNode, exteriorNode); if (exitPath == NULL) { error("exitPath == NULL"); delete path; return NULL; } //find triangle path to exitNode Vector<Triangle*>* trianglePath = NULL; int res = getFloorPath(pointA.getPoint(), exitNode->getPosition(), sourceFloorMesh, trianglePath); if (res != -1 && trianglePath != NULL) addTriangleNodeEdges(pointA.getPoint(), exitNode->getPosition(), trianglePath, path, ourCell); if (trianglePath != NULL) delete trianglePath; path->add(WorldCoordinates(exitNode->getPosition(), ourCell)); //populate cell traversing for (int i = 0; i < exitPath->size(); ++i) { PathNode* pathNode = exitPath->get(i); PathGraph* pathGraph = pathNode->getPathGraph(); FloorMesh* floorMesh = pathGraph->getFloorMesh(); int cellID = floorMesh->getCellID(); if (cellID == 0) { // we are outside WorldCoordinates coord(pathNode->getPosition(), ourCell); path->add(WorldCoordinates(coord.getWorldPosition(), NULL)); } else { // we are inside the building CellObject* pathCell = building->getCell(cellID); path->add(WorldCoordinates(pathNode->getPosition(), pathCell)); } } delete exitPath; exitPath = NULL; if (path->size()) { Vector<WorldCoordinates>* newPath = findPathFromWorldToWorld(path->get(path->size()-1), pointB, zone); if (newPath) { path->addAll(*newPath); delete newPath; } } else path->add(pointB); return path; }
Vector<WorldCoordinates>* PathFinderManager::findPathFromWorldToCell(const WorldCoordinates& pointA, const WorldCoordinates& pointB, Zone *zone) { CellObject* targetCell = pointB.getCell(); if (targetCell == NULL) return NULL; ManagedReference<BuildingObject*> building = dynamic_cast<BuildingObject*>(targetCell->getParent().get().get()); if (building == NULL) { error("building == NULL in PathFinderManager::findPathFromWorldToCell"); return NULL; } SharedObjectTemplate* templateObject = building->getObjectTemplate(); if (templateObject == NULL) return NULL; PortalLayout* portalLayout = templateObject->getPortalLayout(); if (portalLayout == NULL) return NULL; //find nearest entrance FloorMesh* exteriorFloorMesh = portalLayout->getFloorMesh(0); // get outside layout if (exteriorFloorMesh == NULL) return NULL; PathGraph* exteriorPathGraph = exteriorFloorMesh->getPathGraph(); FloorMesh* targetFloorMesh = portalLayout->getFloorMesh(targetCell->getCellNumber()); PathGraph* targetPathGraph = targetFloorMesh->getPathGraph(); Vector<WorldCoordinates>* path = new Vector<WorldCoordinates>(5, 1); path->add(pointA); Vector3 transformedPosition = transformToModelSpace(pointA.getPoint(), building); PathNode* nearestEntranceNode = exteriorPathGraph->findNearestNode(transformedPosition); if (nearestEntranceNode == NULL) { error("NULL entrance node for building " + templateObject->getFullTemplateString()); delete path; return NULL; } //PathNode* nearestTargetNode = targetPathGraph->findNearestNode(pointB.getPoint()); TriangleNode* nearestTargetNodeTriangle = CollisionManager::getTriangle(pointB.getPoint(), targetFloorMesh); if (nearestTargetNodeTriangle == NULL) { delete path; return NULL; } PathNode* nearestTargetNode = CollisionManager::findNearestPathNode(nearestTargetNodeTriangle, targetFloorMesh, pointB.getPoint());//targetPathGraph->findNearestNode(pointB.getPoint()); if (nearestTargetNode == NULL) { delete path; return NULL; } /*if (nearestEntranceNode == nearestTargetNode) info("nearestEntranceNode == nearestTargetNode", true);*/ //find graph from outside to appropriate cell Vector<PathNode*>* pathToCell = portalLayout->getPath(nearestEntranceNode, nearestTargetNode); if (pathToCell == NULL) { error("pathToCell = portalLayout->getPath(nearestEntranceNode, nearestTargetNode); == NULL"); delete path; return NULL; } for (int i = 0; i < pathToCell->size(); ++i) { PathNode* pathNode = pathToCell->get(i); PathGraph* pathGraph = pathNode->getPathGraph(); FloorMesh* floorMesh = pathGraph->getFloorMesh(); int cellID = floorMesh->getCellID(); //info("cellID:" + String::valueOf(cellID), true); if (cellID == 0) { // we are still outside WorldCoordinates coord(pathNode->getPosition(), targetCell); path->add(WorldCoordinates(coord.getWorldPosition(), NULL)); } else { // we are inside the building CellObject* pathCell = building->getCell(cellID); path->add(WorldCoordinates(pathNode->getPosition(), pathCell)); if (i == pathToCell->size() - 1) if (pathCell != targetCell) { error("final cell not target cell"); } } } delete pathToCell; pathToCell = NULL; // path from cell path node to destination point Vector<Triangle*>* trianglePath = NULL; int res = getFloorPath(path->get(path->size() - 1).getPoint(), pointB.getPoint(), targetFloorMesh, trianglePath); if (res != -1 && trianglePath != NULL) addTriangleNodeEdges(path->get(path->size() - 1).getPoint(), pointB.getPoint(), trianglePath, path, targetCell); if (trianglePath != NULL) delete trianglePath; path->add(pointB); return path; }