From f7f01c144aa23a7bbd590f50e9aa39a35afcab20 Mon Sep 17 00:00:00 2001 From: auria Date: Mon, 28 Feb 2011 00:59:02 +0000 Subject: [PATCH] Stop snowing inside tunnels git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7767 178a84e3-b1eb-0310-8ba1-8eac791a3b58 --- src/graphics/particle_emitter.cpp | 80 +++++++++++++++++++++++++++++++ src/graphics/particle_emitter.hpp | 3 ++ src/tracks/track.cpp | 71 +++++++++++++++++++++++++++ src/tracks/track.hpp | 2 + 4 files changed, 156 insertions(+) diff --git a/src/graphics/particle_emitter.cpp b/src/graphics/particle_emitter.cpp index 083e2b68b..b15636e8b 100644 --- a/src/graphics/particle_emitter.cpp +++ b/src/graphics/particle_emitter.cpp @@ -24,6 +24,7 @@ #include "graphics/particle_kind.hpp" #include "graphics/irr_driver.hpp" #include "io/file_manager.hpp" +#include "tracks/track.hpp" #include "utils/constants.hpp" class FadeAwayAffector : public scene::IParticleAffector @@ -41,7 +42,9 @@ public: m_end_fading = end; assert(m_end_fading >= m_start_fading); } // FadeAwayAffector + // ------------------------------------------------------------------------ + virtual void affect(u32 now, scene::SParticle* particlearray, u32 count) { scene::ICameraSceneNode* curr_cam = @@ -76,6 +79,7 @@ public: } // affect // ------------------------------------------------------------------------ + virtual scene::E_PARTICLE_AFFECTOR_TYPE getType() const { // FIXME: this method seems to make sense only for built-in affectors @@ -84,7 +88,74 @@ public: }; // FadeAwayAffector + // ============================================================================ + +class HeightMapCollisionAffector : public scene::IParticleAffector +{ + std::vector< std::vector > m_height_map; + Track* m_track; + +public: + HeightMapCollisionAffector(Track* t) : m_height_map(t->buildHeightMap()) + { + m_track = t; + } + + virtual void affect(u32 now, scene::SParticle* particlearray, u32 count) + { + const Vec3* aabb_min; + const Vec3* aabb_max; + m_track->getAABB(&aabb_min, &aabb_max); + float track_x = aabb_min->getX(); + float track_z = aabb_min->getZ(); + const float track_x_len = aabb_max->getX() - aabb_min->getX(); + const float track_z_len = aabb_max->getZ() - aabb_min->getZ(); + + for (unsigned int n=0; n= 0); + assert(j >= 0); + + /* + core::vector3df lp = curr.pos; + core::vector3df lp2 = curr.pos; + lp2.Y = m_height_map[i][j] + 0.02f; + + irr_driver->getVideoDriver()->draw3DLine(lp, lp2, video::SColor(255,255,0,0)); + core::vector3df lp3 = lp2; + lp3.X += 0.1f; + lp3.Y += 0.02f; + lp3.Z += 0.1f; + lp2.X -= 0.1f; + lp2.Y -= 0.02f; + lp2.Z -= 0.1f; + irr_driver->getVideoDriver()->draw3DBox(core::aabbox3d< f32 >(lp2, lp3), video::SColor(255,255,0,0)); + */ + + if (curr.pos.Y < m_height_map[i][j]) + { + //curr.color = video::SColor(255,255,0,0); + curr.endTime = curr.startTime; // destroy particle + } + } + } + + virtual scene::E_PARTICLE_AFFECTOR_TYPE getType() const + { + // FIXME: this method seems to make sense only for built-in affectors + return scene::EPAT_FADE_OUT; + } +}; + + +// ============================================================================ + ParticleEmitter::ParticleEmitter(const ParticleKind* type, const Vec3 &position, scene::ISceneNode* parent) @@ -297,3 +368,12 @@ void ParticleEmitter::setParticleType(const ParticleKind* type) faa->drop(); } } // setParticleType + +//----------------------------------------------------------------------------- + +void ParticleEmitter::addHeightMapAffector(Track* t) +{ + HeightMapCollisionAffector* hmca = new HeightMapCollisionAffector(t); + m_node->addAffector(hmca); + hmca->drop(); +} diff --git a/src/graphics/particle_emitter.hpp b/src/graphics/particle_emitter.hpp index e5a13ecae..932e61960 100644 --- a/src/graphics/particle_emitter.hpp +++ b/src/graphics/particle_emitter.hpp @@ -28,6 +28,7 @@ using namespace irr; class Material; class ParticleKind; +class Track; /** * \brief manages smoke particle effects @@ -68,6 +69,8 @@ public: void setParticleType(const ParticleKind* p); scene::IParticleSystemSceneNode* getNode() { return m_node; } + + void addHeightMapAffector(Track* t); }; #endif diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index d1af61c80..e3204193f 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -1034,6 +1034,7 @@ void Track::loadTrackModel(World* parent, unsigned int mode_id) // 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 @@ -1172,3 +1173,73 @@ bool Track::setTerrainHeight(Vec3 *pos) const } return false; } // setTerrainHeight + +// ---------------------------------------------------------------------------- + +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(); + const float x_len = m_aabb_max.getX() - m_aabb_min.getX(); + const float z_len = m_aabb_max.getZ() - m_aabb_min.getZ(); + + const float x_step = x_len/HEIGHT_MAP_RESOLUTION; + const float z_step = z_len/HEIGHT_MAP_RESOLUTION; + + btVector3 hitpoint; + const Material* material; + btVector3 normal; + + for (int i=0; icastRay(pos, to, &hitpoint, &material, &normal); + z += z_step; + + out[i][j] = hitpoint.getY(); + + /* + if (out[i][j] < -50) + { + printf(" "); + } + else if (out[i][j] < -25) + { + printf("`"); + } + else if (out[i][j] < 0) + { + printf("-"); + } + else if (out[i][j] < 25) + { + printf(":"); + } + else if (out[i][j] < 50) + { + printf("!"); + } + else if (out[i][j] < 100) + { + printf("#"); + } + */ + } + + //printf("\n"); + x += x_step; + } + + return out; +} diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 25a483d89..8088a58e6 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -316,6 +316,8 @@ public: WeatherType getWeatherType () const { return m_weather_type; } + std::vector< std::vector > buildHeightMap(); + }; // class Track #endif