1 // SuperTuxKart - a fun racing game with go-kart
2 //
3 // Copyright (C) 2012-2015 SuperTuxKart-Team
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/stars.hpp"
20
21 #include "graphics/irr_driver.hpp"
22 #include "karts/abstract_kart.hpp"
23 #include "karts/kart_model.hpp"
24 #include "utils/constants.hpp"
25
26 #include <ISceneNode.h>
27 #include <IBillboardSceneNode.h>
28
29 #include <cmath>
30
31 const int STAR_AMOUNT = 7;
32 const float RADIUS = 0.7f;
33 const float STAR_SIZE = 0.4f;
34
Stars(AbstractKart * kart)35 Stars::Stars(AbstractKart *kart)
36 {
37 m_parent_kart_node = kart->getNode();
38 m_enabled = false;
39 m_center = core::vector3df(0.0f,
40 kart->getKartModel()->getModel()
41 ->getBoundingBox().MaxEdge.Y,
42 0.0f );
43
44 for (int n=0; n<STAR_AMOUNT; n++)
45 {
46 scene::ISceneNode* billboard =
47 irr_driver->addBillboard(core::dimension2df(STAR_SIZE, STAR_SIZE),
48 "starparticle.png", kart->getNode());
49 #ifdef DEBUG
50 billboard->setName("star");
51 #endif
52
53 billboard->setVisible(false);
54
55 m_nodes.push_back(billboard);
56 }
57 } // Stars
58
59 // ----------------------------------------------------------------------------
60
~Stars()61 Stars::~Stars()
62 {
63 const int nodeAmount = (int) m_nodes.size();
64 for (int n=0; n<nodeAmount; n++)
65 {
66 m_parent_kart_node->removeChild(m_nodes[n]);
67 }
68 } // ~Stars
69
70 // ----------------------------------------------------------------------------
71
showFor(float time)72 void Stars::showFor(float time)
73 {
74 m_enabled = true;
75 m_remaining_time = time;
76 m_fade_in_time = 1.0f;
77
78 const int node_amount = (int)m_nodes.size();
79 for (int n=0; n<node_amount; n++)
80 {
81 m_nodes[n]->setVisible(true);
82 ((scene::IBillboardSceneNode*)m_nodes[n])
83 ->setSize( core::dimension2df(0.01f, 0.01f) );
84 }
85
86 // set stars initial position
87 update(0);
88 } // showFor
89
90 // ----------------------------------------------------------------------------
91 /** Resets the stars, esp. disabling them at a restart.
92 */
reset()93 void Stars::reset()
94 {
95 // This will make the stars invisible and disable them
96 m_remaining_time = -1;
97 } // reset
98
99 // ----------------------------------------------------------------------------
100
update(float delta_t)101 void Stars::update(float delta_t)
102 {
103 if (!m_enabled) return;
104
105 m_remaining_time -= delta_t;
106 if (m_remaining_time < 0)
107 {
108 m_enabled = false;
109
110 const int node_amount = (int)m_nodes.size();
111 for (int n=0; n<node_amount; n++)
112 {
113 m_nodes[n]->setVisible(false);
114 }
115 return;
116 }
117
118 const int node_amount = (int)m_nodes.size();
119 for (int n=0; n<node_amount; n++)
120 {
121 // do one full rotation every 4 seconds (this "ranges" ranges
122 // from 0 to 1)
123 float angle = (m_remaining_time / 4.0f) - (int)(m_remaining_time / 4);
124
125 // each star must be at a different angle
126 angle += n * (1.0f / STAR_AMOUNT);
127
128 // keep angle in range [0, 1[
129 angle -= (int)angle;
130
131 float radius = RADIUS;
132
133
134 // manage "fade-in"
135 if (m_fade_in_time > 0.0f)
136 {
137 float fade = (1.0f - m_fade_in_time);
138
139 ((scene::IBillboardSceneNode*)m_nodes[n])->setSize(
140 core::dimension2d< f32 >(fade*STAR_SIZE, fade*STAR_SIZE) );
141
142 radius *= fade;
143 }
144 // manage "fade-out"
145 else if (m_remaining_time < 1.0f)
146 {
147 radius *= m_remaining_time;
148
149 ((scene::IBillboardSceneNode*)m_nodes[n])
150 ->setSize( core::dimension2df(m_remaining_time*STAR_SIZE,
151 m_remaining_time*STAR_SIZE) );
152 }
153
154 // Set position: X and Z are the position in the cirlce,
155 // the Y components shakes the stars up and down like falling coin
156 core::vector3df offset(std::cos(angle*M_PI*2.0f)*radius,
157 std::cos(angle*M_PI*2.0f+m_remaining_time*4.0f)
158 *radius*0.25f,
159 std::sin(angle*M_PI*2.0f)*radius );
160 m_nodes[n]->setPosition(m_center + offset);
161 } // end for
162
163 if (m_fade_in_time > 0.0f) m_fade_in_time -= delta_t;
164 } // update
165
166