// // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2016 SuperTuxKart Team // // This program is free software; you can redistribute it and/or // modify it under the terms of the GNU General Public License // as published by the Free Software Foundation; either version 3 // of the License, or (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef HEADER_GRAPH_HPP #define HEADER_GRAPH_HPP #include "utils/no_copy.hpp" #include "utils/vec3.hpp" #include #include #include #include namespace irr { namespace scene { class ISceneNode; class IMesh; class IMeshBuffer; } namespace video { class ITexture; struct S3DVertex; class SColor; } } using namespace irr; class Quad; class RenderTarget; /** * \brief This class stores a graph of quads. It uses a 'simplified singleton' * design pattern: it has a static create function to create exactly instance, * a destroy function, and a get function (that does not have the side effect * of the 'normal singleton' design pattern to create an instance). Besides * saving on the if statement in get(), this is necessary since certain race * modes might not have a quad graph at all (e.g. arena without navmesh). So * get() returns NULL in this case, and this is tested where necessary. * \ingroup tracks */ class Graph : public NoCopy { protected: static Graph* m_graph; std::vector m_all_nodes; // ------------------------------------------------------------------------ /** Factory method to dynamic create 2d / 3d quad for drive and arena * graph. */ void createQuad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, unsigned int node_index, bool invisible, bool ai_ignore, bool is_arena, bool ignore); // ------------------------------------------------------------------------ /** Map 4 bounding box points to 4 closest graph nodes. */ void loadBoundingBoxNodes(); private: /** The 2d bounding box, used for hashing. */ Vec3 m_bb_min; Vec3 m_bb_max; /** The 4 closest graph nodes to the bounding box. */ int m_bb_nodes[4]; /** The node of the graph mesh. */ scene::ISceneNode *m_node; /** The mesh of the graph mesh. */ scene::IMesh *m_mesh; /** The actual mesh buffer storing the graph. */ scene::IMeshBuffer *m_mesh_buffer; /** Scaling for mini map. */ float m_scaling; /** The render target used for drawing the minimap. */ std::unique_ptr m_render_target; // ------------------------------------------------------------------------ void createMesh(bool show_invisible=true, bool enable_transparency=false, const video::SColor *track_color=NULL, bool invert_x_z = false, bool flatten = false); // ------------------------------------------------------------------------ void createMeshSP(bool show_invisible=true, bool enable_transparency=false, const video::SColor *track_color=NULL, bool invert_x_z = false); // ------------------------------------------------------------------------ void cleanupDebugMesh(); // ------------------------------------------------------------------------ virtual bool hasLapLine() const = 0; // ------------------------------------------------------------------------ virtual void differentNodeColor(int n, video::SColor* c) const = 0; public: static const int UNKNOWN_SECTOR; // For 2d Quad static const float MIN_HEIGHT_TESTING; static const float MAX_HEIGHT_TESTING; // ------------------------------------------------------------------------ /** Returns the one instance of this object. It is possible that there * is no instance created (e.g. arena without navmesh) so we don't assert * that an instance exist. */ static Graph* get() { return m_graph; } // ------------------------------------------------------------------------ /** Set the graph (either drive or arena graph for now). */ static void setGraph(Graph* graph) { assert(m_graph == NULL); m_graph = graph; } // setGraph // ------------------------------------------------------------------------ /** Cleans up the graph. It is possible that this function is called even * if no instance exists (e.g. arena without navmesh). So it is not an * error if there is no instance. */ static void destroy() { if (m_graph) { delete m_graph; m_graph = NULL; } } // destroy // ------------------------------------------------------------------------ Graph(); // ------------------------------------------------------------------------ virtual ~Graph(); // ------------------------------------------------------------------------ void createDebugMesh(); // ------------------------------------------------------------------------ RenderTarget* makeMiniMap(const core::dimension2du &dimension, const std::string &name, const video::SColor &fill_color, bool invert_x_z); // ------------------------------------------------------------------------ void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *out) const; // ------------------------------------------------------------------------ Quad* getQuad(unsigned int i) const { assert(i < m_all_nodes.size()); return m_all_nodes[i]; } // ------------------------------------------------------------------------ unsigned int getNumNodes() const { return (unsigned int)m_all_nodes.size(); } // ------------------------------------------------------------------------ void findRoadSector(const Vec3& XYZ, int *sector, std::vector *all_sectors = NULL, bool ignore_vertical = false) const; // ------------------------------------------------------------------------ int findOutOfRoadSector(const Vec3& xyz, const int curr_sector = UNKNOWN_SECTOR, std::vector *all_sectors = NULL, bool ignore_vertical = false) const; // ------------------------------------------------------------------------ const Vec3& getBBMin() const { return m_bb_min; } // ------------------------------------------------------------------------ const Vec3& getBBMax() const { return m_bb_max; } // ------------------------------------------------------------------------ const int* getBBNodes() const { return m_bb_nodes; } }; // Graph #endif