Пример #1
0
void Tile::initFullPolygon(int mazeWidth, int mazeHeight) {

    Meters halfWallWidth = Meters(P()->wallWidth()) / 2.0;
    Meters tileLength = Meters(P()->wallLength() + P()->wallWidth());
    Cartesian lowerLeftPoint(tileLength * getX() - halfWallWidth * (getX() == 0 ? 1 : 0),
                             tileLength * getY() - halfWallWidth * (getY() == 0 ? 1 : 0));
    Cartesian upperRightPoint(tileLength * (getX() + 1) + halfWallWidth * (getX() == mazeWidth - 1 ? 1 : 0),
                              tileLength * (getY() + 1) + halfWallWidth * (getY() == mazeHeight - 1 ? 1 : 0));
    Cartesian lowerRightPoint(upperRightPoint.getX(), lowerLeftPoint.getY());
    Cartesian upperLeftPoint(lowerLeftPoint.getX(), upperRightPoint.getY());
    m_fullPolygon = Polygon({lowerLeftPoint, upperLeftPoint, upperRightPoint, lowerRightPoint});
}
Пример #2
0
    void testNavMesh()
    {
        Event::EventManager m;
        Event::ListenerRegister & reg = m.getListenerRegister();

        AI::NavMesh::NavMeshGenerationEngine navMeshGenerationEngine;
        navMeshGenerationEngine.registerListeners(reg);

        vector<Threading::ThreadableInterface*> threadables;
        threadables.push_back(&m);

        Threading::Thread eventThread(threadables, 2);
        eventThread.start();

        vector<Threading::ThreadableInterface*> threadables2;
        threadables2.push_back(&navMeshGenerationEngine);

        Threading::Thread generationThread(threadables2, 2);
        generationThread.start();


        Event::EventQueue & queue = m.getEventQueue();

        Geometry::Vec2Df lowerLeftPoint(0.f, 0.f);
        Geometry::Vec2Df upperRightPoint(128.f,128.f);
        queue << new AI::NavMesh::AreaCreatedEvent(lowerLeftPoint, upperRightPoint);

        // Create some obtacles
        queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(110.f,110.f), Geometry::Vec2Df(119.f,119.f)));
        queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(60.f,60.f), Geometry::Vec2Df(70.f,70.f)));
        queue << new AI::NavMesh::ObstacleAddedEvent(AI::NavMesh::Obstacle(Geometry::Vec2Df(10.f,10.f), Geometry::Vec2Df(15.f,15.f)));

        queue << new AI::NavMesh::NavMeshOverEvent(lowerLeftPoint,upperRightPoint);
        int k = 0;
        while (k < 20)
        {
            k++;
            Threading::sleep(Core::makeDurationMillis(200));
        }

        eventThread.stop();
        generationThread.stop();

        // Draw navMesh
        Test::SvgDrawer drawer(256,256);
        const AI::NavMesh::NavMeshContainer::NavMeshesList& navMeshes = navMeshGenerationEngine.getNavMeshes().getNavMeshesList();

        if(navMeshes.size() > 0)
        {
            AI::NavMesh::NavMesh* navMesh = navMeshes.at(0);
            // Path finding
            const Graph::PlanarGraph& graph = navMesh->getGraph();
            const Graph::PlanarNode& startNode = graph.getNodes().front();
            const Graph::PlanarNode& goalNode = graph.getNodes().back();
            Graph::PlanarGraph::NodeCollection path;
            Graph::BasicAStar(graph, startNode, goalNode, path);

            drawNavMesh(*navMesh, drawer);
            //drawPath(path, drawer);
            //std::cout << drawer.getContent().str();
        }

        // Test AI
        // Create entity
        Threading::ConcurrentRessource<Ecs::World> w(
            new Ecs::World(m.getEventQueue())
        );

        Ecs::Entity e1, e2;

        {
            Threading::ConcurrentWriter<Ecs::World> world = w.getWriter();
            e1 = createNewCharacter(
                world,
                Geometry::Vec3Df(0.0,0.0,0.0),
                Geometry::Vec3Df(0.0,0.0,0.0),
                true,
                queue
            );
            e2 = createNewCharacter(
                world,
                Geometry::Vec3Df(80.0,80.0,0.0),
                Geometry::Vec3Df(0.0,0.0,0.0),
                false,
                queue
            );
        }

        // Create thrads for systems
        AI::AiSystem aiSystem(w);
        AI::Sensor::SensorSystem sensorSystem(w);
        Physics::MovementSystem movementSystem(w, m.getEventQueue());
        AI::Subsystem::TargetingSystem targetingSystem(w);

        vector<Threading::ThreadableInterface*> aiSystemVector;
        vector<Threading::ThreadableInterface*> movementSystemVector;
        vector<Threading::ThreadableInterface*> targetingSystemVector;
        vector<Threading::ThreadableInterface*> sensorSystemVector;

        aiSystemVector.push_back(&sensorSystem);
        aiSystemVector.push_back(&targetingSystem);
        aiSystemVector.push_back(&aiSystem);
        movementSystemVector.push_back(&movementSystem);

        Threading::Thread aiThread(aiSystemVector, 20);
        //Threading::Thread sensorThread(sensorSystemVector, 5);
        //Threading::Thread targetingThread(targetingSystemVector, 5);

        Threading::Thread movementThread(movementSystemVector, 20);

        // Get the position component of e1
        Ecs::ComponentGroup::ComponentTypeCollection types;
        types.insert(Geometry::PositionComponent::Type);

        Ecs::ComponentGroup prototype(types);
        Ecs::ComponentGroup componentsE1 = w.getWriter()->getEntityComponents(
            e1,
            prototype
        );

        Ecs::ComponentGroup componentsE2 =
            w.getWriter()->getEntityComponents(e2, prototype);


        types.insert(AI::Subsystem::TargetingComponent::Type);
        Ecs::ComponentGroup components =
            w.getWriter()->getEntityComponents(e1, Ecs::ComponentGroup(types));

        //sensorThread.start();
        //targetingThread.start();
        aiThread.start();
        movementThread.start();
        std::vector<Geometry::Vec2Df> positions;
        positions.push_back(Geometry::Vec2Df(0,0));
        /*
        bool b = true;
        while(b)
        {
            Geometry::Vec2Df lastPos = positions.back();
            Geometry::Vec3Df pos = positionComponentE1.getPosition();
            if((pos -positionComponentE2.getPosition()).getLength() < 2.f)
                b = false;
            Threading::sleep(0,20);
            if(pos.getX() != lastPos.getX() && pos.getY() != lastPos.getY())
                positions.push_back(Geometry::Vec2Df(pos.getX(), pos.getY()));

        }

        for (int j =0; j < 20; j++)
        {
            Threading::sleep(0,100);
        }
        */

        std::vector<Geometry::Vec2Df> positionsE2;
        std::vector<Geometry::Vec2Df> targets;

        // Taget is moving slowly to the upper-right corner of the navMesh
        Geometry::Vec3Df offset(0.1, -0.2, 0.0);
        for (int j =0; j < 20*20; j++)
        {
            Threading::sleep(Core::makeDurationMillis(50));

            ConcurrentReader<Geometry::PositionComponent> positionComponentE1 =
                getConcurrentReader<Ecs::Component, Geometry::PositionComponent>(
                    componentsE1.getComponent(Geometry::PositionComponent::Type)
                );

            ConcurrentWriter<Geometry::PositionComponent> positionComponentE2 =
                getConcurrentWriter<Ecs::Component, Geometry::PositionComponent>(
                    componentsE2.getComponent(Geometry::PositionComponent::Type)
                );

            ConcurrentReader<AI::Subsystem::TargetingComponent> targetingComponent =
                getConcurrentReader<Ecs::Component, AI::Subsystem::TargetingComponent>(
                    components.getComponent(AI::Subsystem::TargetingComponent::Type)
                );

            Geometry::Vec3Df pos1 = positionComponentE1->getPosition();
            Geometry::Vec3Df pos2 = positionComponentE2->getPosition();
            Geometry::Vec3Df target = targetingComponent->getTargetPosition();

            Geometry::Vec3Df newPos = pos2 + offset;
            positionComponentE2->setPosition(newPos);
            positionsE2.push_back(Geometry::Vec2Df(newPos.getX(), newPos.getY()));
            positions.push_back(Geometry::Vec2Df(pos1.getX(), pos1.getY()));
            targets.push_back(Geometry::Vec2Df(target.getX(), target.getY()));


        }

        aiThread.stop();
        //sensorThread.stop();
        //targetingThread.stop();
        movementThread.stop();

        if(navMeshes.size() > 0)
        {
            ConcurrentWriter<Geometry::PositionComponent> positionComponentE2 =
                getConcurrentWriter<Ecs::Component, Geometry::PositionComponent>(
                    componentsE2.getComponent(Geometry::PositionComponent::Type)
                );

            AI::NavMesh::NavMesh* navMesh = navMeshes.at(0);
            // Path finding
            const Graph::PlanarGraph& graph = navMesh->getGraph();
            Geometry::Vec3Df pos2 = positionComponentE2->getPosition();

            Graph::PlanarNode startNode; navMesh->getNode( Geometry::Vec2Df(0, 0), startNode);
            Graph::PlanarNode goalNode; navMesh->getNode( Geometry::Vec2Df(pos2.getX(), pos2.getY()), goalNode);
            Graph::PlanarGraph::NodeCollection path;
            Graph::BasicAStar(graph, startNode, goalNode, path);

            drawPath(path, drawer);
        }

        for(unsigned int i = 0; i < positions.size(); i++)
        {
            Geometry::Vec2Df pos = positions[i];
            drawer.drawCircle(pos.getX(), pos.getY(), 1, "green");
        }
        for(unsigned int i = 0; i < positionsE2.size(); i++)
        {
            Geometry::Vec2Df pos = positionsE2[i];
            drawer.drawCircle(pos.getX(), pos.getY(), 1, "orange");

            Geometry::Vec2Df target = targets[i];
            drawer.drawCircle(target.getX(), target.getY(), 1, "purple");
        }
        drawer.end();

        std::cout << drawer.getContent().str();

    }