1 // SuperTuxKart - a fun racing game with go-kart 2 // 3 // Copyright (C) 2013-2015 Joerg Henrichs, Marianne Gagnon 4 // 5 // This program is free software; you can redistribute it and/or 6 // modify it under the terms of the GNU General Public License 7 // as published by the Free Software Foundation; either version 3 8 // of the License, or (at your option) any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program; if not, write to the Free Software 17 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 19 20 #ifndef HEADER_TRACK_OBJECT_PRESENTATION_HPP 21 #define HEADER_TRACK_OBJECT_PRESENTATION_HPP 22 23 #include "graphics/lod_node.hpp" 24 #include "utils/cpp2011.hpp" 25 #include "utils/no_copy.hpp" 26 #include "utils/log.hpp" 27 #include "utils/leak_check.hpp" 28 #include "utils/time.hpp" 29 #include "utils/vec3.hpp" 30 31 #include <vector3d.h> 32 #include <IAnimatedMeshSceneNode.h> 33 34 #include <memory> 35 #include <limits> 36 #include <string> 37 38 class SFXBase; 39 class ParticleEmitter; 40 class PhysicalObject; 41 class ThreeDAnimation; 42 class ModelDefinitionLoader; 43 class RenderInfo; 44 class STKInstancedSceneNode; 45 class XMLNode; 46 class TrackObject; 47 48 namespace irr 49 { 50 namespace scene { class IAnimatedMesh; class IMeshSceneNode; class ISceneNode; } 51 } 52 using namespace irr; 53 54 /** \ingroup tracks 55 * Base class for all track object presentation classes. 56 */ 57 class TrackObjectPresentation 58 { 59 protected: 60 /** The initial XYZ position of the object. */ 61 core::vector3df m_init_xyz; 62 63 /** The initial hpr of the object. */ 64 core::vector3df m_init_hpr; 65 66 /** The initial scale of the object. */ 67 core::vector3df m_init_scale; 68 69 70 public: 71 72 TrackObjectPresentation(const XMLNode& xml_node); 73 TrackObjectPresentation(const core::vector3df & xyz,const core::vector3df & hpr=core::vector3df (0,0,0),const core::vector3df & scale=core::vector3df (0,0,0))74 TrackObjectPresentation(const core::vector3df& xyz, 75 const core::vector3df& hpr = core::vector3df(0,0,0), 76 const core::vector3df& scale = core::vector3df(0,0,0)) 77 { 78 m_init_xyz = xyz; 79 m_init_hpr = hpr; 80 m_init_scale = scale; 81 } // TrackObjectPresentation 82 83 // ------------------------------------------------------------------------ ~TrackObjectPresentation()84 virtual ~TrackObjectPresentation() {} 85 // ------------------------------------------------------------------------ 86 reset()87 virtual void reset() {} setEnable(bool enabled)88 virtual void setEnable(bool enabled) 89 { 90 Log::warn("TrackObjectPresentation", "setEnable unimplemented for this presentation type"); 91 } updateGraphics(float dt)92 virtual void updateGraphics(float dt) {} update(float dt)93 virtual void update(float dt) {} move(const core::vector3df & xyz,const core::vector3df & hpr,const core::vector3df & scale,bool isAbsoluteCoord)94 virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, 95 const core::vector3df& scale, bool isAbsoluteCoord) {} 96 97 // ------------------------------------------------------------------------ 98 /** Returns the position of this TrackObjectPresentation. */ getPosition() const99 virtual const core::vector3df& getPosition() const { return m_init_xyz; } 100 // ------------------------------------------------------------------------ 101 /** Returns a copy of the initial position. Note this function does not 102 * return a const reference, since some classes overwrite it this way. */ getAbsolutePosition() const103 virtual const core::vector3df getAbsolutePosition() const 104 { 105 return m_init_xyz; 106 } // getAbsolutePosition 107 // ------------------------------------------------------------------------ getAbsoluteCenterPosition() const108 virtual const core::vector3df getAbsoluteCenterPosition() const 109 { 110 return m_init_xyz; 111 } 112 // ------------------------------------------------------------------------ 113 /** Returns the initial rotation. */ getRotation() const114 virtual const core::vector3df& getRotation() const { return m_init_hpr; } 115 // ------------------------------------------------------------------------ 116 /** Returns the initial scale. */ getScale() const117 virtual const core::vector3df& getScale() const { return m_init_scale; } 118 119 LEAK_CHECK() 120 }; 121 122 // ============================================================================ 123 /** \ingroup tracks 124 * Base class for all track object presentation classes using a scene node 125 * as presentation 126 */ 127 class TrackObjectPresentationSceneNode : public TrackObjectPresentation 128 { 129 protected: 130 /** A pointer to the scene node of this object. */ 131 scene::ISceneNode* m_node; 132 133 bool m_force_always_hidden; 134 public: 135 136 /** Constructor based on data from xml. */ TrackObjectPresentationSceneNode(const XMLNode & xml_node)137 TrackObjectPresentationSceneNode(const XMLNode& xml_node) : 138 TrackObjectPresentation(xml_node) 139 { 140 m_node = NULL; 141 m_force_always_hidden = false; 142 } // TrackObjectPresentationSceneNode 143 // ------------------------------------------------------------------------ 144 /** Constructor based on a transform. */ TrackObjectPresentationSceneNode(const core::vector3df & xyz,const core::vector3df & hpr,const core::vector3df & scale,scene::ISceneNode * node=NULL)145 TrackObjectPresentationSceneNode(const core::vector3df& xyz, 146 const core::vector3df& hpr, 147 const core::vector3df& scale, 148 scene::ISceneNode* node = NULL) : 149 TrackObjectPresentation(xyz, hpr, scale) 150 { 151 m_node = node; 152 m_force_always_hidden = false; 153 } // TrackObjectPresentationSceneNode 154 155 // ------------------------------------------------------------------------ 156 virtual const core::vector3df& getPosition() const OVERRIDE; 157 virtual const core::vector3df getAbsolutePosition() const OVERRIDE; 158 virtual const core::vector3df getAbsoluteCenterPosition() const OVERRIDE; 159 virtual const core::vector3df& getRotation() const OVERRIDE; 160 virtual const core::vector3df& getScale() const OVERRIDE; 161 virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, 162 const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE; 163 virtual void setEnable(bool enabled) OVERRIDE; 164 virtual void reset() OVERRIDE; 165 166 // ------------------------------------------------------------------------ 167 /** Returns a pointer to the scene node. */ getNode()168 scene::ISceneNode* getNode() { return m_node; } 169 // ------------------------------------------------------------------------ 170 /** Returns a pointer to the scene node, const version. */ getNode() const171 const scene::ISceneNode* getNode() const { return m_node; } 172 // ------------------------------------------------------------------------ isAlwaysHidden() const173 bool isAlwaysHidden() const { return m_force_always_hidden; } 174 }; // class TrackObjectPresentationSceneNode 175 176 // ============================================================================ 177 /** \ingroup tracks 178 * A track object representation that is invisible and only consists of a 179 * location, rotation and scale. 180 */ 181 class TrackObjectPresentationEmpty : public TrackObjectPresentationSceneNode 182 { 183 public: 184 TrackObjectPresentationEmpty(const XMLNode& xml_node); 185 virtual ~TrackObjectPresentationEmpty(); 186 }; // class TrackObjectPresentationEmpty 187 188 // ============================================================================ 189 /** \ingroup tracks 190 * A track object representation that is a library node 191 */ 192 class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode 193 { 194 TrackObject* m_parent; 195 using TrackObjectPresentationSceneNode::move; 196 std::string m_name; 197 bool m_start_executed, m_reset_executed; 198 public: 199 TrackObjectPresentationLibraryNode(TrackObject* parent, 200 const XMLNode& xml_node, 201 ModelDefinitionLoader& model_def_loader); 202 virtual ~TrackObjectPresentationLibraryNode(); 203 virtual void update(float dt) OVERRIDE; reset()204 virtual void reset() OVERRIDE 205 { 206 m_reset_executed = false; 207 TrackObjectPresentationSceneNode::reset(); 208 } 209 virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, 210 const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE; 211 }; // TrackObjectPresentationLibraryNode 212 213 // ============================================================================ 214 /** \ingroup tracks 215 * A track object representation that consists of a level-of-detail scene node 216 */ 217 class TrackObjectPresentationLOD : public TrackObjectPresentationSceneNode 218 { 219 public: 220 221 TrackObjectPresentationLOD(const XMLNode& xml_node, 222 scene::ISceneNode* parent, 223 ModelDefinitionLoader& model_def_loader, 224 std::shared_ptr<RenderInfo> ri); 225 virtual ~TrackObjectPresentationLOD(); 226 virtual void reset() OVERRIDE; 227 }; 228 229 // ============================================================================ 230 /** \ingroup tracks 231 * A track object representation that consists of a mesh scene node. 232 */ 233 class TrackObjectPresentationMesh : public TrackObjectPresentationSceneNode 234 { 235 private: 236 /** The mesh used here. It needs to be stored so that it can be 237 * removed from irrlicht's mesh cache when it is deleted. */ 238 scene::IMesh *m_mesh; 239 240 /** True if it is a looped animation. */ 241 bool m_is_looped; 242 243 /** True if the object is in the skybox */ 244 bool m_is_in_skybox; 245 246 std::string m_model_file; 247 248 std::shared_ptr<RenderInfo> m_render_info; 249 250 void init(const XMLNode* xml_node, scene::ISceneNode* parent, bool enabled); 251 252 public: 253 TrackObjectPresentationMesh(const XMLNode& xml_node, bool enabled, 254 scene::ISceneNode* parent, 255 std::shared_ptr<RenderInfo> render_info); 256 257 TrackObjectPresentationMesh(const std::string& model_file, 258 const core::vector3df& xyz, 259 const core::vector3df& hpr, 260 const core::vector3df& scale); 261 TrackObjectPresentationMesh(scene::IAnimatedMesh* mesh, 262 const core::vector3df& xyz, 263 const core::vector3df& hpr, 264 const core::vector3df& scale); 265 virtual ~TrackObjectPresentationMesh(); 266 virtual void reset() OVERRIDE; 267 // ------------------------------------------------------------------------ 268 /** Returns the mode file name. */ getModelFile() const269 const std::string& getModelFile() const { return m_model_file; } 270 }; // class TrackObjectPresentationMesh 271 272 // ============================================================================ 273 /** \ingroup tracks 274 * A track object representation that consists of a sound emitter 275 */ 276 class TrackObjectPresentationSound : public TrackObjectPresentation 277 { 278 private: 279 280 /** If a sound is attached to this object and/or this is a sound emitter 281 * object */ 282 SFXBase* m_sound; 283 284 /** Currently used for sound effects only, in cutscenes only atm */ 285 std::string m_trigger_condition; 286 287 core::vector3df m_xyz; 288 289 bool m_enabled; 290 291 public: 292 293 TrackObjectPresentationSound(const XMLNode& xml_node, 294 scene::ISceneNode* parent, 295 bool disable_for_multiplayer); 296 virtual ~TrackObjectPresentationSound(); 297 void onTriggerItemApproached(int kart_id); 298 virtual void updateGraphics(float dt) OVERRIDE; 299 virtual void move(const core::vector3df& xyz, const core::vector3df& hpr, 300 const core::vector3df& scale, bool isAbsoluteCoord) OVERRIDE; 301 void triggerSound(bool loop); 302 void stopSound(); 303 304 virtual void setEnable(bool enabled) OVERRIDE; 305 306 // ------------------------------------------------------------------------ 307 /** Currently used for sound effects only, in cutscenes only atm */ getTriggerCondition() const308 const std::string& getTriggerCondition() const { return m_trigger_condition; } 309 }; // TrackObjectPresentationSound 310 311 // ============================================================================ 312 /** \ingroup tracks 313 * A track object representation that consists of a billboard scene node. 314 */ 315 class TrackObjectPresentationBillboard : public TrackObjectPresentationSceneNode 316 { 317 /** To make the billboard disappear when close to the camera. Useful for 318 * light halos: instead of "colliding" with the camera and suddenly 319 * disappearing when clipped by frustum culling, it will gently fade out. 320 */ 321 bool m_fade_out_when_close; 322 float m_fade_out_start; 323 float m_fade_out_end; 324 public: 325 TrackObjectPresentationBillboard(const XMLNode& xml_node, 326 scene::ISceneNode* parent); 327 virtual ~TrackObjectPresentationBillboard(); 328 virtual void updateGraphics(float dt) OVERRIDE; 329 }; // TrackObjectPresentationBillboard 330 331 332 // ============================================================================ 333 /** \ingroup tracks 334 * A track object representation that consists of a particle emitter 335 */ 336 class TrackObjectPresentationParticles : public TrackObjectPresentationSceneNode 337 { 338 private: 339 ParticleEmitter* m_emitter; 340 LODNode* m_lod_emitter_node; 341 std::string m_trigger_condition; 342 bool m_delayed_stop; 343 double m_delayed_stop_time; 344 345 public: 346 TrackObjectPresentationParticles(const XMLNode& xml_node, 347 scene::ISceneNode* parent); 348 virtual ~TrackObjectPresentationParticles(); 349 350 virtual void updateGraphics(float dt) OVERRIDE; 351 void triggerParticles(); 352 void stop(); 353 void stopIn(double delay); 354 void setRate(float rate); 355 // ------------------------------------------------------------------------ 356 /** Returns the trigger condition for this object. */ getTriggerCondition()357 std::string& getTriggerCondition() { return m_trigger_condition; } 358 }; // TrackObjectPresentationParticles 359 360 // ============================================================================ 361 /** \ingroup tracks 362 * A track object representation that consists of a light emitter 363 */ 364 class TrackObjectPresentationLight : public TrackObjectPresentationSceneNode 365 { 366 private: 367 video::SColor m_color; 368 float m_distance; 369 float m_energy; 370 public: 371 TrackObjectPresentationLight(const XMLNode& xml_node, 372 scene::ISceneNode* parent); 373 virtual ~TrackObjectPresentationLight(); getEnergy() const374 float getEnergy() const { return m_energy; } 375 virtual void setEnable(bool enabled) OVERRIDE; 376 void setEnergy(float energy); 377 }; // TrackObjectPresentationLight 378 379 // ============================================================================ 380 381 enum ActionTriggerType 382 { 383 TRIGGER_TYPE_POINT = 0, 384 TRIGGER_TYPE_CYLINDER = 1 385 }; 386 387 /** \ingroup tracks 388 * A track object representation that consists of an action trigger 389 */ 390 class TrackObjectPresentationActionTrigger : public TrackObjectPresentation 391 { 392 private: 393 /** For action trigger objects */ 394 std::string m_action, m_library_id, m_triggered_object, m_library_name; 395 396 float m_xml_reenable_timeout; 397 398 uint64_t m_reenable_timeout; 399 400 ActionTriggerType m_type; 401 402 public: 403 TrackObjectPresentationActionTrigger(const XMLNode& xml_node, 404 TrackObject* parent); 405 TrackObjectPresentationActionTrigger(const core::vector3df& xyz, 406 const std::string& scriptname, 407 float distance); 408 ~TrackObjectPresentationActionTrigger()409 virtual ~TrackObjectPresentationActionTrigger() {} 410 411 void onTriggerItemApproached(int kart_id); 412 // ------------------------------------------------------------------------ 413 /** Reset the trigger (i.e. sets it to active again). */ reset()414 virtual void reset() OVERRIDE 415 { m_reenable_timeout = StkTime::getMonoTimeMs(); } 416 // ------------------------------------------------------------------------ 417 /** Sets the trigger to be enabled or disabled. getMonoTimeMs is used to 418 * to avoid called update which duplicated in network rewinding. */ setEnable(bool status)419 virtual void setEnable(bool status) OVERRIDE 420 { 421 m_reenable_timeout = status ? StkTime::getMonoTimeMs() : 422 std::numeric_limits<uint64_t>::max(); 423 } 424 // ------------------------------------------------------------------------ setReenableTimeout(float time)425 void setReenableTimeout(float time) 426 { 427 m_reenable_timeout = 428 StkTime::getMonoTimeMs() + (uint64_t)(time * 1000.0f); 429 } 430 }; // class TrackObjectPresentationActionTrigger 431 432 433 #endif // TRACKOBJECTPRESENTATION_HPP 434 435