<commit_before>#include <osgParticle/ParticleSystem>

#include <vector>

#include <osg/Drawable>
#include <osg/CopyOp>
#include <osg/State>
#include <osg/Matrix>
#include <osg/GL>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/BlendFunc>
#include <osg/TexEnv>
#include <osg/Material>
#include <osg/PointSprite>
#include <osg/Program>
#include <osg/Notify>
#include <osg/io_utils>

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgUtil/CullVisitor>

#define USE_LOCAL_SHADERS

static double distance(const osg::Vec3& coord, const osg::Matrix& matrix)
{
    // copied from CullVisitor.cpp
    return -(coord[0]*matrix(0,2)+coord[1]*matrix(1,2)+coord[2]*matrix(2,2)+matrix(3,2));
}

osgParticle::ParticleSystem::ParticleSystem()
:    osg::Drawable(),
    _def_bbox(osg::Vec3(-10, -10, -10), osg::Vec3(10, 10, 10)),
    _alignment(BILLBOARD),
    _align_X_axis(1, 0, 0),
    _align_Y_axis(0, 1, 0),
    _particleScaleReferenceFrame(WORLD_COORDINATES),
    _useVertexArray(false),
    _useShaders(false),
    _dirty_uniforms(false),
    _doublepass(false),
    _frozen(false),
    _bmin(0, 0, 0),
    _bmax(0, 0, 0),
    _reset_bounds_flag(false),
    _bounds_computed(false),
    _def_ptemp(Particle()),
    _last_frame(0),
    _dirty_dt(true),
    _freeze_on_cull(false),
    _t0(0.0),
    _dt(0.0),
    _detail(1),
    _sortMode(NO_SORT),
    _visibilityDistance(-1.0),
    _draw_count(0)
{
    // we don't support display lists because particle systems
    // are dynamic, and they always changes between frames
    setSupportsDisplayList(false);
}

osgParticle::ParticleSystem::ParticleSystem(const ParticleSystem& copy, const osg::CopyOp& copyop)
:    osg::Drawable(copy, copyop),
    _def_bbox(copy._def_bbox),
    _alignment(copy._alignment),
    _align_X_axis(copy._align_X_axis),
    _align_Y_axis(copy._align_Y_axis),
    _particleScaleReferenceFrame(copy._particleScaleReferenceFrame),
    _useVertexArray(copy._useVertexArray),
    _useShaders(copy._useShaders),
    _dirty_uniforms(copy._dirty_uniforms),
    _doublepass(copy._doublepass),
    _frozen(copy._frozen),
    _bmin(copy._bmin),
    _bmax(copy._bmax),
    _reset_bounds_flag(copy._reset_bounds_flag),
    _bounds_computed(copy._bounds_computed),
    _def_ptemp(copy._def_ptemp),
    _last_frame(copy._last_frame),
    _dirty_dt(copy._dirty_dt),
    _freeze_on_cull(copy._freeze_on_cull),
    _t0(copy._t0),
    _dt(copy._dt),
    _detail(copy._detail),
    _sortMode(copy._sortMode),
    _visibilityDistance(copy._visibilityDistance),
    _draw_count(0)
{
}

osgParticle::ParticleSystem::~ParticleSystem()
{
}

