using System.Collections; using System.Collections.Generic; using UnityEngine; namespace UltraCombos.Frozen { public class SnowflakeParticleUpdater : MonoBehaviour { public bool reset = false; [Range(1, 1 << 20)] public int maxParticles = 1 << 15; public StructuredBuffer particleBuffer = null; List buffer_data = null; public ComputeShader shader = null; ComputeBuffer args_buffer = null; public UniformStructuredBuffer uniformBuffer; ParticleUniforms uniforms = null; public Klak.Chromatics.CosineGradient cosineGradient = null; bool is_initialized = false; [SerializeField] KinectOpticalFlow kinectOpticalFlow; [SerializeField] FluidSim3DProject.SmokeFluidSim smokeFluidSim; [SerializeField] ParticleViewerMesh particleViewerMesh; [SerializeField] [Range(0, 1)] public float rate = 1.0f; [SerializeField] DFVolume.VolumeData volumeData; ComputeBuffer volume_buffer; [SerializeField, Range(0, 1)] float value = 0; [SerializeField] string debug; private void Start() { uniforms = uniformBuffer.uniform as ParticleUniforms; particleViewerMesh.BufferCount = (int)(maxParticles * rate); StartCoroutine(Initialize()); } private void FixedUpdate() { if (is_initialized == false) return; if (reset) { reset = false; OnReset(); } debug = string.Format("{0}", volumeData.data[(int)Mathf.Min(volumeData.data.Count * value, volumeData.data.Count - 1)]); UpdateParticle(Time.fixedDeltaTime); } private void OnDestroy() { Utilities.Release(ref args_buffer); Utilities.Release(ref volume_buffer); } private void OnReset() { particleBuffer.SetData(buffer_data); } private IEnumerator Initialize() { { args_buffer = shader.CreateIndirectComputeArgsBuffer(maxParticles, 1, 1); } { var data = volumeData.data; volume_buffer = new ComputeBuffer(data.Count, sizeof(float) * 4); volume_buffer.SetData(data); } { buffer_data = new List(); yield return Utilities.GetRandomParticleData(maxParticles, buffer_data); } is_initialized = true; OnReset(); } private void UpdateParticle(float time_step) { { shader.SetFloat("timeStep", time_step); shader.SetFloat("timeValue", Utilities.GetTimeValue()); shader.SetInt("home_count", kinectOpticalFlow.HomeCount); shader.SetFloat("bufferCount", particleBuffer.count); if (cosineGradient != null) { shader.SetVector("coeffsA", cosineGradient.coeffsA); shader.SetVector("coeffsB", cosineGradient.coeffsB); shader.SetVector("coeffsC", cosineGradient.coeffsC2); shader.SetVector("coeffsD", cosineGradient.coeffsD2); } shader.SetVector("FluidGridDim", smokeFluidSim.GridDim); shader.SetVector("FluidGridRoot", smokeFluidSim.GridRoot); shader.SetVector("FluidGridSize", smokeFluidSim.GridSize); shader.SetBuffer(0, particleBuffer.bufferName, particleBuffer.obj); shader.SetBuffer(0, uniformBuffer.bufferName, uniformBuffer.obj); shader.SetBuffer(0, "home_position_buffer", kinectOpticalFlow.HomePositionBuffer); shader.SetBuffer(0, "home_velocity_buffer", kinectOpticalFlow.HomeVelocityBuffer); shader.SetBuffer(0, "fluid_velocity_buffer", smokeFluidSim.VelocityBuffer); shader.SetBuffer(0, "volume_data", volume_buffer); shader.SetTexture(0, "DFVolume", volumeData.texture); shader.DispatchIndirect(0, args_buffer); } } } }