public void sortByDepth(ref Matrix4 viewMatrix)
        {
            if (_numParticles == 0)
            {
                return;
            }

            for (int i = 0; i < _activeBlockLength; ++i)
            {
                if (isAlive(i))
                {
                    // Do the transform and store z of the result
                    Vector3 pos = readData(_positions, i).Value;
                    pos = Vector3.Transform(pos, viewMatrix);
                    writeDataIfNeeded(ref _viewDepths, i, pos.Z);
                }
                else
                {
                    // since we are doing a sort pass later, might as well make it so
                    // so the dead particles get pushed the back of the arrays
                    writeDataIfNeeded(ref _viewDepths, i, float.PositiveInfinity);
                }
            }

            quickSort(0, _activeBlockLength - 1);

            if (_numParticles < _capacity)
            {
                // update pointers to reflect dead particles that just got sorted to the back
                _nextIdxToWrite    = _numParticles - 1;
                _activeBlockLength = _numParticles;
            }

            #if false
            // set color based on the index of the particle in the arrays
            SSAttributeColor[] debugColors =
            {
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Red)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Green)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Blue)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Yellow))
            };

            for (int i = 0; i < m_activeBlockLength; ++i)
            {
                writeDataIfNeeded(ref m_colors, i, debugColors[i]);
            }
            #endif
        }
Example #2
0
        public override void sortByDepth(ref Matrix4 viewMatrix)
        {
            if (_numParticles == 0)
            {
                return;
            }

            int   numAlive      = 0;
            float prevViewDepth = float.NegativeInfinity;
            bool  alreadySorted = true;

            for (int i = 0; i < _activeBlockLength; ++i)
            {
                if (isAlive(i))
                {
                    // Do the transform and store z of the result
                    Vector3 pos = _readElement(_positions, i).Value;
                    pos = Vector3.Transform(pos, viewMatrix);
                    float viewDepth = pos.Z;
                    writeDataIfNeeded(ref _viewDepths, i, viewDepth);
                    ++numAlive;
                    if (alreadySorted && pos.Z < prevViewDepth)
                    {
                        alreadySorted = false;
                    }
                    prevViewDepth = viewDepth;
                }
                else
                {
                    // since we are doing a sort pass later, might as well make it so
                    // so the dead particles get pushed the back of the arrays
                    writeDataIfNeeded(ref _viewDepths, i, float.PositiveInfinity);
                    alreadySorted = false; //force a "sort" to puch dead particles towards the end
                }
            }

            if (!alreadySorted)
            {
                quickSort(0, _activeBlockLength - 1);

                // somewhat hacky workaround for zombie particles that seem to be related to sortByDepth()
                _numParticles      = numAlive;
                _activeBlockLength = _numParticles;

                if (_numParticles == 0)
                {
                    _nextIdxToWrite = _nextIdxToOverwrite = 0;
                }
                else if (_numParticles < _capacity)
                {
                    // update pointers to reflect dead particles that just got sorted to the back
                    _nextIdxToWrite = _numParticles - 1;
                }
                #if DEBUG_PARTICLE_SORTING
                ++debugNumSorted;
                #endif
            }
            else
            {
                #if DEBUG_PARTICLE_SORTING
                ++debugNumSortSkipped;
                #endif
            }

            #if DEBUG_PARTICLE_SORTING
            System.Console.WriteLine(
                "particle data actually sorted "
                + ((float)debugNumSorted / (float)(debugNumSorted + debugNumSortSkipped) * 100f)
                + "% of the time");
            #endif

            #if false
            // set color based on the index of the particle in the arrays
            SSAttributeColor[] debugColors =
            {
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Red)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Green)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Blue)),
                new SSAttributeColor(OpenTKHelper.Color4toRgba(Color4.Yellow))
            };

            for (int i = 0; i < m_activeBlockLength; ++i)
            {
                writeDataIfNeeded(ref m_colors, i, debugColors[i]);
            }
            #endif
        }