diff --git a/data/gfx/snow.xml b/data/gfx/snow.xml
index e141e7d3a..bd3eb7395 100644
--- a/data/gfx/snow.xml
+++ b/data/gfx/snow.xml
@@ -12,8 +12,8 @@
-
+
= 0);
- assert(j >= 0);
-
+ const int i = (curr.pos.X - track_x)/track_x_len*(HEIGHT_MAP_RESOLUTION);
+ const int j = (curr.pos.Z - track_z)/track_z_len*(HEIGHT_MAP_RESOLUTION);
+ if (i >= HEIGHT_MAP_RESOLUTION || j >= HEIGHT_MAP_RESOLUTION) continue;
+ if (i < 0 || j < 0) continue;
+
/*
+ // debug draw
core::vector3df lp = curr.pos;
core::vector3df lp2 = curr.pos;
lp2.Y = m_height_map[i][j] + 0.02f;
diff --git a/src/karts/kart.cpp b/src/karts/kart.cpp
index ea52fccc6..ecea63735 100644
--- a/src/karts/kart.cpp
+++ b/src/karts/kart.cpp
@@ -101,6 +101,7 @@ Kart::Kart (const std::string& ident, Track* track, int position,
m_saved_controller = NULL;
m_flying = false;
m_rain = NULL;
+ m_sky_particles_emitter= NULL;
m_view_blocked_by_plunger = 0;
@@ -334,10 +335,11 @@ Kart::~Kart()
sfx_manager->deleteSFX(m_beep_sound );
if(m_terrain_sound) sfx_manager->deleteSFX(m_terrain_sound);
if(m_previous_terrain_sound) sfx_manager->deleteSFX(m_previous_terrain_sound);
- if(m_terrain_particles) delete m_terrain_particles;
- if(m_nitro) delete m_nitro;
- if(m_slipstream) delete m_slipstream;
- if(m_rain) delete m_rain;
+ if(m_terrain_particles) delete m_terrain_particles;
+ if(m_nitro) delete m_nitro;
+ if(m_slipstream) delete m_slipstream;
+ if(m_rain) delete m_rain;
+ if(m_sky_particles_emitter) delete m_sky_particles_emitter;
delete m_shadow;
@@ -1609,7 +1611,22 @@ void Kart::loadData(RaceManager::KartType type, Track* track, bool animatedModel
}
}
- if (UserConfigParams::m_weather_effects && track->getWeatherType() == WEATHER_RAIN && type == RaceManager::KT_PLAYER)
+ if (type == RaceManager::KT_PLAYER && UserConfigParams::m_weather_effects &&
+ track->getSkyParticles() != NULL)
+ {
+ track->getSkyParticles()->setBoxSizeX(150.0f);
+ track->getSkyParticles()->setBoxSizeZ(150.0f);
+
+ m_sky_particles_emitter = new ParticleEmitter(track->getSkyParticles(), core::vector3df(0, 40.0f, 0),
+ getNode());
+
+ // FIXME: in multiplayer mode, this will result in several instances of the heightmap being calculated
+ // and kept in memory
+ m_sky_particles_emitter->addHeightMapAffector(track);
+ }
+
+ if (UserConfigParams::m_weather_effects && track->getWeatherType() == WEATHER_RAIN &&
+ type == RaceManager::KT_PLAYER)
{
// camera not yet available at this point
m_rain = new Rain(NULL, NULL);
diff --git a/src/karts/kart.hpp b/src/karts/kart.hpp
index 768997839..a926daf22 100644
--- a/src/karts/kart.hpp
+++ b/src/karts/kart.hpp
@@ -138,6 +138,8 @@ private:
/** Particle emitter used for terrain-specific effects (including but not limited too skidding). */
ParticleEmitter *m_terrain_particles;
+ ParticleEmitter *m_sky_particles_emitter;
+
/** Graphical effect when using a nitro. */
ParticleEmitter *m_nitro;
diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp
index e3204193f..29803bf28 100644
--- a/src/tracks/track.cpp
+++ b/src/tracks/track.cpp
@@ -78,7 +78,6 @@ Track::Track(std::string filename)
m_check_manager = NULL;
m_mini_map = NULL;
m_sky_particles = NULL;
- m_sky_particles_emitter = NULL;
m_sky_dx = 0.05f;
m_sky_dy = 0.0f;
m_weather_type = WEATHER_NONE;
@@ -92,7 +91,6 @@ Track::~Track()
if(m_quad_graph) delete m_quad_graph;
if(m_check_manager) delete m_check_manager;
if(m_mini_map) irr_driver->removeTexture(m_mini_map);
- if(m_sky_particles_emitter) delete m_sky_particles_emitter;
delete m_track_mesh;
delete m_gfx_effect_mesh;
} // ~Track
@@ -139,9 +137,6 @@ void Track::cleanup()
m_all_nodes.clear();
m_all_emitters.clearAndDeleteAll();
-
- if (m_sky_particles_emitter) delete m_sky_particles_emitter;
- m_sky_particles_emitter = NULL;
// The meshes stored in the scene nodes are dropped now.
// But to really remove all track meshes from memory
@@ -1022,20 +1017,6 @@ void Track::loadTrackModel(World* parent, unsigned int mode_id)
createPhysicsModel(main_track_count);
if (UserConfigParams::m_track_debug) m_quad_graph->createDebugMesh();
-
- if (UserConfigParams::m_weather_effects && m_sky_particles != NULL)
- {
- const float x = (m_aabb_max.getX() + m_aabb_min.getX())/2.0f;
- const float z = (m_aabb_max.getZ() + m_aabb_min.getZ())/2.0f;
- const float size_x = m_aabb_max.getX() - m_aabb_min.getX();
- const float size_z = m_aabb_max.getZ() - m_aabb_min.getZ();
- m_sky_particles->setBoxSizeX(size_x*0.5f); // FIXME: don't hardcode size reduction. We need to set the emission area in blender
- m_sky_particles->setBoxSizeZ(size_z*0.5f);
-
- // FIXME: don't hardcode height We need to set the emission area in blender
- m_sky_particles_emitter = new ParticleEmitter(m_sky_particles, core::vector3df(x, m_aabb_max.getY()*0.75f, z));
- m_sky_particles_emitter->addHeightMapAffector(this);
- }
// Only print warning if not in battle mode, since battle tracks don't have
// any quads or check lines.
@@ -1177,9 +1158,7 @@ bool Track::setTerrainHeight(Vec3 *pos) const
// ----------------------------------------------------------------------------
std::vector< std::vector > Track::buildHeightMap()
-{
- const int HEIGHT_MAP_RESOLUTION = 128;
-
+{
std::vector< std::vector > out(HEIGHT_MAP_RESOLUTION);
float x = m_aabb_min.getX();
diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp
index 8088a58e6..4c167b228 100644
--- a/src/tracks/track.hpp
+++ b/src/tracks/track.hpp
@@ -48,6 +48,8 @@ class TriangleMesh;
class World;
class XMLNode;
+const int HEIGHT_MAP_RESOLUTION = 256;
+
enum WeatherType
{
WEATHER_NONE,
@@ -143,9 +145,7 @@ private:
/** Use a special built-in wheather */
WeatherType m_weather_type;
-
- ParticleEmitter* m_sky_particles_emitter;
-
+
/** A simple class to keep information about a track mode. */
class TrackMode
{
@@ -314,7 +314,8 @@ public:
unsigned int getNumberOfStartPositions() const
{ return m_start_transforms.size(); }
- WeatherType getWeatherType () const { return m_weather_type; }
+ WeatherType getWeatherType () const { return m_weather_type; }
+ ParticleKind* getSkyParticles () { return m_sky_particles; }
std::vector< std::vector > buildHeightMap();