1 //  SuperTuxKart - a fun racing game with go-kart
2 //
3 //  Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net>
4 //  Copyright (C) 2009-2015  Joerg Henrichs, Steve Baker
5 //
6 //  This program is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU General Public License
8 //  as published by the Free Software Foundation; either version 3
9 //  of the License, or (at your option) any later version.
10 //
11 //  This program is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 //  GNU General Public License for more details.
15 //
16 //  You should have received a copy of the GNU General Public License
17 //  along with this program; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19 
20 #ifndef HEADER_TRACK_HPP
21 #define HEADER_TRACK_HPP
22 
23 /**
24   * \defgroup tracks
25   * Contains information about tracks, namely drivelines, checklines and track
26   * objects.
27   */
28 
29 #include <algorithm>
30 #include <atomic>
31 #include <memory>
32 #include <string>
33 #include <vector>
34 
35 #include <irrlicht.h>
36 
37 using namespace irr;
38 
39 #include "LinearMath/btTransform.h"
40 
41 #include "utils/aligned_array.hpp"
42 #include "utils/log.hpp"
43 #include "utils/vec3.hpp"
44 #include "utils/stk_process.hpp"
45 
46 class AbstractKart;
47 class AnimationManager;
48 class BezierCurve;
49 class CheckManager;
50 class ItemManager;
51 class ModelDefinitionLoader;
52 class MovingTexture;
53 class MusicInformation;
54 class ParticleEmitter;
55 class ParticleKind;
56 class PhysicalObject;
57 class RenderTarget;
58 class TrackObject;
59 class TrackObjectManager;
60 class TriangleMesh;
61 class XMLNode;
62 
63 const int HEIGHT_MAP_RESOLUTION = 256;
64 
65 // TODO: eventually remove this and fully replace with scripting
66 struct OverworldChallenge
67 {
68 public:
69     core::vector3df m_position;
70     std::string m_challenge_id;
71 
OverworldChallengeOverworldChallenge72     OverworldChallenge(core::vector3df position, std::string challenge_id)
73     {
74         m_position = position;
75         m_challenge_id = challenge_id;
76     }
77 };
78 
79 
80 struct Subtitle
81 {
82     int m_from, m_to;
83     core::stringw m_text;
84 
SubtitleSubtitle85     Subtitle(int from, int to, core::stringw text)
86     {
87         m_from = from;
88         m_to = to;
89         m_text = text;
90     }
getFromSubtitle91     int getFrom() const { return m_from; }
getToSubtitle92     int getTo()   const { return m_to;   }
getTextSubtitle93     const core::stringw& getText() const { return m_text; }
94 };
95 
96 /**
97   * \ingroup tracks
98   */
99 class Track
100 {
101 private:
102 
103     /** If a race is in progress, this stores the active track object.
104      *  NULL otherwise. */
105     static std::atomic<Track*> m_current_track[PT_COUNT];
106 
107 #ifdef DEBUG
108     unsigned int             m_magic_number;
109 #endif
110 
111     /* Gravity to be used for this track. */
112     float                    m_gravity;
113 
114     /** Friction to be used for the track. */
115     float                    m_friction;
116 
117     std::string              m_ident;
118     std::string              m_screenshot;
119     bool                     m_is_day;
120     std::vector<MusicInformation*> m_music;
121 
122     /** Will only be used on overworld */
123     std::vector<OverworldChallenge> m_challenges;
124 
125     std::vector<Subtitle> m_subtitles;
126 
127     /** Start transforms of karts (either the default, or the ones taken
128      *  from the scene file). */
129     AlignedArray<btTransform> m_start_transforms;
130 
131     std::string              m_item_style;
132     std::string              m_description;
133     core::stringw            m_designer;
134 
135     /* For running the startup script */
136     bool m_startup_run;
137     /** The full filename of the config (xml) file. */
138     std::string              m_filename;
139 
140     /** The base dir of all files of this track. */
141     std::string              m_root;
142     std::vector<std::string> m_groups;
143 
144     /** The list of all nodes. */
145     std::vector<scene::ISceneNode*> m_all_nodes;
146 
147     /** The list of all nodes that are to be converted into physics,
148      *  but not to be drawn (e.g. invisible walls). */
149     std::vector<scene::ISceneNode*> m_static_physics_only_nodes;
150 
151     /** Same concept but for track objects. stored separately due to different
152       * memory management.
153       */
154     std::vector<scene::ISceneNode*> m_object_physics_only_nodes;
155 
156     /** The list of all meshes that are loaded from disk, which means
157      *  that those meshes are being cached by irrlicht, and need to be freed. */
158     std::vector<scene::IMesh*>      m_all_cached_meshes;
159 
160     /**
161       * m_all_cached_meshes assumes meshes are attached to a scene node.
162       * This one assumes the mesh is NOT connected to any node.
163       */
164     std::vector<scene::IMesh*>      m_detached_cached_meshes;
165 
166     /** A list of all textures loaded by the track, so that they can
167      *  be removed from the cache at cleanup time. */
168     std::vector<video::ITexture*>   m_all_cached_textures;
169 
170     /** True if the materials.xml file is already loaded. This is used
171      * for the overworld to keep its textures loaded. */
172     bool m_materials_loaded;
173 
174     /** True if this track (textures and track data) should be cached. Used
175      *  for the overworld. */
176     bool m_cache_track;
177 
178 
179 #ifdef DEBUG
180     /** A list of textures that were cached before the track is loaded.
181      *  After cleanup of ta track it can be tested which new textures
182      *  are still in the cache, and print a report of leaked textures
183      *  (in debug mode only). */
184     std::vector<video::ITexture*>   m_old_textures;
185 
186     /** Used to store all buffers in irrlicht's memory cache before a track
187      *  is loaded. After cleanup of a track we can test which meshes are
188      *  still in the cache, and print a report of leaked meshes (of course in
189      *  debug mode only). */
190     std::vector<std::string> m_old_mesh_buffers;
191 #endif
192 
193     scene::ISceneNode  *m_sun;
194     /** Used to collect the triangles for the bullet mesh. */
195     TriangleMesh*            m_track_mesh;
196     /** Used to collect the triangles which do not have a physical
197      *  representation, but are needed for some raycast effects. An
198      *  example is a water surface: the karts ignore this (i.e.
199      *  allowing the kart to drive in/partly under water), but the
200      *  actual surface position is needed for the water splash effect. */
201     TriangleMesh*            m_gfx_effect_mesh;
202     /** Minimum coordinates of this track. */
203     Vec3                     m_aabb_min;
204     /** Maximum coordinates of this track. */
205     Vec3                     m_aabb_max;
206     btTransform              m_red_flag;
207     btTransform              m_blue_flag;
208     /** True if this track is an arena. */
209     bool                     m_is_arena;
210     bool                     m_is_ctf;
211     /** Max players supported by an arena. */
212     unsigned int             m_max_arena_players;
213     /** True if this track has easter eggs. */
214     bool                     m_has_easter_eggs;
215     /** True if this track has navmesh. */
216     bool                     m_has_navmesh;
217     /** True if this track is a soccer arena. */
218     bool                     m_is_soccer;
219 
220     bool                     m_is_cutscene;
221 
222     /** The version of this track. A certain STK version will only support
223      *  certain track versions. */
224     int                      m_version;
225 
226     /** Far value for cameras for this track. */
227     float                    m_camera_far;
228 
229     /** Whether this is an "internal" track. If so it won't be offered
230       * in the track seelction screen
231       */
232     bool                     m_internal;
233 
234     /** Whether this track should be available in reverse version */
235     bool                     m_reverse_available;
236 
237     /** If true a player kart will automatically be rescued if it is
238      *  e.g. on a side, .... */
239     bool                     m_enable_auto_rescue;
240 
241     /** If true any collision of a kart with the track will push the kart
242      *  towards the nearest driveline. While this is (mostly) nice in tracks
243      *  where a kart is pushed back towards the road, it doesn't work well
244      *  on overworld, where karts have been pushed out of 'bubbles' . */
245     bool                     m_enable_push_back;
246 
247     /** The type of sky to be used for the track. */
248     enum {SKY_NONE, SKY_BOX,
249           SKY_DOME, SKY_COLOR}          m_sky_type;
250 
251     /** sky rotation speed */
252     float m_sky_dx, m_sky_dy;
253 
254     /** A list of the textures for the sky to use. It contains one texture
255      *  in case of a dome, and 6 textures for a box. */
256     std::vector<video::ITexture*> m_sky_textures;
257 
258     std::vector<video::ITexture*> m_spherical_harmonics_textures;
259 
260     /** Used if m_sky_type is SKY_COLOR only */
261     irr::video::SColor m_sky_color;
262 
263     /** The list of all animated textures. */
264     std::vector<MovingTexture*> m_animated_textures;
265 
266     /** Manager for all track objects. */
267     TrackObjectManager *m_track_object_manager;
268 
269     /** If a sky dome is used, the number of horizontal segments
270      *  the sphere should be divided in. */
271     int                      m_sky_hori_segments;
272 
273     /** If a sky dome is used, the number of vertical segments
274      *  the sphere should be divided in. */
275     int                      m_sky_vert_segments;
276 
277     /** If a sky dome is used, percentage of the sphere to be used. */
278     float                    m_sky_sphere_percent;
279 
280     /** If a sky dome is used, percentage of the texture to be used. */
281     float                    m_sky_texture_percent;
282 
283     /** Particles emitted from the sky (wheather) */
284     ParticleKind*            m_sky_particles;
285 
286     /** Use a special built-in wheather */
287     bool                     m_weather_lightning;
288     std::string              m_weather_sound;
289 
290     /** A simple class to keep information about a track mode. */
291     class TrackMode
292     {
293     public:
294         std::string m_name;        /**< Name / description of this mode. */
295         std::string m_quad_name;   /**< Name of the quad file to use.    */
296         std::string m_graph_name;  /**< Name of the graph file to use.   */
297         std::string m_scene;       /**< Name of the scene file to use.   */
298 
299 #ifdef DEBUG
300         unsigned int m_magic_number;
301 #endif
302 
303         /** Default constructor, sets default names for all fields. */
TrackMode()304         TrackMode() : m_name("default"),         m_quad_name("quads.xml"),
305                       m_graph_name("graph.xml"), m_scene("scene.xml")
306         {
307 #ifdef DEBUG
308             m_magic_number = 0x46825179;
309 #endif
310         }
311 
~TrackMode()312         ~TrackMode()
313         {
314 #ifdef DEBUG
315             assert(m_magic_number == 0x46825179);
316             m_magic_number = 0xDEADBEEF;
317 #endif
318         }
319 
320     };   // TrackMode
321 
322     /** List of all modes for a track. */
323     std::vector<TrackMode> m_all_modes;
324 
325     /** Name of the track to display. */
326     std::string         m_name;
327 
328     /** The name used in sorting the track. */
329     core::stringw       m_sort_name;
330 
331     /** True if the track uses fog. */
332     bool                m_use_fog;
333 
334     /** Can be set to force fog off (e.g. for rendering minimap). */
335     bool                m_force_disable_fog;
336 
337     /** True if this track supports using smoothed normals. */
338     bool                m_smooth_normals;
339 
340     bool                m_is_addon;
341 
342     float               m_fog_max;
343     float               m_fog_start;
344     float               m_fog_end;
345     float               m_fog_height_start;
346     float               m_fog_height_end;
347     core::vector3df     m_sun_position;
348     /** The current ambient color for each kart. */
349     video::SColor       m_ambient_color;
350     video::SColor       m_default_ambient_color;
351     video::SColor       m_sun_specular_color;
352     video::SColor       m_sun_diffuse_color;
353     video::SColor       m_fog_color;
354 
355     /** The render target for the mini map, which is displayed in the race gui. */
356     RenderTarget           *m_render_target;
357     CheckManager*           m_check_manager;
358     std::shared_ptr<ItemManager> m_item_manager;
359     float                   m_minimap_x_scale;
360     float                   m_minimap_y_scale;
361 
362     bool m_clouds;
363 
364     bool m_bloom;
365     float m_bloom_threshold;
366 
367     bool m_godrays;
368     core::vector3df m_godrays_position;
369     float m_godrays_opacity;
370     video::SColor m_godrays_color;
371 
372     bool m_shadows;
373 
374     float m_displacement_speed;
375     int m_physical_object_uid;
376 
377     bool m_minimap_invert_x_z;
378 
379     /** The levels for color correction
380      * m_color_inlevel(black, gamma, white)
381      * m_color_outlevel(black, white)*/
382     core::vector3df m_color_inlevel;
383     core::vector2df m_color_outlevel;
384 
385     /** List of all bezier curves in the track - for e.g. camera, ... */
386     std::vector<BezierCurve*> m_all_curves;
387 
388     std::vector<std::pair<TrackObject*, TrackObject*> > m_meta_library;
389 
390     /** The number of laps the track will be raced in a random GP.
391      * m_actual_number_of_laps is initialised with this value.*/
392     int m_default_number_of_laps;
393 
394     /** The number of laps that is predefined in a track info dialog. */
395     int m_actual_number_of_laps;
396 
397     void loadTrackInfo();
398     void loadDriveGraph(unsigned int mode_id, const bool reverse);
399     void loadArenaGraph(const XMLNode &node);
400     btQuaternion getArenaStartRotation(const Vec3& xyz, float heading);
401     bool loadMainTrack(const XMLNode &node);
402     void loadMinimap();
403     void createWater(const XMLNode &node);
404     void getMusicInformation(std::vector<std::string>&  filenames,
405                              std::vector<MusicInformation*>& m_music   );
406     void loadCurves(const XMLNode &node);
407     void handleSky(const XMLNode &root, const std::string &filename);
408     void freeCachedMeshVertexBuffer();
409     void copyFromMainProcess();
410 public:
411 
412     /** Static function to get the current track. NULL if no current
413      *  track is defined (i.e. no race is active atm) */
getCurrentTrack()414     static Track* getCurrentTrack()
415     {
416         ProcessType type = STKProcess::getType();
417         return m_current_track[type];
418     }
419     // ------------------------------------------------------------------------
clone()420     Track* clone()
421     {
422         Track* child_track = new Track(*this);
423         child_track->copyFromMainProcess();
424         return child_track;
425     }
426     // ------------------------------------------------------------------------
427     void initChildTrack();
428     // ------------------------------------------------------------------------
429     static void cleanChildTrack();
430     // ------------------------------------------------------------------------
431     void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
432 
433     /** Flag to avoid loading navmeshes (useful to speedup debugging: e.g.
434      *  the temple navmesh distance matric computation takes around 12
435      *  minutes(!) in debug mode to be computed. */
436     static bool        m_dont_load_navmesh;
437 
438     /** Static helper function to pre-upload vertex buffer in spm. */
439     static void uploadNodeVertexBuffer(scene::ISceneNode *node);
440 
441     static const float NOHIT;
442 
443                        Track             (const std::string &filename);
444                       ~Track             ();
445     void               cleanup           ();
446     void               removeCachedData  ();
447     void               startMusic        () const;
448 
449     void               createPhysicsModel(unsigned int main_track_count);
450     void               updateGraphics(float dt);
451     void               update(int ticks);
452     void               reset();
453     void               itemCommand(const XMLNode *node);
454     Vec3               flagCommand(const XMLNode *node);
455     //-----------------------------------------------------------------------------
456     core::stringw      getName() const;
457     //-----------------------------------------------------------------------------
458     core::stringw      getSortName() const;
459     bool               isInGroup(const std::string &group_name);
460     const core::vector3df& getSunRotation();
461     /** Sets the current ambient color for a kart with index k. */
462     void               setAmbientColor(const video::SColor &color,
463                                        unsigned int k);
464     void               handleExplosion(const Vec3 &pos,
465                                        const PhysicalObject *mp,
466                                        bool secondary_hits=true) const;
467     void               loadTrackModel  (bool reverse_track = false,
468                                         unsigned int mode_id=0);
469     bool findGround(AbstractKart *kart);
470 
471     std::vector< std::vector<float> > buildHeightMap();
472     void               drawMiniMap(const core::rect<s32>& dest_rect) const;
473     void               updateMiniMapScale();
474     // ------------------------------------------------------------------------
475     /** Returns true if this track has an arena mode. */
isArena() const476     bool isArena() const { return m_is_arena; }
477     // ------------------------------------------------------------------------
isCTF() const478     bool isCTF() const { return m_is_ctf; }
479     // ------------------------------------------------------------------------
480     /** Returns true if this track is a racing track. This means it is not an
481      *  internal track (like cut scenes), arena, or soccer field. */
isRaceTrack() const482     bool isRaceTrack() const
483     {
484         return !m_internal && !m_is_arena && !m_is_soccer;
485     }   // isRaceTrack
486     // ------------------------------------------------------------------------
487     /** Returns true if this track has easter eggs. */
hasEasterEggs() const488     bool hasEasterEggs() const { return m_has_easter_eggs; }
489     // ------------------------------------------------------------------------
490     /** Returns true if this race can be driven in reverse. */
reverseAvailable() const491     bool reverseAvailable() const { return m_reverse_available; }
492     // ------------------------------------------------------------------------
493     /** Returns true if this track navmesh. */
hasNavMesh() const494     bool hasNavMesh() const { return m_has_navmesh; }
495     // ------------------------------------------------------------------------
496     void loadObjects(const XMLNode* root, const std::string& path,
497         ModelDefinitionLoader& lod_loader, bool create_lod_definitions,
498         scene::ISceneNode* parent, TrackObject* parent_library);
499     // ------------------------------------------------------------------------
isSoccer() const500     bool               isSoccer             () const { return m_is_soccer; }
501     // ------------------------------------------------------------------------
addMusic(MusicInformation * mi)502     void               addMusic          (MusicInformation* mi)
503                                                   {m_music.push_back(mi);     }
504     // ------------------------------------------------------------------------
getGravity() const505     float              getGravity        () const {return m_gravity;          }
506     // ------------------------------------------------------------------------
507     /** Returns the version of the .track file. */
getVersion() const508     int                getVersion        () const {return m_version;          }
509     // ------------------------------------------------------------------------
510     /** Returns the length of the main driveline. */
511     float              getTrackLength    () const;
512     // ------------------------------------------------------------------------
513     /** Returns a unique identifier for this track (the directory name). */
getIdent() const514     const std::string& getIdent          () const {return m_ident;            }
515     // ------------------------------------------------------------------------
516     /** Returns all groups this track belongs to. */
517     const std::vector<std::string>&
getGroups() const518                        getGroups         () const {return m_groups;           }
519     // ------------------------------------------------------------------------
520     /** Returns the filename of this track. */
getFilename() const521     const std::string& getFilename       () const {return m_filename;         }
522     // ------------------------------------------------------------------------
523     /** Returns the name of the designer. */
getDesigner() const524     const core::stringw& getDesigner     () const {return m_designer;         }
525     // ------------------------------------------------------------------------
526     /** Returns an absolute path to the screenshot file of this track */
getScreenshotFile() const527     const std::string& getScreenshotFile () const {return m_screenshot;       }
528     // ------------------------------------------------------------------------
529     /** Returns if the track is during day time */
getIsDuringDay() const530     const bool getIsDuringDay () const {return m_is_day;               }
531     // ------------------------------------------------------------------------
532     /** Returns if invert minimap */
getMinimapInvert() const533     const bool getMinimapInvert () const {return m_minimap_invert_x_z;               }
534     // ------------------------------------------------------------------------
535     /** Returns the start coordinates for a kart with a given index.
536      *  \param index Index of kart ranging from 0 to kart_num-1. */
getStartTransform(unsigned int index) const537     const btTransform& getStartTransform (unsigned int index) const
538     {
539         if (index >= m_start_transforms.size())
540             Log::fatal("Track", "No start position for kart %i.", index);
541         return m_start_transforms[index];
542     }
543     // ------------------------------------------------------------------------
544     /** Shuffles the start transformations
545     */
shuffleStartTransforms()546     void shuffleStartTransforms()
547     {
548         std::random_shuffle(m_start_transforms.begin(), m_start_transforms.end());
549     }
550     // ------------------------------------------------------------------------
551     /** Sets pointer to the aabb of this track. */
getAABB(const Vec3 ** min,const Vec3 ** max) const552     void               getAABB(const Vec3 **min, const Vec3 **max) const
553                        { *min = &m_aabb_min; *max = &m_aabb_max; }
554     // ------------------------------------------------------------------------
555     /** Returns 'a' angle for quad n. This angle is used to position a kart
556      *  after a rescue, and to detect wrong directions. This function will
557      *  always return the angle towards the first successor, i.e. the angle
558      *  in the direction of the default way on the track.
559      *  \param n Number of the quad for which the angle is asked.
560      */
561     float              getAngle(int n) const;
562     // ------------------------------------------------------------------------
563     /** Returns the 2d coordinates of a point when drawn on the mini map
564      *  texture.
565      *  \param xyz Coordinates of the point to map.
566      *  \param draw_at The coordinates in pixel on the mini map of the point,
567      *         only the first two coordinates will be used.
568      */
569     void               mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const;
570     // ------------------------------------------------------------------------
571     /** Returns the full path of a given file inside this track directory. */
getTrackFile(const std::string & s) const572     std::string        getTrackFile(const std::string &s) const
573                                 { return m_root+"/"+s; }
574     // ------------------------------------------------------------------------
575     /** Returns the number of modes available for this track. */
getNumberOfModes() const576     unsigned int       getNumberOfModes() const { return (unsigned int) m_all_modes.size();  }
577     // ------------------------------------------------------------------------
578     /** Returns number of completed challenges. */
579     unsigned int getNumOfCompletedChallenges();
580     // ------------------------------------------------------------------------
581     /** Returns the name of the i-th. mode. */
getModeName(unsigned int i) const582     const std::string &getModeName(unsigned int i) const
583                                               { return m_all_modes[i].m_name; }
584     // ------------------------------------------------------------------------
585     /** Returns the default ambient color. */
getDefaultAmbientColor() const586     const video::SColor &getDefaultAmbientColor() const
587                                             { return m_default_ambient_color; }
588     // ------------------------------------------------------------------------
589     /** Returns the far value for cameras. */
getCameraFar() const590     float  getCameraFar() const { return m_camera_far; }
591     // ------------------------------------------------------------------------
592     /** Returns the triangle mesh for this track. */
getPtrTriangleMesh() const593     const TriangleMesh *getPtrTriangleMesh() const { return m_track_mesh; }
getTriangleMesh() const594     const TriangleMesh& getTriangleMesh() const {return *m_track_mesh; }
595     // ------------------------------------------------------------------------
596     /** Returns the graphical effect mesh for this track. */
getGFXEffectMesh() const597     const TriangleMesh& getGFXEffectMesh() const {return *m_gfx_effect_mesh;}
598     // ------------------------------------------------------------------------
599     /** Get the max players supported for this track, for arena only. */
getMaxArenaPlayers() const600     unsigned int getMaxArenaPlayers() const
601                                                 { return m_max_arena_players; }
602     // ------------------------------------------------------------------------
603     /** Get the number of start positions defined in the scene file. */
getNumberOfStartPositions() const604     unsigned int getNumberOfStartPositions() const
605                             { return (unsigned int)m_start_transforms.size(); }
606     // ------------------------------------------------------------------------
getWeatherLightning()607     bool getWeatherLightning() {return m_weather_lightning;}
608     // ------------------------------------------------------------------------
getWeatherSound()609     const std::string& getWeatherSound() {return m_weather_sound;}
610     // ------------------------------------------------------------------------
getSkyParticles()611     ParticleKind* getSkyParticles         () { return m_sky_particles; }
612     // ------------------------------------------------------------------------
613     /** Override track fog value to force disabled */
forceFogDisabled(bool v)614     void forceFogDisabled(bool v) { m_force_disable_fog = v; }
615     //-------------------------------------------------------------------------
616     /** Returns if fog is currently enabled. It can be disabled per track, or
617      *  temporary be disabled (e.g. for rendering mini map). */
isFogEnabled() const618     bool isFogEnabled() const
619     {
620         return !m_force_disable_fog && m_use_fog;
621     }   // isFogEnabled
622 
623     // ------------------------------------------------------------------------
getFogStart() const624     float getFogStart()  const { return m_fog_start; }
625     // ------------------------------------------------------------------------
setFogStart(float start)626     void setFogStart(float start) { m_fog_start = start; }
627     // ------------------------------------------------------------------------
getFogEnd() const628     float getFogEnd()    const { return m_fog_end; }
629     // ------------------------------------------------------------------------
setFogEnd(float end)630     void setFogEnd(float end) { m_fog_end = end; }
631     // ------------------------------------------------------------------------
getFogStartHeight() const632     float getFogStartHeight()  const { return m_fog_height_start; }
633     // ------------------------------------------------------------------------
getFogEndHeight() const634     float getFogEndHeight()    const { return m_fog_height_end; }
635     // ------------------------------------------------------------------------
getFogMax() const636     float getFogMax()    const { return m_fog_max; }
637     // ------------------------------------------------------------------------
setFogMax(float max)638     void setFogMax(float max) { m_fog_max = max; }
639     // ------------------------------------------------------------------------
getFogColor() const640     video::SColor getFogColor() const { return m_fog_color; }
641     // ------------------------------------------------------------------------
setFogColor(video::SColor & color)642     void setFogColor(video::SColor& color) { m_fog_color = color; }
643     // ------------------------------------------------------------------------
getSunColor() const644     video::SColor getSunColor() const { return m_sun_diffuse_color; }
645     // ------------------------------------------------------------------------
646     /** Whether this is an "internal" track. If so it won't be offered
647      * in the track selection screen. */
isInternal() const648     bool isInternal() const { return m_internal; }
649     // ------------------------------------------------------------------------
650     /** Returns true if auto rescue is enabled. */
isAutoRescueEnabled() const651     bool isAutoRescueEnabled() const { return m_enable_auto_rescue; }
652     // ------------------------------------------------------------------------
653     /** True if push back of karts towards the track should be enabled. */
isPushBackEnabled() const654     bool isPushBackEnabled() const { return m_enable_push_back; }
655     // ------------------------------------------------------------------------
656     /** Returns true if the normals of this track can be smoothed. */
smoothNormals() const657     bool smoothNormals() const { return m_smooth_normals; }
658     // ------------------------------------------------------------------------
659     /** Returns the track object manager. */
getTrackObjectManager() const660     TrackObjectManager* getTrackObjectManager() const
661     {
662         return m_track_object_manager;
663     }   // getTrackObjectManager
664 
665     // ------------------------------------------------------------------------
666     /** Get list of challenges placed on that world. Works only for overworld. */
getChallengeList() const667     const std::vector<OverworldChallenge>& getChallengeList() const
668         { return m_challenges; }
669 
670     // ------------------------------------------------------------------------
getSubtitles() const671     const std::vector<Subtitle>& getSubtitles() const { return m_subtitles; }
672 
673     // ------------------------------------------------------------------------
hasClouds() const674     bool hasClouds() const { return m_clouds; }
675 
676     // ------------------------------------------------------------------------
hasBloom() const677     bool hasBloom() const { return m_bloom; }
678 
679     // ------------------------------------------------------------------------
getBloomThreshold() const680     float getBloomThreshold() const { return m_bloom_threshold; }
681 
682     // ------------------------------------------------------------------------
683     /** Return the color levels for color correction shader */
getColorLevelIn() const684     core::vector3df getColorLevelIn() const { return m_color_inlevel; }
685     // ------------------------------------------------------------------------
getColorLevelOut() const686     core::vector2df getColorLevelOut() const { return m_color_outlevel; }
687     // ------------------------------------------------------------------------
hasGodRays() const688     bool hasGodRays() const { return m_godrays; }
689     // ------------------------------------------------------------------------
getGodRaysPosition() const690     core::vector3df getGodRaysPosition() const { return m_godrays_position; }
691     // ------------------------------------------------------------------------
getGodRaysOpacity() const692     float getGodRaysOpacity() const { return m_godrays_opacity; }
693     // ------------------------------------------------------------------------
getGodRaysColor() const694     video::SColor getGodRaysColor() const { return m_godrays_color; }
695     // ------------------------------------------------------------------------
hasShadows() const696     bool hasShadows() const { return m_shadows; }
697     // ------------------------------------------------------------------------
addNode(scene::ISceneNode * node)698     void addNode(scene::ISceneNode* node) { m_all_nodes.push_back(node); }
699     // ------------------------------------------------------------------------
addPhysicsOnlyNode(scene::ISceneNode * node)700     void addPhysicsOnlyNode(scene::ISceneNode* node)
701     {
702         m_object_physics_only_nodes.push_back(node);
703     }
704     // ------------------------------------------------------------------------
getDisplacementSpeed() const705     float getDisplacementSpeed() const { return m_displacement_speed;    }
706     // ------------------------------------------------------------------------
getPhysicalObjectUID()707     int getPhysicalObjectUID()              { return m_physical_object_uid++; }
708     // ------------------------------------------------------------------------
getDefaultNumberOfLaps() const709     const int getDefaultNumberOfLaps() const { return m_default_number_of_laps;}
710     // ------------------------------------------------------------------------
getActualNumberOfLap() const711     const int getActualNumberOfLap() const { return m_actual_number_of_laps; }
712     // ------------------------------------------------------------------------
setActualNumberOfLaps(unsigned int laps)713     void setActualNumberOfLaps(unsigned int laps)
714                                          { m_actual_number_of_laps = laps; }
715     // ------------------------------------------------------------------------
716     bool operator<(const Track &other) const;
717     // ------------------------------------------------------------------------
718     /** Adds mesh to cleanup list */
addCachedMesh(scene::IMesh * mesh)719     void addCachedMesh(scene::IMesh* mesh) { m_all_cached_meshes.push_back(mesh); }
720     // ------------------------------------------------------------------------
721     /** Adds the parent of the meta library for correction later */
addMetaLibrary(TrackObject * parent,TrackObject * meta_library)722     void addMetaLibrary(TrackObject* parent, TrackObject* meta_library)
723                          { m_meta_library.emplace_back(parent, meta_library); }
724     // ------------------------------------------------------------------------
getRedFlag() const725     const btTransform& getRedFlag() const                { return m_red_flag; }
726     // ------------------------------------------------------------------------
getBlueFlag() const727     const btTransform& getBlueFlag() const              { return m_blue_flag; }
728     // ------------------------------------------------------------------------
isAddon() const729     bool isAddon() const                                 { return m_is_addon; }
730     // ------------------------------------------------------------------------
731     void convertTrackToBullet(scene::ISceneNode *node);
732     // ------------------------------------------------------------------------
getCheckManager() const733     CheckManager* getCheckManager() const           { return m_check_manager; }
734     // ------------------------------------------------------------------------
getItemManager() const735     ItemManager* getItemManager() const        { return m_item_manager.get(); }
736 };   // class Track
737 
738 #endif
739