/// <inheritdoc />
        public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
            ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter)
        {
            // Get all the required particle fields
            var positionField = sorter.GetField(ParticleFields.Position);
            if (!positionField.IsValid())
                return 0;
            var sizeField = sorter.GetField(ParticleFields.Size);

            var orderField = sorter.GetField(ParticleFields.Order);

            // Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
            // ReSharper disable once CompareOfFloatsByEqualityOperator
            var trsIdentity = (spaceScale == 1f);
            trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
            trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));

            var ribbonizer = new Ribbonizer(this, currentTotalParticles, currentQuadsPerParticle);

            var renderedParticles = 0;
            bufferState.StartOver();

            uint oldOrderValue = 0;

            foreach (var particle in sorter)
            {
                if (orderField.IsValid())
                {
                    var orderValue = (*((uint*)particle[orderField]));

                    if ((orderValue >> SpawnOrderConst.GroupBitOffset) != (oldOrderValue >> SpawnOrderConst.GroupBitOffset)) 
                    {
                        ribbonizer.Ribbonize(ref bufferState, invViewX, invViewY, QuadsPerParticle);
                        ribbonizer.RibbonSplit();
                    }

                    oldOrderValue = orderValue;
                }

                var centralPos = particle.Get(positionField);

                var particleSize = sizeField.IsValid() ? particle.Get(sizeField) : 1f;

                if (!trsIdentity)
                {
                    spaceRotation.Rotate(ref centralPos);
                    centralPos = centralPos * spaceScale + spaceTranslation;
                    particleSize *= spaceScale;
                }
                
                ribbonizer.AddParticle(ref centralPos, particleSize);
                renderedParticles++;
            }

            ribbonizer.Ribbonize(ref bufferState, invViewX, invViewY, QuadsPerParticle);

            ribbonizer.Free();

            var vtxPerShape = 4 * QuadsPerParticle;
            return renderedParticles * vtxPerShape;
        }
Esempio n. 2
0
        /// <inheritdoc />
        public override unsafe int BuildVertexBuffer(ref ParticleBufferState bufferState, Vector3 invViewX, Vector3 invViewY,
                                                     ref Vector3 spaceTranslation, ref Quaternion spaceRotation, float spaceScale, ref ParticleList sorter, ref Matrix viewProj)
        {
            // Get all the required particle fields
            var positionField = sorter.GetField(ParticleFields.Position);

            if (!positionField.IsValid())
            {
                return(0);
            }
            var sizeField      = sorter.GetField(ParticleFields.Size);
            var directionField = sorter.GetField(ParticleFields.Direction);

            // Check if the draw space is identity - in this case we don't need to transform the position, scale and rotation vectors
            var trsIdentity = (spaceScale == 1f);

            trsIdentity = trsIdentity && (spaceTranslation.Equals(new Vector3(0, 0, 0)));
            trsIdentity = trsIdentity && (spaceRotation.Equals(Quaternion.Identity));

            var ribbonizer = new Ribbonizer(this, currentTotalParticles, currentQuadsPerParticle);

            var renderedParticles = 0;

            bufferState.StartOver();

            uint oldOrderValue = 0;
            var  orderField    = sorter.GetField(ParticleFields.Order);

            foreach (var particle in sorter)
            {
                if (orderField.IsValid())
                {
                    var orderValue = (*((uint *)particle[orderField]));

                    if ((orderValue >> SpawnOrderConst.GroupBitOffset) != (oldOrderValue >> SpawnOrderConst.GroupBitOffset))
                    {
                        ribbonizer.Ribbonize(ref bufferState, QuadsPerParticle);
                        ribbonizer.RibbonSplit();
                    }

                    oldOrderValue = orderValue;
                }

                var centralPos = particle.Get(positionField);

                var particleSize      = sizeField.IsValid() ? particle.Get(sizeField) : 1f;
                var particleDirection = directionField.IsValid() ? particle.Get(directionField) * particleSize : new Vector3(0f, particleSize, 0f);

                if (!trsIdentity)
                {
                    spaceRotation.Rotate(ref centralPos);
                    centralPos = centralPos * spaceScale + spaceTranslation;

                    // Direction
                    spaceRotation.Rotate(ref particleDirection);
                    particleDirection *= spaceScale;
                }

                ribbonizer.AddParticle(ref centralPos, ref particleDirection);

                renderedParticles++;
            }

            ribbonizer.Ribbonize(ref bufferState, QuadsPerParticle);

            ribbonizer.Free();

            var vtxPerShape = 4 * QuadsPerParticle;

            return(renderedParticles * vtxPerShape);
        }