2019-12-12 12:08:41 +00:00
|
|
|
using UnityEngine;
|
2019-12-13 15:14:22 +00:00
|
|
|
using UnityEngine.Events;
|
2019-12-12 12:08:41 +00:00
|
|
|
using GraphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat;
|
|
|
|
|
|
|
|
namespace Akvfx
|
|
|
|
{
|
2019-12-13 15:14:22 +00:00
|
|
|
|
|
|
|
|
2019-12-12 12:08:41 +00:00
|
|
|
public sealed class PointCloudBaker : MonoBehaviour
|
|
|
|
{
|
2019-12-13 15:14:22 +00:00
|
|
|
|
2019-12-12 12:08:41 +00:00
|
|
|
#region Editable attributes
|
|
|
|
|
|
|
|
[SerializeField] DeviceSettings _deviceSettings = null;
|
|
|
|
[SerializeField] RenderTexture _colorTexture = null;
|
|
|
|
[SerializeField] RenderTexture _positionTexture = null;
|
|
|
|
[SerializeField] Shader _shader = null;
|
2019-12-13 15:14:22 +00:00
|
|
|
[SerializeField] UnityEvent azureDataUpdated;
|
|
|
|
|
2019-12-12 12:08:41 +00:00
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region Internal objects
|
|
|
|
|
|
|
|
ThreadedDriver _driver;
|
|
|
|
Material _material;
|
|
|
|
ComputeBuffer _xyTable;
|
|
|
|
(Texture2D color, Texture2D depth) _temporaries;
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
|
|
|
|
#region MonoBehaviour implementation
|
|
|
|
|
|
|
|
void Start()
|
|
|
|
{
|
|
|
|
// Start capturing via the threaded driver.
|
|
|
|
_driver = new ThreadedDriver(_deviceSettings);
|
|
|
|
|
|
|
|
// Temporary objects for convertion shader
|
|
|
|
_material = new Material(_shader);
|
|
|
|
_temporaries = (
|
|
|
|
new Texture2D(2048, 1536, GraphicsFormat.B8G8R8A8_SRGB, 0),
|
|
|
|
new Texture2D(2048 * 2, 1536, GraphicsFormat.R8_UNorm, 0)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
void OnDestroy()
|
|
|
|
{
|
|
|
|
if (_material != null) Destroy(_material);
|
|
|
|
_xyTable?.Dispose();
|
|
|
|
if (_temporaries.color != null) Destroy(_temporaries.color);
|
|
|
|
if (_temporaries.depth != null) Destroy(_temporaries.depth);
|
|
|
|
_driver?.Dispose();
|
|
|
|
}
|
|
|
|
|
|
|
|
RenderBuffer[] _mrt = new RenderBuffer[2];
|
|
|
|
|
|
|
|
unsafe void Update()
|
|
|
|
{
|
|
|
|
// Try initializing XY table if it's not ready.
|
|
|
|
if (_xyTable == null)
|
|
|
|
{
|
|
|
|
var data = _driver.XYTable;
|
|
|
|
if (data.IsEmpty) return; // Table is not ready.
|
|
|
|
|
|
|
|
// Allocate and initialize the XY table.
|
|
|
|
_xyTable = new ComputeBuffer(data.Length, sizeof(float));
|
|
|
|
_xyTable.SetData(data);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try retrieving the last frame.
|
|
|
|
var (color, depth) = _driver.LockLastFrame();
|
|
|
|
if (color.IsEmpty || depth.IsEmpty) return;
|
|
|
|
|
|
|
|
// Load the frame data into the temporary textures.
|
|
|
|
_temporaries.color.LoadRawTextureData(color.Span);
|
|
|
|
_temporaries.depth.LoadRawTextureData(depth.Span);
|
|
|
|
_temporaries.color.Apply();
|
|
|
|
_temporaries.depth.Apply();
|
|
|
|
|
|
|
|
// We don't need the last frame any more.
|
|
|
|
_driver.ReleaseLastFrame();
|
|
|
|
|
|
|
|
// Invoke the unprojection shader.
|
|
|
|
_material.SetTexture("_ColorTexture", _temporaries.color);
|
|
|
|
_material.SetTexture("_DepthTexture", _temporaries.depth);
|
|
|
|
_material.SetBuffer("_XYTable", _xyTable);
|
|
|
|
_material.SetFloat("_MaxDepth", _deviceSettings.maxDepth);
|
|
|
|
var prevRT = RenderTexture.active;
|
|
|
|
GraphicsExtensions.SetRenderTarget(_colorTexture, _positionTexture);
|
|
|
|
Graphics.Blit(null, _material, 0);
|
|
|
|
RenderTexture.active = prevRT;
|
2019-12-13 15:14:22 +00:00
|
|
|
|
|
|
|
azureDataUpdated.Invoke();
|
2019-12-12 12:08:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
#endregion
|
|
|
|
}
|
|
|
|
}
|