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 }
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 }