You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

189 lines
7.2 KiB

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace UltraCombos
{
public class KinectOpticalFlow : MonoBehaviour
{
const int width = 512;
const int height = 424;
const int POSITION = 0;
const int VELOCITY = 1;
[SerializeField]
List<StructuredBuffer> kinectBuffers = new List<StructuredBuffer>();
public ComputeBuffer PositionBuffer { get { return kinectBuffers[POSITION].obj; } }
public ComputeBuffer VelocityBuffer { get { return kinectBuffers[VELOCITY].obj; } }
[SerializeField]
ComputeShader updateShader;
[SerializeField]
ComputeShader applyShader;
ComputeBuffer clear_grid_buffer_args_buffer = null;
ComputeBuffer args_buffer = null;
public bool flipX = true;
public Vector3 clipMin = Vector3.one * -10;
public Vector3 clipMax = Vector3.one * 10;
[SerializeField]
FluidSim3DProject.SmokeFluidSim fluidSimulation;
ComputeBuffer kinect_grid_buffer;
public ComputeBuffer KinectGridBuffer { get { return kinect_grid_buffer; } }
int grid_width, grid_height, grid_depth;
[Range(0, 5)]
public float kinectAmount = 0;
public List<RenderTexture> renderTextures;
[SerializeField, Header("Debug")]
bool debug = false;
[SerializeField]
bool colorize = false;
[SerializeField]
Material debugMaterial;
[SerializeField]
string debugInfo;
ComputeBuffer home_position_buffer;
public ComputeBuffer HomePositionBuffer { get { return home_position_buffer; } }
ComputeBuffer home_velocity_buffer;
public ComputeBuffer HomeVelocityBuffer { get { return home_velocity_buffer; } }
ComputeBuffer home_count_buffer;
public ComputeBuffer HomeCountBuffer { get { return home_count_buffer; } }
int home_count = 0;
public int HomeCount { get { return home_count; } }
private void Start()
{
foreach (var buf in kinectBuffers)
buf.Allocate(width * height, sizeof(float) * 4);
{
grid_width = fluidSimulation.m_width;
grid_height = fluidSimulation.m_height;
grid_depth = fluidSimulation.m_depth;
int grid_count = grid_width * grid_height * grid_depth;
kinect_grid_buffer = new ComputeBuffer(grid_count, sizeof(float) * 4);
}
{
home_position_buffer = new ComputeBuffer(512 * 424, sizeof(float) * 4, ComputeBufferType.Append);
home_velocity_buffer = new ComputeBuffer(512 * 424, sizeof(float) * 4, ComputeBufferType.Append);
home_count_buffer = new ComputeBuffer(1, sizeof(int), ComputeBufferType.Raw);
}
}
private void FixedUpdate()
{
if (args_buffer == null)
{
args_buffer = updateShader.CreateIndirectComputeArgsBuffer(width * height, 1, 1);
}
// update
{
var m = transform.localToWorldMatrix;
float[] mat_floats = new float[16]
{ m.m00, m.m01, m.m02, m.m03,
m.m10, m.m11, m.m12, m.m13,
m.m20, m.m21, m.m22, m.m23,
m.m30, m.m31, m.m32, m.m33};
updateShader.SetVector("ClipMin", clipMin);
updateShader.SetVector("ClipMax", clipMax);
updateShader.SetFloats("ModelMatrix", mat_floats);
updateShader.SetVector("FluidSize", fluidSimulation.GridSize);
updateShader.SetVector("FluidRoot", fluidSimulation.GridRoot);
updateShader.SetVector("FluidDim", fluidSimulation.GridDim);
updateShader.SetInt("flipX", flipX ? 1 : 0);
updateShader.SetTexture(0, "PositionTexture", renderTextures[POSITION]);
updateShader.SetTexture(0, "VelocityTexture", renderTextures[VELOCITY]);
foreach (var buf in kinectBuffers)
updateShader.SetBuffer(0, buf.bufferName, buf.obj);
updateShader.SetBuffer(0, "KinectGridBuffer", kinect_grid_buffer);
updateShader.SetBuffer(0, "HomePositionBuffer", home_position_buffer);
updateShader.SetBuffer(0, "HomeVelocityBuffer", home_velocity_buffer);
updateShader.DispatchIndirect(0, args_buffer);
}
{
ComputeBuffer.CopyCount(home_position_buffer, home_count_buffer, 0);
#if false
var data = new int[home_count_buffer.count];
home_count_buffer.GetData(data);
home_count = data[0];
#else
home_count = 0;
#endif
debugInfo = string.Format("{0}", home_count);
home_position_buffer.SetCounterValue(0);
home_velocity_buffer.SetCounterValue(0);
}
if (clear_grid_buffer_args_buffer == null)
{
Vector3Int dim = Vector3Int.FloorToInt(fluidSimulation.GridDim);
clear_grid_buffer_args_buffer = applyShader.CreateIndirectComputeArgsBuffer(dim.x, dim.y, dim.z);
}
{
applyShader.SetVector("FluidDim", fluidSimulation.GridDim);
applyShader.SetBuffer(0, "VelocityBuffer", fluidSimulation.VelocityBuffer);
applyShader.SetBuffer(0, "TemperatureBuffer", fluidSimulation.TemperatureBuffer);
applyShader.SetBuffer(0, "ObstacleBuffer", fluidSimulation.ObstacleBuffer);
applyShader.SetBuffer(0, "DensityBuffer", fluidSimulation.DensityBuffer);
applyShader.SetFloat("timeStep", Time.fixedDeltaTime);
applyShader.SetFloat("temperatureAmount", fluidSimulation.m_temperatureAmount);
applyShader.SetFloat("densityAmount", fluidSimulation.m_densityAmount);
applyShader.SetFloat("kinectAmount", kinectAmount);
applyShader.SetBuffer(0, "KinectGridBuffer", kinect_grid_buffer);
applyShader.DispatchIndirect(0, clear_grid_buffer_args_buffer);
}
}
private bool IsTextureValid(Texture2D tex)
{
bool res = false;
if (tex)
{
if (tex.width == 512 && tex.height == 424)
res = true;
}
return res;
}
private void OnRenderObject()
{
if (debug == false)
return;
if (Utilities.SkipCamera(Camera.current.name))
return;
debugMaterial.SetPass(0);
debugMaterial.SetInt("colorize", colorize ? 1 : 0);
foreach (var buf in kinectBuffers)
debugMaterial.SetBuffer(buf.bufferName, buf.obj);
Graphics.DrawProcedural(MeshTopology.Points, PositionBuffer.count);
}
private void OnDestroy()
{
clear_grid_buffer_args_buffer.Release();
args_buffer.Release();
KinectGridBuffer.Release();
home_position_buffer.Release();
home_velocity_buffer.Release();
home_count_buffer.Release();
}
}
}