@@ -32,6 +32,7 @@ irr::scene::ISceneManager *g_menucloudsmgr = NULL;
32
32
33
33
static void cloud_3d_setting_changed (const std::string &settingname, void *data)
34
34
{
35
+ // TODO: only re-read cloud settings, not height or radius
35
36
((Clouds *)data)->readSettings ();
36
37
}
37
38
@@ -44,9 +45,10 @@ Clouds::Clouds(
44
45
):
45
46
scene::ISceneNode(parent, mgr, id),
46
47
m_seed(seed),
47
- m_camera_pos(0 ,0 ),
48
- m_time(0 ),
49
- m_camera_offset(0 ,0 ,0 )
48
+ m_camera_pos(0 .0f , 0 .0f ),
49
+ m_origin(0 .0f , 0 .0f ),
50
+ m_camera_offset(0 .0f , 0 .0f , 0 .0f ),
51
+ m_color(1 .0f , 1 .0f , 1 .0f , 1 .0f )
50
52
{
51
53
m_material.setFlag (video::EMF_LIGHTING, false );
52
54
// m_material.setFlag(video::EMF_BACK_FACE_CULLING, false);
@@ -57,14 +59,18 @@ Clouds::Clouds(
57
59
// m_material.MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
58
60
m_material.MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
59
61
62
+ m_params.density = 0 .4f ;
63
+ m_params.thickness = 16 .0f ;
64
+ m_params.color_bright = video::SColor (229 , 255 , 240 , 240 );
65
+ m_params.color_ambient = video::SColor (255 , 0 , 0 , 0 );
66
+ m_params.speed = v2f (0 .0f , -2 .0f );
67
+
60
68
m_passed_cloud_y = cloudheight;
61
69
readSettings ();
62
70
g_settings->registerChangedCallback (" enable_3d_clouds" ,
63
71
&cloud_3d_setting_changed, this );
64
72
65
- m_box = aabb3f (-BS*1000000 ,m_cloud_y-BS,-BS*1000000 ,
66
- BS*1000000 ,m_cloud_y+BS,BS*1000000 );
67
-
73
+ updateBox ();
68
74
}
69
75
70
76
Clouds::~Clouds ()
@@ -88,6 +94,10 @@ void Clouds::OnRegisterSceneNode()
88
94
89
95
void Clouds::render ()
90
96
{
97
+
98
+ if (m_params.density <= 0 .0f )
99
+ return ; // no need to do anything
100
+
91
101
video::IVideoDriver* driver = SceneManager->getVideoDriver ();
92
102
93
103
if (SceneManager->getSceneNodeRenderPass () != scene::ESNRP_TRANSPARENT)
@@ -107,15 +117,12 @@ void Clouds::render()
107
117
Clouds move from Z+ towards Z-
108
118
*/
109
119
110
- const float cloud_size = BS * 64 ;
111
- const v2f cloud_speed (0 , -BS * 2 );
120
+ static const float cloud_size = BS * 64 .0f ;
112
121
113
122
const float cloud_full_radius = cloud_size * m_cloud_radius_i;
114
123
115
- // Position of cloud noise origin in world coordinates
116
- v2f world_cloud_origin_pos_f = m_time * cloud_speed;
117
124
// Position of cloud noise origin from the camera
118
- v2f cloud_origin_from_camera_f = world_cloud_origin_pos_f - m_camera_pos;
125
+ v2f cloud_origin_from_camera_f = m_origin - m_camera_pos;
119
126
// The center point of drawing in the noise
120
127
v2f center_of_drawing_in_noise_f = -cloud_origin_from_camera_f;
121
128
// The integer center point of drawing in the noise
@@ -127,7 +134,7 @@ void Clouds::render()
127
134
v2f world_center_of_drawing_in_noise_f = v2f (
128
135
center_of_drawing_in_noise_i.X * cloud_size,
129
136
center_of_drawing_in_noise_i.Y * cloud_size
130
- ) + world_cloud_origin_pos_f ;
137
+ ) + m_origin ;
131
138
132
139
/* video::SColor c_top(128,b*240,b*240,b*255);
133
140
video::SColor c_side_1(128,b*230,b*230,b*255);
@@ -146,10 +153,6 @@ void Clouds::render()
146
153
c_bottom_f.r *= 0.80 ;
147
154
c_bottom_f.g *= 0.80 ;
148
155
c_bottom_f.b *= 0.80 ;
149
- c_top_f.a = 0.9 ;
150
- c_side_1_f.a = 0.9 ;
151
- c_side_2_f.a = 0.9 ;
152
- c_bottom_f.a = 0.9 ;
153
156
video::SColor c_top = c_top_f.toSColor ();
154
157
video::SColor c_side_1 = c_side_1_f.toSColor ();
155
158
video::SColor c_side_2 = c_side_2_f.toSColor ();
@@ -187,11 +190,14 @@ void Clouds::render()
187
190
zi + center_of_drawing_in_noise_i.Y
188
191
);
189
192
190
- double noise = noise2d_perlin (
193
+ float noise = noise2d_perlin (
191
194
(float )p_in_noise_i.X * cloud_size_noise,
192
195
(float )p_in_noise_i.Y * cloud_size_noise,
193
196
m_seed, 3 , 0.5 );
194
- grid[i] = (noise >= 0.4 );
197
+ // normalize to 0..1 (given 3 octaves)
198
+ static const float noise_bound = 1 .0f + 0 .5f + 0 .25f ;
199
+ float density = noise / noise_bound * 0 .5f + 0 .5f ;
200
+ grid[i] = (density < m_params.density );
195
201
}
196
202
}
197
203
@@ -236,8 +242,9 @@ void Clouds::render()
236
242
v[3].Color.setBlue(255);
237
243
}*/
238
244
239
- f32 rx = cloud_size/2 ;
240
- f32 ry = 8 * BS;
245
+ f32 rx = cloud_size / 2 .0f ;
246
+ // if clouds are flat, the top layer should be at the given height
247
+ f32 ry = m_enable_3d ? m_params.thickness * BS : 0 .0f ;
241
248
f32 rz = cloud_size / 2 ;
242
249
243
250
for (int i=0 ; i<num_faces_to_draw; i++)
@@ -265,8 +272,8 @@ void Clouds::render()
265
272
}
266
273
v[0 ].Pos .set (-rx, ry,-rz);
267
274
v[1 ].Pos .set ( rx, ry,-rz);
268
- v[2 ].Pos .set ( rx,-ry ,-rz);
269
- v[3 ].Pos .set (-rx,-ry ,-rz);
275
+ v[2 ].Pos .set ( rx, 0 ,-rz);
276
+ v[3 ].Pos .set (-rx, 0 ,-rz);
270
277
break ;
271
278
case 2 : // right
272
279
if (INAREA (xi + 1 , zi, m_cloud_radius_i)) {
@@ -280,8 +287,8 @@ void Clouds::render()
280
287
}
281
288
v[0 ].Pos .set ( rx, ry,-rz);
282
289
v[1 ].Pos .set ( rx, ry, rz);
283
- v[2 ].Pos .set ( rx,-ry , rz);
284
- v[3 ].Pos .set ( rx,-ry ,-rz);
290
+ v[2 ].Pos .set ( rx, 0 , rz);
291
+ v[3 ].Pos .set ( rx, 0 ,-rz);
285
292
break ;
286
293
case 3 : // front
287
294
if (INAREA (xi, zi + 1 , m_cloud_radius_i)) {
@@ -295,8 +302,8 @@ void Clouds::render()
295
302
}
296
303
v[0 ].Pos .set ( rx, ry, rz);
297
304
v[1 ].Pos .set (-rx, ry, rz);
298
- v[2 ].Pos .set (-rx,-ry , rz);
299
- v[3 ].Pos .set ( rx,-ry , rz);
305
+ v[2 ].Pos .set (-rx, 0 , rz);
306
+ v[3 ].Pos .set ( rx, 0 , rz);
300
307
break ;
301
308
case 4 : // left
302
309
if (INAREA (xi-1 , zi, m_cloud_radius_i)) {
@@ -310,22 +317,22 @@ void Clouds::render()
310
317
}
311
318
v[0 ].Pos .set (-rx, ry, rz);
312
319
v[1 ].Pos .set (-rx, ry,-rz);
313
- v[2 ].Pos .set (-rx,-ry ,-rz);
314
- v[3 ].Pos .set (-rx,-ry , rz);
320
+ v[2 ].Pos .set (-rx, 0 ,-rz);
321
+ v[3 ].Pos .set (-rx, 0 , rz);
315
322
break ;
316
323
case 5 : // bottom
317
324
for (int j=0 ;j<4 ;j++){
318
325
v[j].Color = c_bottom;
319
326
v[j].Normal .set (0 ,-1 ,0 );
320
327
}
321
- v[0 ].Pos .set ( rx,-ry , rz);
322
- v[1 ].Pos .set (-rx,-ry , rz);
323
- v[2 ].Pos .set (-rx,-ry ,-rz);
324
- v[3 ].Pos .set ( rx,-ry ,-rz);
328
+ v[0 ].Pos .set ( rx, 0 , rz);
329
+ v[1 ].Pos .set (-rx, 0 , rz);
330
+ v[2 ].Pos .set (-rx, 0 ,-rz);
331
+ v[3 ].Pos .set ( rx, 0 ,-rz);
325
332
break ;
326
333
}
327
334
328
- v3f pos (p0.X , m_cloud_y , p0.Y );
335
+ v3f pos (p0.X , m_params. height * BS , p0.Y );
329
336
pos -= intToFloat (m_camera_offset, BS);
330
337
331
338
for (u16 i=0 ; i<4 ; i++)
@@ -345,22 +352,25 @@ void Clouds::render()
345
352
346
353
void Clouds::step (float dtime)
347
354
{
348
- m_time += dtime;
355
+ m_origin = m_origin + dtime * BS * m_params. speed ;
349
356
}
350
357
351
- void Clouds::update (v2f camera_p, video::SColorf color )
358
+ void Clouds::update (v2f camera_p, video::SColorf color_diffuse )
352
359
{
353
360
m_camera_pos = camera_p;
354
- m_color = color;
355
- // m_brightness = brightness;
356
- // dstream<<"m_brightness="<<m_brightness<<std::endl;
361
+ m_color.r = MYMIN (MYMAX (color_diffuse.r * m_params.color_bright .getRed (),
362
+ m_params.color_ambient .getRed ()), 255 ) / 255 .0f ;
363
+ m_color.g = MYMIN (MYMAX (color_diffuse.r * m_params.color_bright .getGreen (),
364
+ m_params.color_ambient .getGreen ()), 255 ) / 255 .0f ;
365
+ m_color.b = MYMIN (MYMAX (color_diffuse.b * m_params.color_bright .getBlue (),
366
+ m_params.color_ambient .getBlue ()), 255 ) / 255 .0f ;
367
+ m_color.a = m_params.color_bright .getAlpha () / 255 .0f ;
357
368
}
358
369
359
370
void Clouds::readSettings ()
360
371
{
361
- m_cloud_y = BS * (m_passed_cloud_y ? m_passed_cloud_y :
372
+ m_params. height = (m_passed_cloud_y ? m_passed_cloud_y :
362
373
g_settings->getS16 (" cloud_height" ));
363
374
m_cloud_radius_i = g_settings->getU16 (" cloud_radius" );
364
375
m_enable_3d = g_settings->getBool (" enable_3d_clouds" );
365
376
}
366
-
0 commit comments