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