void osgParticle::ParticleSystem::update(double dt, osg::NodeVisitor& nv)
{
    // reset bounds
    _reset_bounds_flag = true;

    if (_useShaders)
    {
        // Update shader uniforms
        // This slightly reduces the consumption of traversing the particle vector, because we
        // don't compute tile and angle attributes that are useleff for shaders.
        // At present, our lcoal shader implementation will ignore these particle props:
        //     _cur_tile, _s_coord, _t_coord, _prev_pos, _prev_angle and _angle
        osg::StateSet* stateset = getOrCreateStateSet();

        if (_dirty_uniforms)
        {
            osg::Uniform* u_vd = stateset->getUniform("visibilityDistance");
            if (u_vd) u_vd->set((float)_visibilityDistance);
            _dirty_uniforms = false;
        }
    }

    for(unsigned int i=0; i<_particles.size(); ++i)
    {
        Particle& particle = _particles[i];
        if (particle.isAlive())
        {
            if (particle.update(dt, _useShaders))
            {
                update_bounds(particle.getPosition(), particle.getCurrentSize());
            }
            else
            {
                reuseParticle(i);
            }
        }
    }

    if (_sortMode != NO_SORT)
    {
        // sort particles
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
        if (cv)
        {
            osg::Matrixd modelview = *(cv->getModelViewMatrix());
            float scale = (_sortMode==SORT_FRONT_TO_BACK ? -1.0f : 1.0f);
            for (unsigned int i=0; i<_particles.size(); ++i)
            {
                Particle& particle = _particles[i];
                if (particle.isAlive())
                    particle.setDepth(distance(particle.getPosition(), modelview) * scale);
                else
                    particle.setDepth(0.0f);
            }
            std::sort<Particle_vector::iterator>(_particles.begin(), _particles.end());<commit_msg>Added repolation of the _deadparts stack which would otherwise been invalidatd by the depth sort of particles.<commit_after>#include <osgParticle/ParticleSystem>

#include <vector>

#include <osg/Drawable>
#include <osg/CopyOp>
#include <osg/State>
#include <osg/Matrix>
#include <osg/GL>
#include <osg/StateSet>
#include <osg/Texture2D>
#include <osg/BlendFunc>
#include <osg/TexEnv>
#include <osg/Material>
#include <osg/PointSprite>
#include <osg/Program>
#include <osg/Notify>
#include <osg/io_utils>

#include <osgDB/FileUtils>
#include <osgDB/ReadFile>
#include <osgUtil/CullVisitor>

#define USE_LOCAL_SHADERS

static double distance(const osg::Vec3& coord, const osg::Matrix& matrix)
{
    // copied from CullVisitor.cpp
    return -(coord[0]*matrix(0,2)+coord[1]*matrix(1,2)+coord[2]*matrix(2,2)+matrix(3,2));
}

osgParticle::ParticleSystem::ParticleSystem()
:    osg::Drawable(),
    _def_bbox(osg::Vec3(-10, -10, -10), osg::Vec3(10, 10, 10)),
    _alignment(BILLBOARD),
    _align_X_axis(1, 0, 0),
    _align_Y_axis(0, 1, 0),
    _particleScaleReferenceFrame(WORLD_COORDINATES),
    _useVertexArray(false),
    _useShaders(false),
    _dirty_uniforms(false),
    _doublepass(false),
    _frozen(false),
    _bmin(0, 0, 0),
    _bmax(0, 0, 0),
    _reset_bounds_flag(false),
    _bounds_computed(false),
    _def_ptemp(Particle()),
    _last_frame(0),
    _dirty_dt(true),
    _freeze_on_cull(false),
    _t0(0.0),
    _dt(0.0),
    _detail(1),
    _sortMode(NO_SORT),
    _visibilityDistance(-1.0),
    _draw_count(0)
{
    // we don't support display lists because particle systems
    // are dynamic, and they always changes between frames
    setSupportsDisplayList(false);
}

osgParticle::ParticleSystem::ParticleSystem(const ParticleSystem& copy, const osg::CopyOp& copyop)
:    osg::Drawable(copy, copyop),
    _def_bbox(copy._def_bbox),
    _alignment(copy._alignment),
    _align_X_axis(copy._align_X_axis),
    _align_Y_axis(copy._align_Y_axis),
    _particleScaleReferenceFrame(copy._particleScaleReferenceFrame),
    _useVertexArray(copy._useVertexArray),
    _useShaders(copy._useShaders),
    _dirty_uniforms(copy._dirty_uniforms),
    _doublepass(copy._doublepass),
    _frozen(copy._frozen),
    _bmin(copy._bmin),
    _bmax(copy._bmax),
    _reset_bounds_flag(copy._reset_bounds_flag),
    _bounds_computed(copy._bounds_computed),
    _def_ptemp(copy._def_ptemp),
    _last_frame(copy._last_frame),
    _dirty_dt(copy._dirty_dt),
    _freeze_on_cull(copy._freeze_on_cull),
    _t0(copy._t0),
    _dt(copy._dt),
    _detail(copy._detail),
    _sortMode(copy._sortMode),
    _visibilityDistance(copy._visibilityDistance),
    _draw_count(0)
{
}

osgParticle::ParticleSystem::~ParticleSystem()
{
}

void osgParticle::ParticleSystem::update(double dt, osg::NodeVisitor& nv)
{
    // reset bounds
    _reset_bounds_flag = true;

    if (_useShaders)
    {
        // Update shader uniforms
        // This slightly reduces the consumption of traversing the particle vector, because we
        // don't compute tile and angle attributes that are useleff for shaders.
        // At present, our lcoal shader implementation will ignore these particle props:
        //     _cur_tile, _s_coord, _t_coord, _prev_pos, _prev_angle and _angle
        osg::StateSet* stateset = getOrCreateStateSet();

        if (_dirty_uniforms)
        {
            osg::Uniform* u_vd = stateset->getUniform("visibilityDistance");
            if (u_vd) u_vd->set((float)_visibilityDistance);
            _dirty_uniforms = false;
        }
    }

    for(unsigned int i=0; i<_particles.size(); ++i)
    {
        Particle& particle = _particles[i];
        if (particle.isAlive())
        {
            if (particle.update(dt, _useShaders))
            {
                update_bounds(particle.getPosition(), particle.getCurrentSize());
            }
            else
            {
                reuseParticle(i);
            }
        }
    }

    if (_sortMode != NO_SORT)
    {
        // sort particles
        osgUtil::CullVisitor* cv = dynamic_cast<osgUtil::CullVisitor*>(&nv);
        if (cv)
        {
            osg::Matrixd modelview = *(cv->getModelViewMatrix());
            double scale = (_sortMode==SORT_FRONT_TO_BACK ? -1.0 : 1.0);
            double deadDistance = DBL_MAX;
            for (unsigned int i=0; i<_particles.size(); ++i)
            {
                Particle& particle = _particles[i];
                if (particle.isAlive())
                    particle.setDepth(distance(particle.getPosition(), modelview) * scale);
                else
                    particle.setDepth(deadDistance);
            }
            std::sort<Particle_vector::iterator>(_particles.begin(), _particles.end());

            // Repopulate the death stack as it will have been invalidated by the sort.
            unsigned int numDead = _deadparts.size();
            if (numDead>0)
            {            
                 // clear the death stack
                _deadparts = Death_stack();
                
                // copy the tail of the _particles vector as this will contain all the dead Particle thanks to the depth sort against DBL_MAX
                Particle* first_dead_ptr  = &_particles[_particles.size()-numDead];
                Particle* last_dead_ptr  = &_particles[_particles.size()-1];
                for(Particle* dead_ptr  = first_dead_ptr; dead_ptr<=last_dead_ptr; ++dead_ptr)
                {
                    _deadparts.push(dead_ptr);
                }
            }
{'fraction_non_alphanumeric': 0.12206712206712207, 'fraction_numerical': 0.01188001188001188, 'mean_word_length': 2.907930367504836, 'pattern_counts': {'":': 0, '<': 50, '<?xml version=': 0, '>': 52, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5982504', 'n_tokens_mistral': 3467, 'n_tokens_neox': 3353, 'n_words': 603}