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