279 lines
5.6 KiB
C#
279 lines
5.6 KiB
C#
using System.Collections.Generic;
|
|
using AmplifyMotion;
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
[AddComponentMenu("")]
|
|
[RequireComponent(typeof(Camera))]
|
|
public class AmplifyMotionCamera : MonoBehaviour
|
|
{
|
|
internal AmplifyMotionEffectBase Instance;
|
|
|
|
internal Matrix4x4 PrevViewProjMatrix;
|
|
|
|
internal Matrix4x4 ViewProjMatrix;
|
|
|
|
internal Matrix4x4 InvViewProjMatrix;
|
|
|
|
internal Matrix4x4 PrevViewProjMatrixRT;
|
|
|
|
internal Matrix4x4 ViewProjMatrixRT;
|
|
|
|
private bool m_linked;
|
|
|
|
private bool m_initialized;
|
|
|
|
private bool m_starting = true;
|
|
|
|
private Camera m_camera;
|
|
|
|
private bool m_autoStep = true;
|
|
|
|
private bool m_step;
|
|
|
|
private bool m_overlay;
|
|
|
|
private int m_prevFrameCount;
|
|
|
|
private HashSet<AmplifyMotionObjectBase> m_affectedObjectsTable = new HashSet<AmplifyMotionObjectBase>();
|
|
|
|
private AmplifyMotionObjectBase[] m_affectedObjects;
|
|
|
|
private bool m_affectedObjectsChanged = true;
|
|
|
|
public bool Initialized
|
|
{
|
|
get
|
|
{
|
|
return m_initialized;
|
|
}
|
|
}
|
|
|
|
public bool AutoStep
|
|
{
|
|
get
|
|
{
|
|
return m_autoStep;
|
|
}
|
|
}
|
|
|
|
public bool Overlay
|
|
{
|
|
get
|
|
{
|
|
return m_overlay;
|
|
}
|
|
}
|
|
|
|
public void RegisterObject(AmplifyMotionObjectBase obj)
|
|
{
|
|
m_affectedObjectsTable.Add(obj);
|
|
m_affectedObjectsChanged = true;
|
|
}
|
|
|
|
public void UnregisterObject(AmplifyMotionObjectBase obj)
|
|
{
|
|
m_affectedObjectsTable.Remove(obj);
|
|
m_affectedObjectsChanged = true;
|
|
}
|
|
|
|
private void UpdateAffectedObjects()
|
|
{
|
|
if (m_affectedObjects == null || m_affectedObjectsTable.Count != m_affectedObjects.Length)
|
|
{
|
|
m_affectedObjects = new AmplifyMotionObjectBase[m_affectedObjectsTable.Count];
|
|
}
|
|
m_affectedObjectsTable.CopyTo(m_affectedObjects);
|
|
m_affectedObjectsChanged = false;
|
|
}
|
|
|
|
public void LinkTo(AmplifyMotionEffectBase instance, bool overlay)
|
|
{
|
|
Instance = instance;
|
|
m_camera = GetComponent<Camera>();
|
|
m_camera.depthTextureMode |= DepthTextureMode.Depth;
|
|
m_overlay = overlay;
|
|
m_linked = true;
|
|
}
|
|
|
|
public void Initialize()
|
|
{
|
|
m_step = false;
|
|
UpdateMatrices();
|
|
m_initialized = true;
|
|
}
|
|
|
|
private void OnEnable()
|
|
{
|
|
AmplifyMotionEffectBase.RegisterCamera(this);
|
|
}
|
|
|
|
private void OnDisable()
|
|
{
|
|
m_initialized = false;
|
|
AmplifyMotionEffectBase.UnregisterCamera(this);
|
|
}
|
|
|
|
private void OnDestroy()
|
|
{
|
|
if (Instance != null)
|
|
{
|
|
Instance.RemoveCamera(m_camera);
|
|
}
|
|
}
|
|
|
|
public void StopAutoStep()
|
|
{
|
|
if (m_autoStep)
|
|
{
|
|
m_autoStep = false;
|
|
m_step = true;
|
|
}
|
|
}
|
|
|
|
public void StartAutoStep()
|
|
{
|
|
m_autoStep = true;
|
|
}
|
|
|
|
public void Step()
|
|
{
|
|
m_step = true;
|
|
}
|
|
|
|
private void Update()
|
|
{
|
|
if (m_linked && Instance.isActiveAndEnabled)
|
|
{
|
|
if (!m_initialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
if ((m_camera.depthTextureMode & DepthTextureMode.Depth) == 0)
|
|
{
|
|
m_camera.depthTextureMode |= DepthTextureMode.Depth;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void UpdateMatrices()
|
|
{
|
|
if (!m_starting)
|
|
{
|
|
PrevViewProjMatrix = ViewProjMatrix;
|
|
PrevViewProjMatrixRT = ViewProjMatrixRT;
|
|
}
|
|
Matrix4x4 worldToCameraMatrix = m_camera.worldToCameraMatrix;
|
|
Matrix4x4 gPUProjectionMatrix = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, false);
|
|
ViewProjMatrix = gPUProjectionMatrix * worldToCameraMatrix;
|
|
InvViewProjMatrix = Matrix4x4.Inverse(ViewProjMatrix);
|
|
Matrix4x4 gPUProjectionMatrix2 = GL.GetGPUProjectionMatrix(m_camera.projectionMatrix, true);
|
|
ViewProjMatrixRT = gPUProjectionMatrix2 * worldToCameraMatrix;
|
|
if (m_starting)
|
|
{
|
|
PrevViewProjMatrix = ViewProjMatrix;
|
|
PrevViewProjMatrixRT = ViewProjMatrixRT;
|
|
}
|
|
}
|
|
|
|
public void FixedUpdateTransform(CommandBuffer updateCB)
|
|
{
|
|
if (!m_initialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
if (m_affectedObjectsChanged)
|
|
{
|
|
UpdateAffectedObjects();
|
|
}
|
|
for (int i = 0; i < m_affectedObjects.Length; i++)
|
|
{
|
|
if (m_affectedObjects[i].FixedStep)
|
|
{
|
|
m_affectedObjects[i].OnUpdateTransform(m_camera, updateCB, m_starting);
|
|
}
|
|
}
|
|
}
|
|
|
|
public void UpdateTransform(CommandBuffer updateCB)
|
|
{
|
|
if (!m_initialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
if (Time.frameCount <= m_prevFrameCount || (!m_autoStep && !m_step))
|
|
{
|
|
return;
|
|
}
|
|
UpdateMatrices();
|
|
if (m_affectedObjectsChanged)
|
|
{
|
|
UpdateAffectedObjects();
|
|
}
|
|
for (int i = 0; i < m_affectedObjects.Length; i++)
|
|
{
|
|
if (!m_affectedObjects[i].FixedStep)
|
|
{
|
|
m_affectedObjects[i].OnUpdateTransform(m_camera, updateCB, m_starting);
|
|
}
|
|
}
|
|
m_starting = false;
|
|
m_step = false;
|
|
m_prevFrameCount = Time.frameCount;
|
|
}
|
|
|
|
public void RenderVectors(CommandBuffer renderCB, float scale, float fixedScale, Quality quality)
|
|
{
|
|
if (!m_initialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
float nearClipPlane = m_camera.nearClipPlane;
|
|
float farClipPlane = m_camera.farClipPlane;
|
|
Vector4 value = default(Vector4);
|
|
if (AmplifyMotionEffectBase.IsD3D)
|
|
{
|
|
value.x = 1f - farClipPlane / nearClipPlane;
|
|
value.y = farClipPlane / nearClipPlane;
|
|
}
|
|
else
|
|
{
|
|
value.x = (1f - farClipPlane / nearClipPlane) / 2f;
|
|
value.y = (1f + farClipPlane / nearClipPlane) / 2f;
|
|
}
|
|
value.z = value.x / farClipPlane;
|
|
value.w = value.y / farClipPlane;
|
|
Shader.SetGlobalVector("_AM_ZBUFFER_PARAMS", value);
|
|
if (m_affectedObjectsChanged)
|
|
{
|
|
UpdateAffectedObjects();
|
|
}
|
|
for (int i = 0; i < m_affectedObjects.Length; i++)
|
|
{
|
|
if ((m_camera.cullingMask & (1 << m_affectedObjects[i].gameObject.layer)) != 0)
|
|
{
|
|
m_affectedObjects[i].OnRenderVectors(m_camera, renderCB, (!m_affectedObjects[i].FixedStep) ? scale : fixedScale, quality);
|
|
}
|
|
}
|
|
}
|
|
|
|
private void OnGUI()
|
|
{
|
|
if (Application.isEditor && m_linked && Instance.isActiveAndEnabled)
|
|
{
|
|
if (!m_initialized)
|
|
{
|
|
Initialize();
|
|
}
|
|
if (m_affectedObjectsChanged)
|
|
{
|
|
UpdateAffectedObjects();
|
|
}
|
|
for (int i = 0; i < m_affectedObjects.Length; i++)
|
|
{
|
|
m_affectedObjects[i].OnRenderDebugHUD(m_camera);
|
|
}
|
|
}
|
|
}
|
|
}
|