1 //  SuperTuxKart - a fun racing game with go-kart
2 //  Copyright (C) 2018 SuperTuxKart-Team
3 //
4 //  This program is free software; you can redistribute it and/or
5 //  modify it under the terms of the GNU General Public License
6 //  as published by the Free Software Foundation; either version 3
7 //  of the License, or (at your option) any later version.
8 //
9 //  This program is distributed in the hope that it will be useful,
10 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
11 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 //  GNU General Public License for more details.
13 //
14 //  You should have received a copy of the GNU General Public License
15 //  along with this program; if not, write to the Free Software
16 //  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
17 
18 #ifndef HEADER_SP_MESH_NODE_HPP
19 #define HEADER_SP_MESH_NODE_HPP
20 
21 #include "../../../lib/irrlicht/source/Irrlicht/CAnimatedMeshSceneNode.h"
22 #include <array>
23 #include <cassert>
24 #include <string>
25 #include <memory>
26 #include <vector>
27 #include <unordered_map>
28 
29 using namespace irr;
30 using namespace scene;
31 class RenderInfo;
32 
33 namespace SP
34 {
35 class SPMesh;
36 class SPShader;
37 
38 class SPMeshNode : public irr::scene::CAnimatedMeshSceneNode
39 {
40 private:
41     std::vector<std::shared_ptr<RenderInfo> > m_render_info;
42 
43     std::shared_ptr<RenderInfo> m_first_render_info;
44 
45     std::unordered_map<std::string, IBoneSceneNode*> m_joint_nodes;
46 
47     SPMesh* m_mesh;
48 
49     int m_skinning_offset;
50 
51     bool m_animated;
52 
53     bool m_is_in_shadowpass;
54 
55     std::vector<std::array<float, 16> > m_skinning_matrices;
56 
57     video::SColorf m_glow_color;
58 
59     std::vector<std::array<float, 2> > m_texture_matrices;
60 
61     // ------------------------------------------------------------------------
62     void cleanRenderInfo();
63     // ------------------------------------------------------------------------
cleanJoints()64     void cleanJoints()
65     {
66         for (auto& p : m_joint_nodes)
67         {
68             removeChild(p.second);
69         }
70         m_joint_nodes.clear();
71         m_skinning_matrices.clear();
72     }
73 
74 public:
75     // ------------------------------------------------------------------------
76     SPMeshNode(IAnimatedMesh* mesh, ISceneNode* parent, ISceneManager* mgr,
77                s32 id, const std::string& debug_name,
78                const core::vector3df& position = core::vector3df(),
79                const core::vector3df& rotation = core::vector3df(),
80                const core::vector3df& scale = core::vector3df(1, 1, 1),
81                std::shared_ptr<RenderInfo> render_info = nullptr);
82     // ------------------------------------------------------------------------
83     ~SPMeshNode();
84     // ------------------------------------------------------------------------
render()85     virtual void render() {}
86     // ------------------------------------------------------------------------
87     virtual void setMesh(irr::scene::IAnimatedMesh* mesh);
88     // ------------------------------------------------------------------------
89     virtual void OnAnimate(u32 time_ms);
90     // ------------------------------------------------------------------------
animateJoints(bool calculate_absolute_positions=true)91     virtual void animateJoints(bool calculate_absolute_positions = true) {}
92     // ------------------------------------------------------------------------
93     virtual irr::scene::IMesh* getMeshForCurrentFrame();
94     // ------------------------------------------------------------------------
95     virtual IBoneSceneNode* getJointNode(const c8* joint_name);
96     // ------------------------------------------------------------------------
getJointNode(u32 joint_id)97     virtual IBoneSceneNode* getJointNode(u32 joint_id)
98     {
99         // SPM uses joint_name only
100         assert(false);
101         return NULL;
102     }
103     // ------------------------------------------------------------------------
setJointMode(E_JOINT_UPDATE_ON_RENDER mode)104     virtual void setJointMode(E_JOINT_UPDATE_ON_RENDER mode) {}
105     // ------------------------------------------------------------------------
checkJoints()106     virtual void checkJoints() {}
107     // ------------------------------------------------------------------------
getSPM() const108     SPMesh* getSPM() const { return m_mesh; }
109     // ------------------------------------------------------------------------
110     int getTotalJoints() const;
111     // ------------------------------------------------------------------------
setSkinningOffset(int offset)112     void setSkinningOffset(int offset)          { m_skinning_offset = offset; }
113     // ------------------------------------------------------------------------
getSkinningOffset() const114     int getSkinningOffset() const                 { return m_skinning_offset; }
115     // ------------------------------------------------------------------------
116     void setAnimationState(bool val);
117     // ------------------------------------------------------------------------
getAnimationState() const118     bool getAnimationState() const                       { return m_animated; }
119     // ------------------------------------------------------------------------
isInShadowPass() const120     bool isInShadowPass() const                  { return m_is_in_shadowpass; }
121     // ------------------------------------------------------------------------
setInShadowPass(const bool is_in_shadowpass)122     void setInShadowPass(const bool is_in_shadowpass)
123     {
124         m_is_in_shadowpass = is_in_shadowpass;
125     }
126     // ------------------------------------------------------------------------
127     SPShader* getShader(unsigned mesh_buffer_id) const;
128     // ------------------------------------------------------------------------
getSkinningMatrices() const129     const std::array<float, 16>* getSkinningMatrices() const
130                                          { return m_skinning_matrices.data(); }
131     // ------------------------------------------------------------------------
getRenderInfo(unsigned mb_id) const132     RenderInfo* getRenderInfo(unsigned mb_id) const
133     {
134         if (m_render_info.size() > mb_id && m_render_info[mb_id].get())
135         {
136             return m_render_info[mb_id].get();
137         }
138         return NULL;
139     }
140     // ------------------------------------------------------------------------
resetFirstRenderInfo(std::shared_ptr<RenderInfo> ri)141     void resetFirstRenderInfo(std::shared_ptr<RenderInfo> ri)
142     {
143         m_render_info.clear();
144         m_first_render_info = ri;
145         m_render_info.resize(getMesh()->getMeshBufferCount(),
146             m_first_render_info);
147     }
148     // ------------------------------------------------------------------------
setGlowColor(const video::SColorf & color)149     void setGlowColor(const video::SColorf& color)    { m_glow_color = color; }
150     // ------------------------------------------------------------------------
getGlowColor() const151     const video::SColorf& getGlowColor() const         { return m_glow_color; }
152     // ------------------------------------------------------------------------
hasGlowColor() const153     bool hasGlowColor() const
154     {
155         return !(m_glow_color.r == 0.0f && m_glow_color.g == 0.0f &&
156             m_glow_color.b == 0.0f);
157     }
158     // ------------------------------------------------------------------------
getTextureMatrix(unsigned mb_id)159     std::array<float, 2>& getTextureMatrix(unsigned mb_id)
160     {
161         assert(mb_id < m_texture_matrices.size());
162         return m_texture_matrices[mb_id];
163     }
164     // ------------------------------------------------------------------------
setTextureMatrix(unsigned mb_id,const std::array<float,2> & tm)165     void setTextureMatrix(unsigned mb_id, const std::array<float, 2>& tm)
166     {
167         assert(mb_id < m_texture_matrices.size());
168         m_texture_matrices[mb_id] = tm;
169     }
170 };
171 
172 }
173 
174 #endif
175