diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp index a755d6f3e..cde72b919 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.cpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.cpp @@ -105,7 +105,7 @@ std::vector g_flips_data; void ObjectData::init(const irr::scene::SParticle& particle, int material_id, const btQuaternion& rotation, const irr::core::vector3df& view_position, bool flips, - bool backface_culling) + bool sky_particle, bool backface_culling) { memcpy(&m_translation_x, &particle.pos, sizeof(float) * 3); float scale_x = particle.size.Width / 2.0f; @@ -152,6 +152,16 @@ void ObjectData::init(const irr::scene::SParticle& particle, int material_id, scale_x = -scale_x; } } + else if (sky_particle) + { + irr::core::vector3df diff = particle.pos - view_position; + float angle = atan2f(diff.X, diff.Z); + btQuaternion rotated(btVector3(0.0f, 1.0f, 0.0f), angle); + rotated.normalize(); + // Conjugated quaternion in glsl + rotated[3] = -rotated[3]; + memcpy(m_rotation, &rotated[0], sizeof(btQuaternion)); + } else memcpy(m_rotation, &rotation[0], sizeof(btQuaternion)); m_scale_x = scale_x; @@ -505,11 +515,12 @@ start: } ObjectData* obj = (ObjectData*)mapped_addr; bool flips = pn->getFlips(); + bool sky_particle = pn->isSkyParticle(); for (unsigned i = 0; i < ps; i++) { obj[i].init(particles[i], material_id, m_billboard_rotation, m_view_position, flips, - settings.m_backface_culling); + sky_particle, settings.m_backface_culling); written_size += sizeof(ObjectData); mapped_addr += sizeof(ObjectData); } diff --git a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp index 36c39ad88..6c6547cc7 100644 --- a/lib/graphics_engine/src/ge_vulkan_draw_call.hpp +++ b/lib/graphics_engine/src/ge_vulkan_draw_call.hpp @@ -62,7 +62,7 @@ struct ObjectData void init(const irr::scene::SParticle& particle, int material_id, const btQuaternion& rotation, const irr::core::vector3df& view_position, bool flips, - bool backface_culling); + bool sky_particle, bool backface_culling); }; struct PipelineSettings diff --git a/lib/irrlicht/include/IParticleSystemSceneNode.h b/lib/irrlicht/include/IParticleSystemSceneNode.h index 726db601d..f1f71899e 100644 --- a/lib/irrlicht/include/IParticleSystemSceneNode.h +++ b/lib/irrlicht/include/IParticleSystemSceneNode.h @@ -506,6 +506,7 @@ public: virtual core::array& getParticles() = 0; virtual bool getFlips() const { return false; } + virtual bool isSkyParticle() const { return false; } }; } // end namespace scene diff --git a/src/graphics/stk_particle.hpp b/src/graphics/stk_particle.hpp index a33076955..a72d0a122 100644 --- a/src/graphics/stk_particle.hpp +++ b/src/graphics/stk_particle.hpp @@ -160,6 +160,8 @@ public: assert(m_flips_buffer != 0); return m_flips_buffer; } + // ------------------------------------------------------------------------ + virtual bool isSkyParticle() const { return m_hm != NULL; } }; #endif