/* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #pragma once #include #include #include #include #include #include "parser.h" #include "openglgeometrybank.h" #include "scenenode.h" #include "track.h" #include "traction.h" namespace scene { int const EU07_CELLSIZE = 250; int const EU07_SECTIONSIZE = 1000; int const EU07_REGIONSIDESECTIONCOUNT = 500; // number of sections along a side of square region struct scratch_data { std::stack location_offset; glm::vec3 location_rotation; struct trainset_data { std::string name; std::string track; float offset { 0.f }; float velocity { 0.f }; std::vector vehicles; std::vector couplings; TDynamicObject * driver { nullptr }; bool is_open { false }; } trainset; bool initialized { false }; }; // basic element of rudimentary partitioning scheme for the section. fixed size, no further subdivision // TBD, TODO: replace with quadtree scheme? class basic_cell { friend class opengl_renderer; public: // methods // legacy method, updates sounds and polls event launchers within radius around specified point void update(); // legacy method, finds and assigns traction piece to specified pantograph of provided vehicle void update_traction( TDynamicObject *Vehicle, int const Pantographindex ); // legacy method, triggers radio-stop procedure for all vehicles located on paths in the cell void radio_stop(); // legacy method, adds specified path to the list of pieces undergoing state change bool RaTrackAnimAdd( TTrack *Track ); // legacy method, updates geometry for pieces in the animation list void RaAnimate( unsigned int const Framestamp ); // adds provided shape to the cell void insert( shape_node Shape ); // adds provided lines to the cell void insert( lines_node Lines ); // adds provided path to the cell void insert( TTrack *Path ); // adds provided path to the cell void insert( TTraction *Traction ); // adds provided model instance to the cell void insert( TAnimModel *Instance ); // adds provided sound instance to the cell void insert( TTextSound *Sound ); // adds provided event launcher to the cell void insert( TEventLauncher *Launcher ); // registers provided path in the lookup directory of the cell void register_end( TTrack *Path ); // registers provided traction piece in the lookup directory of the cell void register_end( TTraction *Traction ); // find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance std::tuple find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ); // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint std::tuple find( glm::dvec3 const &Point, TTrack const *Exclude ); // finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint std::tuple find( glm::dvec3 const &Point, TTraction const *Exclude ); // finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece std::tuple find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ); // sets center point of the cell void center( glm::dvec3 Center ); // generates renderable version of held non-instanced geometry in specified geometry bank void create_geometry( geometrybank_handle const &Bank ); // provides access to bounding area data bounding_area const & area() const { return m_area; } private: // types using shapenode_sequence = std::vector; using linesnode_sequence = std::vector; using path_sequence = std::vector; using traction_sequence = std::vector; using instance_sequence = std::vector; using sound_sequence = std::vector; using eventlauncher_sequence = std::vector; // members scene::bounding_area m_area { glm::dvec3(), static_cast( 0.5 * M_SQRT2 * EU07_CELLSIZE ) }; bool m_active { false }; // whether the cell holds any actual data // content shapenode_sequence m_shapesopaque; // opaque pieces of geometry shapenode_sequence m_shapestranslucent; // translucent pieces of geometry linesnode_sequence m_lines; path_sequence m_paths; // path pieces instance_sequence m_instancesopaque; instance_sequence m_instancetranslucent; traction_sequence m_traction; sound_sequence m_sounds; eventlauncher_sequence m_eventlaunchers; // search helpers struct lookup_data { path_sequence paths; traction_sequence traction; } m_directories; // animation of owned items (legacy code, clean up along with track refactoring) bool m_geometrycreated { false }; unsigned int m_framestamp { 0 }; // id of last rendered gfx frame TTrack *tTrackAnim = nullptr; // obiekty do przeliczenia animacji }; // basic scene partitioning structure, holds terrain geometry and collection of cells class basic_section { friend class opengl_renderer; public: // methods // legacy method, updates sounds and polls event launchers within radius around specified point void update( glm::dvec3 const &Location, float const Radius ); // legacy method, finds and assigns traction piece to specified pantograph of provided vehicle void update_traction( TDynamicObject *Vehicle, int const Pantographindex ); // legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location void radio_stop( glm::dvec3 const &Location, float const Radius ); // adds provided shape to the section void insert( shape_node Shape ); // adds provided lines to the section void insert( lines_node Lines ); // adds provided node to the section template void insert( Type_ *Node ) { auto &targetcell { cell( Node->location() ) }; targetcell.insert( Node ); // some node types can extend bounding area of the target cell m_area.radius = std::max( m_area.radius, glm::length( m_area.center - targetcell.area().center ) + targetcell.area().radius ); } // registers provided node in the lookup directory of the section enclosing specified point template void register_node( Type_ *Node, glm::dvec3 const &Point ) { cell( Point ).register_end( Node ); } // find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance std::tuple find( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ); // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint std::tuple find( glm::dvec3 const &Point, TTrack const *Exclude ); // finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint std::tuple find( glm::dvec3 const &Point, TTraction const *Exclude ); // finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece std::tuple find( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ); // sets center point of the section void center( glm::dvec3 Center ); // generates renderable version of held non-instanced geometry void create_geometry(); // provides access to bounding area data bounding_area const & area() const { return m_area; } private: // types using cell_array = std::array; using shapenode_sequence = std::vector; // methods // provides access to section enclosing specified point basic_cell & cell( glm::dvec3 const &Location ); // members // placement and visibility scene::bounding_area m_area { glm::dvec3(), static_cast( 0.5 * M_SQRT2 * EU07_SECTIONSIZE + 0.25 * EU07_SECTIONSIZE ) }; // content cell_array m_cells; // partitioning scheme shapenode_sequence m_shapes; // large pieces of opaque geometry and (legacy) terrain // TODO: implement dedicated, higher fidelity, fixed resolution terrain mesh item // gfx renderer data geometrybank_handle m_geometrybank; bool m_geometrycreated { false }; }; // top-level of scene spatial structure, holds collection of sections class basic_region { friend class opengl_renderer; public: // constructors basic_region(); // destructor ~basic_region(); // methods // legacy method, updates sounds and polls event launchers around camera void update(); // legacy method, finds and assigns traction piece to specified pantograph of provided vehicle void update_traction( TDynamicObject *Vehicle, int const Pantographindex ); // legacy method, links specified path piece with potential neighbours void TrackJoin( TTrack *Track ); // legacy method, triggers radio-stop procedure for all vehicles in 2km radius around specified location void RadioStop( glm::dvec3 const &Location ); // inserts provided shape in the region void insert_shape( shape_node Shape, scratch_data &Scratchpad, bool const Transform ); // inserts provided lines in the region void insert_lines( lines_node Lines, scratch_data &Scratchpad ); // inserts provided track in the region void insert_path( TTrack *Path, scratch_data &Scratchpad ); // inserts provided track in the region void insert_traction( TTraction *Traction, scratch_data &Scratchpad ); // inserts provided instance of 3d model in the region void insert_instance( TAnimModel *Instance, scratch_data &Scratchpad ); // inserts provided sound in the region void insert_sound( TTextSound *Sound, scratch_data &Scratchpad ); // inserts provided event launcher in the region void insert_launcher( TEventLauncher *Launcher, scratch_data &Scratchpad ); // find a vehicle located nearest to specified point, within specified radius. reurns: located vehicle and distance std::tuple find_vehicle( glm::dvec3 const &Point, float const Radius, bool const Onlycontrolled, bool const Findbycoupler ); // finds a path with one of its ends located in specified point. returns: located path and id of the matching endpoint std::tuple find_path( glm::dvec3 const &Point, TTrack const *Exclude ); // finds a traction piece with one of its ends located in specified point. returns: located traction piece and id of the matching endpoint std::tuple find_traction( glm::dvec3 const &Point, TTraction const *Exclude ); // finds a traction piece located nearest to specified point, sharing section with specified other piece and powered in specified direction. returns: located traction piece std::tuple find_traction( glm::dvec3 const &Point, TTraction const *Other, int const Currentdirection ); // finds sections inside specified sphere. returns: list of sections std::vector const & sections( glm::dvec3 const &Point, float const Radius ); private: // types using section_array = std::array; struct region_scratchpad { std::vector sections; }; // methods // registers specified end point of the provided path in the lookup directory of the region void register_path( TTrack *Path, glm::dvec3 const &Point ); // registers specified end point of the provided traction piece in the lookup directory of the region void register_traction( TTraction *Traction, glm::dvec3 const &Point ); // checks whether specified point is within boundaries of the region bool point_inside( glm::dvec3 const &Location ); // legacy method, trims provided shape to fit into a section. adds trimmed part at the end of provided list, returns true if changes were made bool RaTriangleDivider( shape_node &Shape, std::deque &Shapes ); // provides access to section enclosing specified point basic_section & section( glm::dvec3 const &Location ); // members section_array m_sections; region_scratchpad m_scratchpad; }; } // scene //---------------------------------------------------------------------------