コード例 #1
0
ファイル: arena_graph.cpp プロジェクト: devnexen/stk-code
// -----------------------------------------------------------------------------
ArenaGraph::ArenaGraph(const std::string &navmesh, const XMLNode *node)
          : Graph()
{
    loadNavmesh(navmesh);
    buildGraph();
    // Compute shortest distance from all nodes
    for (unsigned int i = 0; i < getNumNodes(); i++)
        computeDijkstra(i);

    setNearbyNodesOfAllNodes();
    if (node && race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
        loadGoalNodes(node);

    loadBoundingBoxNodes();

}   // ArenaGraph
コード例 #2
0
ファイル: drive_graph.cpp プロジェクト: Benau/stk-code
/** Loads a drive graph from a file.
 *  \param filename Name of the quad file to load.
 *  \param filename Name of the graph file to load.
 */
void DriveGraph::load(const std::string &quad_file_name,
                      const std::string &filename)
{
    XMLNode *quad = file_manager->createXMLTree(quad_file_name);
    if (!quad || quad->getName() != "quads")
    {
        Log::error("DriveGraph : Quad xml '%s' not found.", filename.c_str());
        delete quad;
        return;
    }

    // Each quad is part of the graph exactly once now.
    for (unsigned int i = 0; i < quad->getNumNodes(); i++)
    {
        const XMLNode *xml_node = quad->getNode(i);
        if (xml_node->getName() != "quad")
        {
            Log::warn("DriveGraph: Unsupported node type '%s' found in '%s' - ignored.",
                xml_node->getName().c_str(), filename.c_str());
            continue;
        }

        // Note that it's not easy to do the reading of the parameters here
        // in quad, since the specification in the xml can contain references
        // to previous points. E.g.:
        // <quad p0="40:3" p1="40:2" p2="25.396030 0.770338 64.796539" ...
        Vec3 p0, p1, p2, p3;
        getPoint(xml_node, "p0", &p0);
        getPoint(xml_node, "p1", &p1);
        getPoint(xml_node, "p2", &p2);
        getPoint(xml_node, "p3", &p3);
        bool invisible = false;
        xml_node->get("invisible", &invisible);
        bool ai_ignore = false;
        xml_node->get("ai-ignore", &ai_ignore);

        bool ignored = false;
        std::string direction;
        xml_node->get("direction", &direction);
        if (direction == "forward" && race_manager->getReverseTrack())
        {
            ignored = true;
            invisible = true;
            ai_ignore = true;
        }
        else if (direction == "reverse" && !race_manager->getReverseTrack())
        {
            ignored = true;
            invisible = true;
            ai_ignore = true;
        }

        createQuad(p0, p1, p2, p3, m_all_nodes.size(), invisible, ai_ignore,
                   false/*is_arena*/, ignored);
    }
    delete quad;

    const XMLNode *xml = file_manager->createXMLTree(filename);

    if(!xml)
    {
        // No graph file exist, assume a default loop X -> X+1
        // Set the default loop:
        setDefaultSuccessors();
        computeDirectionData();

        if (m_all_nodes.size() > 0)
        {
            m_lap_length = getNode(m_all_nodes.size()-1)->getDistanceFromStart()
                         + getNode(m_all_nodes.size()-1)->getDistanceToSuccessor(0);
        }
        else
        {
            Log::error("DriveGraph", "No node in driveline graph.");
            m_lap_length = 10.0f;
        }

        return;
    }

    // The graph file exist, so read it in. The graph file must first contain
    // the node definitions, before the edges can be set.
    for(unsigned int node_index=0; node_index<xml->getNumNodes(); node_index++)
    {
        const XMLNode *xml_node = xml->getNode(node_index);
        // Load the definition of edges between the graph nodes:
        // -----------------------------------------------------
        if (xml_node->getName() == "node-list")
        {
            // Each quad is part of the graph exactly once now.
            unsigned int to = 0;
            xml_node->get("to-quad", &to);
            assert(to + 1 == m_all_nodes.size());
            continue;
        }
        else if(xml_node->getName()=="edge-loop")
        {
            // A closed loop:
            unsigned int from, to;
            xml_node->get("from", &from);
            xml_node->get("to", &to);
            for(unsigned int i=from; i<=to; i++)
            {
                assert(i!=to ? i+1 : from <m_all_nodes.size());
                addSuccessor(i,(i!=to ? i+1 : from));
                //~ m_all_nodes[i]->addSuccessor(i!=to ? i+1 : from);
            }
        }
        else if(xml_node->getName()=="edge-line")
        {
            // A line:
            unsigned int from, to;
            xml_node->get("from", &from);
            xml_node->get("to", &to);
            for(unsigned int i=from; i<to; i++)
            {
                addSuccessor(i,i+1);
                //~ m_all_nodes[i]->addSuccessor(i+1);
            }
        }
        else if(xml_node->getName()=="edge")
        {
            // Adds a single edge to the graph:
            unsigned int from, to;
            xml_node->get("from", &from);
            xml_node->get("to", &to);
            assert(to<m_all_nodes.size());
            addSuccessor(from,to);
            //~ m_all_nodes[from]->addSuccessor(to);
        }   // edge
        else
        {
            Log::error("DriveGraph", "Incorrect specification in '%s': '%s' ignored.",
                    filename.c_str(), xml_node->getName().c_str());
            continue;
        }   // incorrect specification
    }
    delete xml;

    setDefaultSuccessors();
    computeDistanceFromStart(getStartNode(), 0.0f);
    computeDirectionData();

    // Define the track length as the maximum at the end of a quad
    // (i.e. distance_from_start + length till successor 0).
    m_lap_length = -1;
    for(unsigned int i=0; i<m_all_nodes.size(); i++)
    {
        float l = getNode(i)->getDistanceFromStart()
                + getNode(i)->getDistanceToSuccessor(0);
        if(l > m_lap_length)
            m_lap_length = l;
    }

    loadBoundingBoxNodes();

}   // load