/// <summary> /// Build the vertex buffer from particle data /// Should come before <see cref="KickVertexBuffer"/> /// </summary> /// <param name="device">The graphics device, used to rebuild vertex layouts and shaders if needed</param> /// <param name="invViewMatrix">The current camera's inverse view matrix</param> public void BuildVertexBuffer(CommandList commandList, ref Matrix invViewMatrix) { // Get camera-space X and Y axes for billboard expansion and sort the particles if needed var unitX = new Vector3(invViewMatrix.M11, invViewMatrix.M12, invViewMatrix.M13); var unitY = new Vector3(invViewMatrix.M21, invViewMatrix.M22, invViewMatrix.M23); depthSortVector = Vector3.Cross(unitX, unitY); ParticleSorter.Sort(); // If the particles are in world space they don't need to be fixed as their coordinates are already in world space // If the particles are in local space they need to be drawn in world space using the emitter's current location matrix var posIdentity = new Vector3(0, 0, 0); var rotIdentity = new Quaternion(0, 0, 0, 1); var scaleIdentity = 1f; if (simulationSpace == EmitterSimulationSpace.Local) { posIdentity = drawPosition; rotIdentity = drawRotation; scaleIdentity = drawScale; } VertexBuilder.MapBuffer(commandList); ShapeBuilder.BuildVertexBuffer(VertexBuilder, unitX, unitY, ref posIdentity, ref rotIdentity, scaleIdentity, ParticleSorter); VertexBuilder.RestartBuffer(); ShapeBuilder.SetRequiredQuads(ShapeBuilder.QuadsPerParticle, pool.LivingParticles, pool.ParticleCapacity); Material.PatchVertexBuffer(VertexBuilder, unitX, unitY, ParticleSorter); VertexBuilder.UnmapBuffer(commandList); }
/// <summary> /// Build the vertex buffer from particle data /// </summary> /// <param name="sharedBufferPtr">The shared vertex buffer position where the particle data should be output</param> /// <param name="invViewMatrix">The current camera's inverse view matrix</param> public void BuildVertexBuffer(IntPtr sharedBufferPtr, ref Matrix invViewMatrix, ref Matrix viewProj) { // Get camera-space X and Y axes for billboard expansion and sort the particles if needed var unitX = new Vector3(invViewMatrix.M11, invViewMatrix.M12, invViewMatrix.M13); var unitY = new Vector3(invViewMatrix.M21, invViewMatrix.M22, invViewMatrix.M23); // Not the best solution, might want to improve var depthVector = Vector3.Cross(unitX, unitY); if (simulationSpace == EmitterSimulationSpace.Local) { var inverseRotation = drawTransform.WorldRotation; inverseRotation.W *= -1; inverseRotation.Rotate(ref depthVector); } var sortedList = ParticleSorter.GetSortedList(depthVector); // If the particles are in world space they don't need to be fixed as their coordinates are already in world space // If the particles are in local space they need to be drawn in world space using the emitter's current location matrix var posIdentity = new Vector3(0, 0, 0); var rotIdentity = Quaternion.Identity; var scaleIdentity = 1f; if (simulationSpace == EmitterSimulationSpace.Local) { posIdentity = drawTransform.WorldPosition; rotIdentity = drawTransform.WorldRotation; scaleIdentity = drawTransform.WorldScale.X; } ParticleBufferState bufferState = new ParticleBufferState(sharedBufferPtr, VertexBuilder); ShapeBuilder.SetRequiredQuads(ShapeBuilder.QuadsPerParticle, pool.LivingParticles, pool.ParticleCapacity); ShapeBuilder.BuildVertexBuffer(ref bufferState, unitX, unitY, ref posIdentity, ref rotIdentity, scaleIdentity, ref sortedList, ref viewProj); bufferState.StartOver(); Material.PatchVertexBuffer(ref bufferState, unitX, unitY, ref sortedList); ParticleSorter.FreeSortedList(ref sortedList); }