1 //
2 // SuperTuxKart - a fun racing game with go-kart
3 // Copyright (C) 2009-2013 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 #include "graphics/shadow.hpp"
20 #include "karts/abstract_kart.hpp"
21 #include "karts/skidding.hpp"
22 #include "graphics/sp/sp_shader_manager.hpp"
23 #include "graphics/sp/sp_dynamic_draw_call.hpp"
24 #include "physics/btKart.hpp"
25 #include "utils/mini_glm.hpp"
26 #include "utils/vec3.hpp"
27
28 #ifndef SERVER_ONLY
29
Shadow(Material * shadow_mat,const AbstractKart & kart)30 Shadow::Shadow(Material* shadow_mat, const AbstractKart& kart)
31 : m_dy_dc(NULL), m_shadow_enabled(false), m_kart(kart)
32 {
33 m_dy_dc = std::make_shared<SP::SPDynamicDrawCall>
34 (scene::EPT_TRIANGLE_STRIP,
35 SP::SPShaderManager::get()->getSPShader("alphablend"), shadow_mat);
36
37 m_dy_dc->getVerticesVector().resize(4);
38 video::S3DVertexSkinnedMesh* v = m_dy_dc->getVerticesVector().data();
39 v[0].m_all_uvs[0] = 0;
40 v[0].m_all_uvs[1] = 0;
41 v[1].m_all_uvs[0] = 15360;
42 v[1].m_all_uvs[1] = 0;
43 v[3].m_all_uvs[0] = 15360;
44 v[3].m_all_uvs[1] = 15360;
45 v[2].m_all_uvs[0] = 0;
46 v[2].m_all_uvs[1] = 15360;
47
48 m_dy_dc->setVisible(false);
49 SP::addDynamicDrawCall(m_dy_dc);
50 } // Shadow
51
52 // ----------------------------------------------------------------------------
~Shadow()53 Shadow::~Shadow()
54 {
55 m_dy_dc->removeFromSP();
56 } // ~Shadow
57
58 // ----------------------------------------------------------------------------
59 /** Updates the simulated shadow. It takes the 4 suspension lengths of vehicle
60 * from ground to position the shadow quad exactly on the ground.
61 * It also disables the shadow if requested (e.g. if the kart is in the air).
62 * \param enabled If the shadow should be shown or not.
63 */
update(bool enabled)64 void Shadow::update(bool enabled)
65 {
66 if (enabled != m_shadow_enabled)
67 {
68 m_shadow_enabled = enabled;
69 if (m_shadow_enabled)
70 {
71 m_dy_dc->setVisible(true);
72 }
73 else
74 {
75 m_dy_dc->setVisible(false);
76 }
77 }
78 if (m_shadow_enabled)
79 {
80 video::S3DVertexSkinnedMesh* v = m_dy_dc->getVerticesVector().data();
81 v[0].m_position.X = -1; v[0].m_position.Z = 1; v[0].m_position.Y = 0;
82 v[1].m_position.X = 1; v[1].m_position.Z = 1; v[1].m_position.Y = 0;
83 v[2].m_position.X = -1; v[2].m_position.Z = -1; v[2].m_position.Y = 0;
84 v[3].m_position.X = 1; v[3].m_position.Z = -1; v[3].m_position.Y = 0;
85 btTransform kart_trans = m_kart.getSmoothedTrans();
86 btTransform skidding_rotation;
87 skidding_rotation.setOrigin(Vec3(0, 0, 0));
88 skidding_rotation.setRotation
89 (btQuaternion(m_kart.getSkidding()->getVisualSkidRotation(), 0, 0));
90 kart_trans *= skidding_rotation;
91 for (unsigned i = 0; i < 4; i++)
92 {
93 const btWheelInfo& wi = m_kart.getVehicle()->getWheelInfo(i);
94 Vec3 up_vector = kart_trans.getBasis().getColumn(1);
95 up_vector = up_vector * (wi.m_raycastInfo.m_suspensionLength - 0.02f);
96 Vec3 pos = kart_trans(Vec3(v[i].m_position)) - up_vector;
97 v[i].m_position = pos.toIrrVector();
98 v[i].m_normal = MiniGLM::compressVector3
99 (Vec3(wi.m_raycastInfo.m_contactNormalWS).toIrrVector());
100 }
101 m_dy_dc->recalculateBoundingBox();
102 m_dy_dc->setUpdateOffset(0);
103 }
104 } // update
105
106 #endif
107