/// <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; }
/// <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); }