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_INSTANCED_DATA_HPP
19 #define HEADER_SP_INSTANCED_DATA_HPP
20 
21 #include "utils/mini_glm.hpp"
22 #include "utils/vec3.hpp"
23 #include <cassert>
24 #include <matrix4.h>
25 
26 using namespace irr;
27 
28 namespace SP
29 {
30 
31 class SPInstancedData
32 {
33 private:
34     char m_data[44];
35 
36 public:
37     // ------------------------------------------------------------------------
SPInstancedData()38     SPInstancedData()
39     {
40         memset(m_data, 0, 44);
41     }
42     // ------------------------------------------------------------------------
SPInstancedData(const core::matrix4 & model_mat,float texture_trans_x,float texture_trans_y,float hue,short skinning_offset)43     SPInstancedData(const core::matrix4& model_mat,
44                     float texture_trans_x, float texture_trans_y, float hue,
45                     short skinning_offset)
46     {
47         using namespace MiniGLM;
48         float position[3] = { model_mat[12], model_mat[13], model_mat[14] };
49         core::quaternion rotation(0.0f, 0.0f, 0.0f, 1.0f);
50         core::vector3df scale = model_mat.getScale();
51         if (scale.X != 0.0f && scale.Y != 0.0f && scale.Z != 0.0f)
52         {
53             core::matrix4 local_mat = model_mat;
54             local_mat[0] = local_mat[0] / scale.X / local_mat[15];
55             local_mat[1] = local_mat[1] / scale.X / local_mat[15];
56             local_mat[2] = local_mat[2] / scale.X / local_mat[15];
57             local_mat[4] = local_mat[4] / scale.Y / local_mat[15];
58             local_mat[5] = local_mat[5] / scale.Y / local_mat[15];
59             local_mat[6] = local_mat[6] / scale.Y / local_mat[15];
60             local_mat[8] = local_mat[8] / scale.Z / local_mat[15];
61             local_mat[9] = local_mat[9] / scale.Z / local_mat[15];
62             local_mat[10] = local_mat[10] / scale.Z / local_mat[15];
63             rotation = getQuaternion(local_mat);
64             // Conjugated quaternion in glsl
65             rotation.W = -rotation.W;
66         }
67         memcpy(m_data, position, 12);
68         memcpy(m_data + 12, &rotation, 16);
69         short s[4] = { toFloat16(scale.X), toFloat16(scale.Y),
70             toFloat16(scale.Z), 0 };
71         memcpy(m_data + 28, s, 8);
72         short tm[2] =
73             {
74                 short(texture_trans_x * 32767.0f),
75                 short(texture_trans_y * 32767.0f)
76             };
77         memcpy(m_data + 36, tm, 4);
78         memcpy(m_data + 40, &skinning_offset, 2);
79         short hue_packed = short(core::clamp(int(hue * 100.0f), 0, 100));
80         memcpy(m_data + 42, &hue_packed, 2);
81     }
82     // ------------------------------------------------------------------------
getData() const83     const void* getData() const                              { return m_data; }
84 
85 };
86 
87 
88 
89 }
90 
91 #endif
92