using System;
using UnityEngine;

public class Mirror_2DandOculus : MonoBehaviour
{
	private void Start()
	{
		this.m_My_Render = base.GetComponent<Renderer>();
		this.m_My_Render.sharedMaterial.shader = Resources.Load<Shader>("Shaders/Mirror_2DandOculus");
		int antiAliasing = (QualitySettings.antiAliasing != 0) ? QualitySettings.antiAliasing : 1;
		this.m_Reflect_Texture = new RenderTexture(this.m_TextureSize, this.m_TextureSize, 16);
		this.m_Reflect_Texture.name = "_MirrorTexture";
		this.m_Reflect_Texture.isPowerOfTwo = true;
		this.m_Reflect_Texture.antiAliasing = antiAliasing;
		this.CreateMirrorObjects();
	}

	private void OnWillRenderObject()
	{
		if (this.m_SelfRendering)
		{
			return;
		}
		if (SteamVR.instance != null)
		{
			base.enabled = false;
			return;
		}
		this.m_SelfRendering = true;
		this.Reflection(Camera.current, this.m_Reflect_Texture);
		this.m_SelfRendering = false;
	}

	private void Reflection(Camera current_cam, RenderTexture reflect_Tex)
	{
		Vector3 position = base.transform.position;
		Vector3 vector = base.transform.TransformDirection(Vector3.back);
		this.UpdateCameraModes(current_cam, this.m_Reflect_Camera);
		float w = -Vector3.Dot(vector, position) - this.m_ClipPlaneOffset;
		Vector4 plane = new Vector4(vector.x, vector.y, vector.z, w);
		Matrix4x4 zero = Matrix4x4.zero;
		this.CalculateReflectionMatrix(ref zero, plane);
		Vector3 position2 = Camera.current.transform.position;
		Vector3 position3 = zero.MultiplyPoint(position2);
		this.m_Reflect_Camera.transform.position = position3;
		Vector3 eulerAngles = Camera.current.transform.eulerAngles;
		this.m_Reflect_Camera.transform.eulerAngles = eulerAngles;
		this.m_Reflect_Camera.worldToCameraMatrix = current_cam.worldToCameraMatrix * zero;
		Vector4 clipPlane = this.CameraSpacePlane(this.m_Reflect_Camera, position, vector, 1f);
		Matrix4x4 projectionMatrix = current_cam.CalculateObliqueMatrix(clipPlane);
		this.m_Reflect_Camera.projectionMatrix = projectionMatrix;
		this.m_Reflect_Camera.cullingMask = this.m_ReflectLayers.value;
		GL.invertCulling = true;
		this.m_Reflect_Camera.targetTexture = reflect_Tex;
		this.m_Reflect_Camera.Render();
		this.m_My_Render.sharedMaterial.SetTexture("_MainTex", reflect_Tex);
		GL.invertCulling = false;
	}

	private void UpdateCameraModes(Camera src, Camera dest)
	{
		if (dest == null)
		{
			return;
		}
		dest.clearFlags = src.clearFlags;
		dest.backgroundColor = src.backgroundColor;
		dest.farClipPlane = src.farClipPlane;
		dest.nearClipPlane = src.nearClipPlane;
		dest.orthographic = src.orthographic;
		dest.fieldOfView = src.fieldOfView;
		dest.aspect = src.aspect;
		dest.orthographicSize = src.orthographicSize;
	}

	private void CreateMirrorObjects()
	{
		GameObject gameObject = new GameObject("Mirror Refl Camera", new Type[]
		{
			typeof(Camera)
		});
		this.m_Reflect_Camera = gameObject.GetComponent<Camera>();
		this.m_Reflect_Camera.enabled = false;
		this.m_Reflect_Camera.transform.position = base.transform.position;
		this.m_Reflect_Camera.transform.rotation = base.transform.rotation;
		gameObject.transform.parent = base.transform;
	}

	private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign)
	{
		Vector3 v = pos + normal * this.m_ClipPlaneOffset;
		Matrix4x4 worldToCameraMatrix = cam.worldToCameraMatrix;
		Vector3 lhs = worldToCameraMatrix.MultiplyPoint(v);
		Vector3 rhs = worldToCameraMatrix.MultiplyVector(normal).normalized * sideSign;
		return new Vector4(rhs.x, rhs.y, rhs.z, -Vector3.Dot(lhs, rhs));
	}

	private void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane)
	{
		reflectionMat.m00 = 1f - 2f * plane[0] * plane[0];
		reflectionMat.m01 = -2f * plane[0] * plane[1];
		reflectionMat.m02 = -2f * plane[0] * plane[2];
		reflectionMat.m03 = -2f * plane[3] * plane[0];
		reflectionMat.m10 = -2f * plane[1] * plane[0];
		reflectionMat.m11 = 1f - 2f * plane[1] * plane[1];
		reflectionMat.m12 = -2f * plane[1] * plane[2];
		reflectionMat.m13 = -2f * plane[3] * plane[1];
		reflectionMat.m20 = -2f * plane[2] * plane[0];
		reflectionMat.m21 = -2f * plane[2] * plane[1];
		reflectionMat.m22 = 1f - 2f * plane[2] * plane[2];
		reflectionMat.m23 = -2f * plane[3] * plane[2];
		reflectionMat.m30 = 0f;
		reflectionMat.m31 = 0f;
		reflectionMat.m32 = 0f;
		reflectionMat.m33 = 1f;
	}

	private const string m_Shader_Path = "Shaders/Mirror_2DandOculus";

	[SerializeField]
	private int m_TextureSize = 2048;

	[SerializeField]
	private float m_ClipPlaneOffset = 0.07f;

	[SerializeField]
	private LayerMask m_ReflectLayers = -1;

	private bool m_SelfRendering;

	private Renderer m_My_Render;

	private Camera m_Reflect_Camera;

	private RenderTexture m_Reflect_Texture;
}
