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] string debug; private void Start() { uniforms = uniformBuffer.uniform as ParticleUniforms; StartCoroutine(Initialize()); } private void FixedUpdate() { if (is_initialized == false) return; if (reset) { reset = false; OnReset(); } UpdateParticle(Time.fixedDeltaTime); } private void OnDestroy() { Utilities.Release(ref args_buffer); } private void OnReset() { particleBuffer.SetData(buffer_data); } private IEnumerator Initialize() { #if false { uint[] args = new uint[3] { (uint)Mathf.CeilToInt((float)maxHomes / WORK_GROUP_SIZE), 1, 1 }; home_args_buffer = new ComputeBuffer(1, args.Length * sizeof(uint), ComputeBufferType.IndirectArguments); home_args_buffer.SetData(args); } #endif { args_buffer = shader.CreateIndirectComputeArgsBuffer(maxParticles, 1, 1); } { 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.DispatchIndirect(0, args_buffer); } } } }