1 // 2 // SuperTuxKart - a fun racing game with go-kart 3 // Copyright (C) 2009-2015 Joerg Henrichs 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 #ifndef HEADER_TRACK_OBJECT_HPP 20 #define HEADER_TRACK_OBJECT_HPP 21 22 #include <vector3d.h> 23 24 #include "physics/physical_object.hpp" 25 #include "scriptengine/scriptvec3.hpp" 26 #include "tracks/track_object_presentation.hpp" 27 #include "utils/cpp2011.hpp" 28 #include "utils/vec3.hpp" 29 #include <string> 30 #include "animations/three_d_animation.hpp" 31 32 #include <memory> 33 34 class ModelDefinitionLoader; 35 class RenderInfo; 36 class ThreeDAnimation; 37 class XMLNode; 38 39 /** 40 * \ingroup tracks 41 * This is a base object for any separate object on the track, which 42 * might also have a skeletal animation. This is used by objects that 43 * have an IPO animation, as well as physical objects. 44 */ 45 class TrackObject 46 { 47 //public: 48 // The different type of track objects: physical objects, graphical 49 // objects (without a physical representation) - the latter might be 50 // eye candy (to reduce work for physics), ... 51 //enum TrackObjectType {TO_PHYSICAL, TO_GRAPHICAL}; 52 53 private: 54 /** True if the object is currently being displayed. */ 55 bool m_enabled; 56 57 TrackObjectPresentation* m_presentation; 58 59 std::string m_name; 60 61 std::string m_id; 62 63 std::shared_ptr<RenderInfo> m_render_info; 64 65 protected: 66 67 /** The initial XYZ position of the object. */ 68 core::vector3df m_init_xyz; 69 70 /** The initial hpr of the object. */ 71 core::vector3df m_init_hpr; 72 73 /** The initial scale of the object. */ 74 core::vector3df m_init_scale; 75 76 /** LOD group this object is part of, if it is LOD */ 77 std::string m_lod_group; 78 79 std::string m_interaction; 80 81 std::string m_type; 82 83 bool m_soccer_ball; 84 85 /** True if a kart can drive on this object. This will */ 86 bool m_is_driveable; 87 88 std::shared_ptr<PhysicalObject> m_physical_object; 89 90 ThreeDAnimation* m_animator; 91 92 TrackObject* m_parent_library; 93 94 std::vector<TrackObject*> m_movable_children; 95 std::vector<TrackObject*> m_children; 96 97 bool m_initially_visible; 98 99 std::string m_visibility_condition; 100 101 void init(const XMLNode &xml_node, scene::ISceneNode* parent, 102 ModelDefinitionLoader& model_def_loader, 103 TrackObject* parent_library); 104 105 public: 106 TrackObject(const XMLNode &xml_node, 107 scene::ISceneNode* parent, 108 ModelDefinitionLoader& model_def_loader, 109 TrackObject* parent_library); 110 111 TrackObject(const core::vector3df& xyz, 112 const core::vector3df& hpr, 113 const core::vector3df& scale, 114 const char* interaction, 115 TrackObjectPresentation* presentation, 116 bool is_dynamic, 117 const PhysicalObject::Settings* physicsSettings); 118 virtual ~TrackObject(); 119 virtual void update(float dt); 120 virtual void updateGraphics(float dt); 121 virtual void resetAfterRewind(); 122 void move(const core::vector3df& xyz, const core::vector3df& hpr, 123 const core::vector3df& scale, bool updateRigidBody, 124 bool isAbsoluteCoord); 125 126 virtual void reset(); 127 const core::vector3df& getPosition() const; 128 const core::vector3df getAbsolutePosition() const; 129 const core::vector3df getAbsoluteCenterPosition() const; 130 const core::vector3df& getRotation() const; 131 const core::vector3df& getScale() const; 132 bool castRay(const btVector3 &from, 133 const btVector3 &to, btVector3 *hit_point, 134 const Material **material, btVector3 *normal, 135 bool interpolate_normal) const; 136 getParentLibrary()137 TrackObject* getParentLibrary() 138 { 139 return m_parent_library; 140 } 141 142 // ------------------------------------------------------------------------ 143 /** To finish object constructions. Called after the track model 144 * is ready. */ 145 virtual void onWorldReady(); 146 // ------------------------------------------------------------------------ 147 /** Called when an explosion happens. As a default does nothing, will 148 * e.g. be overwritten by physical objects etc. */ handleExplosion(const Vec3 & pos,bool directHit)149 virtual void handleExplosion(const Vec3& pos, bool directHit) {}; setID(std::string obj_id)150 void setID(std::string obj_id) { m_id = obj_id; } 151 152 // ------------------------------------------------------------------------ getLodGroup() const153 const std::string& getLodGroup() const { return m_lod_group; } 154 // ------------------------------------------------------------------------ getType() const155 const std::string& getType() const { return m_type; } 156 // ------------------------------------------------------------------------ getName() const157 const std::string getName() const { return m_name; } 158 // ------------------------------------------------------------------------ getID() const159 const std::string getID() const { return m_id; } 160 // ------------------------------------------------------------------------ getInteraction() const161 const std::string getInteraction() const { return m_interaction; } 162 // ------------------------------------------------------------------------ isEnabled() const163 bool isEnabled() const { return m_enabled; } 164 // ------------------------------------------------------------------------ isSoccerBall() const165 bool isSoccerBall() const { return m_soccer_ball; } 166 // ------------------------------------------------------------------------ getPhysicalObject() const167 const PhysicalObject* getPhysicalObject() const 168 { return m_physical_object.get(); } 169 // ------------------------------------------------------------------------ getPhysicalObject()170 PhysicalObject* getPhysicalObject() { return m_physical_object.get(); } 171 // ------------------------------------------------------------------------ getInitXYZ() const172 const core::vector3df getInitXYZ() const { return m_init_xyz; } 173 // ------------------------------------------------------------------------ getInitRotation() const174 const core::vector3df getInitRotation() const { return m_init_hpr; } 175 // ------------------------------------------------------------------------ getInitScale() const176 const core::vector3df getInitScale() const { return m_init_scale; } 177 // ------------------------------------------------------------------------ 178 template<typename T> getPresentation()179 T* getPresentation() { return dynamic_cast<T*>(m_presentation); } 180 // ------------------------------------------------------------------------ 181 template<typename T> getPresentation() const182 const T* getPresentation() const { return dynamic_cast<T*>(m_presentation); } 183 // ------------------------------------------------------------------------ 184 // Methods usable by scripts 185 /** 186 * \addtogroup Scripting 187 * @{ 188 * \addtogroup Scripting_Track Track 189 * @{ 190 * \addtogroup Scripting_TrackObject TrackObject (script binding) 191 * @{ 192 */ 193 /** Should only be used on mesh track objects. 194 * On the script side, the returned object is of type : @ref Scripting_Mesh 195 */ 196 scene::IAnimatedMeshSceneNode* getMesh(); 197 /** Should only be used on particle emitter track objects. 198 * On the script side, the returned object is of type : @ref Scripting_ParticleEmitter 199 */ getParticleEmitter()200 TrackObjectPresentationParticles* getParticleEmitter() { return getPresentation<TrackObjectPresentationParticles>(); } 201 /** Should only be used on sound emitter track objects. 202 * On the script side, the returned object is of type : @ref Scripting_SoundEmitter 203 */ getSoundEmitter()204 TrackObjectPresentationSound* getSoundEmitter(){ return getPresentation<TrackObjectPresentationSound>(); } 205 /** Should only be used on sound emitter track objects. 206 * On the script side, the returned object is of type : @ref Scripting_Light 207 */ getLight()208 TrackObjectPresentationLight* getLight() { return getPresentation<TrackObjectPresentationLight>(); } 209 // For angelscript. Needs to be named something different than getAnimator since it's overloaded. 210 /** Should only be used on TrackObjects that use curve-based animation. 211 * On the script side, the returned object is of type : @ref Scripting_Animator 212 */ getIPOAnimator()213 ThreeDAnimation* getIPOAnimator() { return m_animator; } 214 // For angelscript. Needs to be named something different than getPhysicalObject since it's overloaded. 215 /** Get the physics representation of an object. 216 * On the script side, the returned object is of type : @ref Scripting_PhysicalObject 217 */ getPhysics()218 PhysicalObject* getPhysics() { return m_physical_object.get(); } 219 /** Hide or show the object */ 220 void setEnabled(bool mode); 221 222 void moveTo(const Scripting::SimpleVec3* pos, bool isAbsoluteCoord); 223 /* @} */ 224 /* @} */ 225 /* @} */ 226 227 void resetEnabled(); 228 // ------------------------------------------------------------------------ getAnimator()229 ThreeDAnimation* getAnimator() { return m_animator; } 230 // ------------------------------------------------------------------------ getAnimator() const231 const ThreeDAnimation* getAnimator() const { return m_animator; } 232 // ------------------------------------------------------------------------ 233 /* Return true if it has animator or its parent library has */ hasAnimatorRecursively() const234 bool hasAnimatorRecursively() const 235 { 236 if (m_animator) 237 return true; 238 if (!m_parent_library) 239 return false; 240 return m_parent_library->hasAnimatorRecursively(); 241 } 242 // ------------------------------------------------------------------------ setPaused(bool mode)243 void setPaused(bool mode){ m_animator->setPaused(mode); } 244 // ------------------------------------------------------------------------ setInitiallyVisible(bool val)245 void setInitiallyVisible(bool val) { m_initially_visible = val; } 246 // ------------------------------------------------------------------------ 247 /** Returns if a kart can drive on this object. */ isDriveable() const248 bool isDriveable() const { return m_is_driveable; } 249 // ------------------------------------------------------------------------ 250 /** Used along the "extract movable nodes out of library objects" hack, used 251 * to still preserve the parent-child relationship 252 */ 253 void addMovableChild(TrackObject* child); 254 // ------------------------------------------------------------------------ 255 void addChild(TrackObject* child); 256 // ------------------------------------------------------------------------ getMovableChildren()257 std::vector<TrackObject*>& getMovableChildren() { return m_movable_children; } 258 // ------------------------------------------------------------------------ getChildren()259 std::vector<TrackObject*>& getChildren() { return m_children; } 260 // ------------------------------------------------------------------------ 261 void movePhysicalBodyToGraphicalNode(const core::vector3df& xyz, const core::vector3df& hpr); 262 // ------------------------------------------------------------------------ 263 bool joinToMainTrack(); 264 // ------------------------------------------------------------------------ 265 TrackObject* cloneToChild(); 266 LEAK_CHECK() 267 }; // TrackObject 268 269 #endif 270