Firstborn/Assets/AwesomeTechnologies/TouchReactSystemPro/Runtime/TouchReactSystem.cs

990 lines
34 KiB
C#
Raw Permalink Normal View History

using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
namespace AwesomeTechnologies.TouchReact
{
[Serializable]
public class CapsuleColliderInfo
{
public float Radius;
public float Height;
public Mesh CapsuleColliderMesh;
}
[Serializable]
public class TouchColliderInfo
{
public Collider Collider;
public float Scale = 1;
}
public enum TouchReactQuality
{
Low = 0,
Normal = 1,
High = 2
}
[HelpURL("http://www.awesometech.no/index.php/home/vegetation-studio/components/touch-bend-system")]
[ExecuteInEditMode]
public class TouchReactSystem : MonoBehaviour
{
public Vector3 Rotation;
public static TouchReactSystem Instance;
// public int InvisibleLayer = 29;
public Camera TouchReactCamera;
public Camera SelectedCamera;
public bool AutoselectCamera = true;
public float CameraYPosition = -1000f;
private Material _touchReactMaterial;
private Material _touchreactMaterialInstanced;
private MaterialPropertyBlock _touchreactMaterialPropertyBlock;
public TouchReactQuality TouchReactQuality = TouchReactQuality.Normal;
public int OrthographicSize = 50;
public float Speed = 2f;
public bool ShowDebugColliders;
public bool HideTouchReactCamera = true;
private Mesh _sphereColliderMesh;
private Mesh _boxColliderMesh;
private RenderTexture _currentTouchRenderTexture;
private RenderTexture _lastFrameTouchRenderTexture;
private Material _blendBufferMaterial;
public List<TouchColliderInfo> ColliderList = new List<TouchColliderInfo>();
public List<MeshFilter> MeshFilterList = new List<MeshFilter>();
private readonly List<CapsuleColliderInfo> _capsuleColliderMeshList = new List<CapsuleColliderInfo>();
private Vector2 _uvOffset;
private static readonly int SpeedID = Shader.PropertyToID("_Speed");
private static readonly int OffsetVid = Shader.PropertyToID("_offsetV");
private static readonly int OffsetUid = Shader.PropertyToID("_offsetU");
private Camera _currentCamera;
// ReSharper disable once UnusedMember.Local
void Awake()
{
if (Instance == null) Instance = this;
ColliderList.Clear();
MeshFilterList.Clear();
}
// ReSharper disable once UnusedMember.Local
private void OnEnable()
{
CreateColliderPrimitives();
Init();
}
// ReSharper disable once UnusedMember.Local
private void OnDisable()
{
if (TouchReactCamera) TouchReactCamera.enabled = false;
if (TouchReactCamera)
{
TouchReactCamera.targetTexture = null;
if (_currentTouchRenderTexture) DestroyImmediate(_currentTouchRenderTexture);
if (_lastFrameTouchRenderTexture) DestroyImmediate(_lastFrameTouchRenderTexture);
}
}
private void CreateColliderPrimitives()
{
_capsuleColliderMeshList.Clear();
_sphereColliderMesh = CreateSphereMesh();
_boxColliderMesh = CreateBoxMesh();
}
public int GetTouchReactQualityPixelResolution(TouchReactQuality touchReactQuality)
{
switch (touchReactQuality)
{
case TouchReactQuality.Low:
return 512;
case TouchReactQuality.Normal:
return 1024;
case TouchReactQuality.High:
return 2048;
default:
return 1024;
}
}
public void UpdateCamera()
{
if (TouchReactCamera)
{
// TouchReactCamera.cullingMask = 1 << InvisibleLayer;
TouchReactCamera.orthographicSize = OrthographicSize;
int textureResolution = GetTouchReactQualityPixelResolution(TouchReactQuality);
if (_currentTouchRenderTexture) DestroyImmediate(_currentTouchRenderTexture);
if (_lastFrameTouchRenderTexture) DestroyImmediate(_lastFrameTouchRenderTexture);
_currentTouchRenderTexture =
new RenderTexture(textureResolution, textureResolution, 24,RenderTextureFormat.RGFloat, RenderTextureReadWrite.Linear)
{
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Point,
autoGenerateMips = false,
hideFlags = HideFlags.DontSave
};
_lastFrameTouchRenderTexture =
new RenderTexture(textureResolution, textureResolution, 24,RenderTextureFormat.RGFloat, RenderTextureReadWrite.Linear)
{
wrapMode = TextureWrapMode.Clamp,
filterMode = FilterMode.Point,
autoGenerateMips = false,
hideFlags = HideFlags.DontSave
};
_blendBufferMaterial = (Material) Resources.Load("BlendTouchReactBuffer", typeof(Material));
//RenderTexture oldRenderTexture = TouchReactCamera.targetTexture;
// RenderTexture rt =
// new RenderTexture(textureResolution, textureResolution, 24, RenderTextureFormat.RGFloat, RenderTextureReadWrite.Linear)
// {
// wrapMode = TextureWrapMode.Clamp,
// filterMode = FilterMode.Point,
// autoGenerateMips = false,
// hideFlags = HideFlags.DontSave
// };
//
// RenderTexture oldRenderTexture = TouchReactCamera.targetTexture;
TouchReactCamera.targetTexture = _currentTouchRenderTexture;
}
}
private Mesh GetCapsuleColliderMesh(float radius, float height)
{
for (int i = 0; i <= _capsuleColliderMeshList.Count - 1; i++)
if (Math.Abs(_capsuleColliderMeshList[i].Radius - radius) < 0.01f &&
Math.Abs(_capsuleColliderMeshList[i].Height - height) < 0.01f)
return _capsuleColliderMeshList[i].CapsuleColliderMesh;
CapsuleColliderInfo newCapsuleColliderInfo = new CapsuleColliderInfo
{
Radius = radius,
Height = height,
CapsuleColliderMesh = CreateCapsuleMesh(radius, height)
};
_capsuleColliderMeshList.Add(newCapsuleColliderInfo);
return newCapsuleColliderInfo.CapsuleColliderMesh;
}
public static Mesh CreateBoxMesh(float length = 1f,float width = 1f, float height = 1f)
{
Mesh mesh = new Mesh();
mesh.Clear();
//const float length = 1f;
//const float width = 1f;
//const float height = 1f;
#region Vertices
Vector3 p0 = new Vector3(-length * .5f, -width * .5f, height * .5f);
Vector3 p1 = new Vector3(length * .5f, -width * .5f, height * .5f);
Vector3 p2 = new Vector3(length * .5f, -width * .5f, -height * .5f);
Vector3 p3 = new Vector3(-length * .5f, -width * .5f, -height * .5f);
Vector3 p4 = new Vector3(-length * .5f, width * .5f, height * .5f);
Vector3 p5 = new Vector3(length * .5f, width * .5f, height * .5f);
Vector3 p6 = new Vector3(length * .5f, width * .5f, -height * .5f);
Vector3 p7 = new Vector3(-length * .5f, width * .5f, -height * .5f);
Vector3[] vertices =
{
// Bottom
p0, p1, p2, p3,
// Left
p7, p4, p0, p3,
// Front
p4, p5, p1, p0,
// Back
p6, p7, p3, p2,
// Right
p5, p6, p2, p1,
// Top
p7, p6, p5, p4
};
#endregion
#region Normales
Vector3 up = Vector3.up;
Vector3 down = Vector3.down;
Vector3 front = Vector3.forward;
Vector3 back = Vector3.back;
Vector3 left = Vector3.left;
Vector3 right = Vector3.right;
Vector3[] normales =
{
// Bottom
down, down, down, down,
// Left
left, left, left, left,
// Front
front, front, front, front,
// Back
back, back, back, back,
// Right
right, right, right, right,
// Top
up, up, up, up
};
#endregion
#region UVs
Vector2 _00 = new Vector2(0f, 0f);
Vector2 _10 = new Vector2(1f, 0f);
Vector2 _01 = new Vector2(0f, 1f);
Vector2 _11 = new Vector2(1f, 1f);
UnityEngine.Vector2[] uvs =
{
// Bottom
_11, _01, _00, _10,
// Left
_11, _01, _00, _10,
// Front
_11, _01, _00, _10,
// Back
_11, _01, _00, _10,
// Right
_11, _01, _00, _10,
// Top
_11, _01, _00, _10
};
#endregion
#region Triangles
int[] triangles =
{
// Bottom
3, 1, 0,
3, 2, 1,
// Left
3 + 4 * 1, 1 + 4 * 1, 0 + 4 * 1,
3 + 4 * 1, 2 + 4 * 1, 1 + 4 * 1,
// Front
3 + 4 * 2, 1 + 4 * 2, 0 + 4 * 2,
3 + 4 * 2, 2 + 4 * 2, 1 + 4 * 2,
// Back
3 + 4 * 3, 1 + 4 * 3, 0 + 4 * 3,
3 + 4 * 3, 2 + 4 * 3, 1 + 4 * 3,
// Right
3 + 4 * 4, 1 + 4 * 4, 0 + 4 * 4,
3 + 4 * 4, 2 + 4 * 4, 1 + 4 * 4,
// Top
3 + 4 * 5, 1 + 4 * 5, 0 + 4 * 5,
3 + 4 * 5, 2 + 4 * 5, 1 + 4 * 5
};
#endregion
mesh.vertices = vertices;
mesh.normals = normales;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateBounds();
return mesh;
}
public static Mesh CreateCapsuleMesh(float radius, float height)
{
int segments = 24;
if (segments % 2 != 0)
segments++;
// extra vertex on the seam
int points = segments + 1;
// calculate points around a circle
float[] pX = new float[points];
float[] pZ = new float[points];
float[] pY = new float[points];
float[] pR = new float[points];
float calcH = 0f;
float calcV = 0f;
for (int i = 0; i < points; i++)
{
pX[i] = Mathf.Sin(calcH * Mathf.Deg2Rad);
pZ[i] = Mathf.Cos(calcH * Mathf.Deg2Rad);
pY[i] = Mathf.Cos(calcV * Mathf.Deg2Rad);
pR[i] = Mathf.Sin(calcV * Mathf.Deg2Rad);
calcH += 360f / segments;
calcV += 180f / segments;
}
// - Vertices and UVs -
Vector3[] vertices = new Vector3[points * (points + 1)];
Vector2[] uvs = new Vector2[vertices.Length];
int ind = 0;
// Y-offset is half the height minus the diameter
float yOff = (height - radius * 2f) * 0.5f;
if (yOff < 0)
yOff = 0;
// uv calculations
float stepX = 1f / (points - 1);
float uvX, uvY;
// Top Hemisphere
int top = Mathf.CeilToInt(points * 0.5f);
for (int y = 0; y < top; y++)
for (int x = 0; x < points; x++)
{
vertices[ind] = new Vector3(pX[x] * pR[y], pY[y], pZ[x] * pR[y]) * radius;
vertices[ind].y = yOff + vertices[ind].y;
uvX = 1f - stepX * x;
uvY = (vertices[ind].y + height * 0.5f) / height;
uvs[ind] = new Vector2(uvX, uvY);
ind++;
}
// Bottom Hemisphere
int btm = Mathf.FloorToInt(points * 0.5f);
for (int y = btm; y < points; y++)
for (int x = 0; x < points; x++)
{
vertices[ind] = new Vector3(pX[x] * pR[y], pY[y], pZ[x] * pR[y]) * radius;
vertices[ind].y = -yOff + vertices[ind].y;
uvX = 1f - stepX * x;
uvY = (vertices[ind].y + height * 0.5f) / height;
uvs[ind] = new UnityEngine.Vector2(uvX, uvY);
ind++;
}
// - Triangles -
int[] triangles = new int[segments * (segments + 1) * 2 * 3];
for (int y = 0, t = 0; y < segments + 1; y++)
for (int x = 0; x < segments; x++, t += 6)
{
triangles[t + 0] = (y + 0) * (segments + 1) + x + 0;
triangles[t + 1] = (y + 1) * (segments + 1) + x + 0;
triangles[t + 2] = (y + 1) * (segments + 1) + x + 1;
triangles[t + 3] = (y + 0) * (segments + 1) + x + 1;
triangles[t + 4] = (y + 0) * (segments + 1) + x + 0;
triangles[t + 5] = (y + 1) * (segments + 1) + x + 1;
}
Mesh mesh = new Mesh();
mesh.Clear();
mesh.name = "ProceduralCapsule";
mesh.vertices = vertices;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateBounds();
mesh.RecalculateNormals();
return mesh;
//_capsuleColliderMesh = mesh;
}
public static Mesh CreateSphereMesh(float radius = 1f)
{
Mesh mesh = new Mesh();
mesh.Clear();
//float radius = 1f;
// Longitude |||
int nbLong = 24;
// Latitude ---
int nbLat = 16;
#region Vertices
Vector3[] vertices = new Vector3[(nbLong + 1) * nbLat + 2];
float _pi = Mathf.PI;
var _2Pi = _pi * 2f;
vertices[0] = Vector3.up * radius;
for (int lat = 0; lat < nbLat; lat++)
{
float a1 = _pi * (lat + 1) / (nbLat + 1);
float sin1 = Mathf.Sin(a1);
float cos1 = Mathf.Cos(a1);
for (int lon = 0; lon <= nbLong; lon++)
{
float a2 = _2Pi * (lon == nbLong ? 0 : lon) / nbLong;
float sin2 = Mathf.Sin(a2);
float cos2 = Mathf.Cos(a2);
vertices[lon + lat * (nbLong + 1) + 1] = new Vector3(sin1 * cos2, cos1, sin1 * sin2) * radius;
}
}
vertices[vertices.Length - 1] = Vector3.up * -radius;
#endregion
#region Normales
Vector3[] normales = new Vector3[vertices.Length];
for (int n = 0; n < vertices.Length; n++)
normales[n] = vertices[n].normalized;
#endregion
#region UVs
UnityEngine.Vector2[] uvs = new UnityEngine.Vector2[vertices.Length];
uvs[0] = UnityEngine.Vector2.up;
uvs[uvs.Length - 1] = UnityEngine.Vector2.zero;
for (int lat = 0; lat < nbLat; lat++)
for (int lon = 0; lon <= nbLong; lon++)
uvs[lon + lat * (nbLong + 1) + 1] =
new UnityEngine.Vector2((float) lon / nbLong, 1f - (float) (lat + 1) / (nbLat + 1));
#endregion
#region Triangles
int nbFaces = vertices.Length;
int nbTriangles = nbFaces * 2;
int nbIndexes = nbTriangles * 3;
int[] triangles = new int[nbIndexes];
//Top Cap
int i = 0;
for (int lon = 0; lon < nbLong; lon++)
{
triangles[i++] = lon + 2;
triangles[i++] = lon + 1;
triangles[i++] = 0;
}
//Middle
for (int lat = 0; lat < nbLat - 1; lat++)
for (int lon = 0; lon < nbLong; lon++)
{
int current = lon + lat * (nbLong + 1) + 1;
int next = current + nbLong + 1;
triangles[i++] = current;
triangles[i++] = current + 1;
triangles[i++] = next + 1;
triangles[i++] = current;
triangles[i++] = next + 1;
triangles[i++] = next;
}
//Bottom Cap
for (int lon = 0; lon < nbLong; lon++)
{
triangles[i++] = vertices.Length - 1;
triangles[i++] = vertices.Length - (lon + 2) - 1;
triangles[i++] = vertices.Length - (lon + 1) - 1;
}
#endregion
mesh.vertices = vertices;
mesh.normals = normales;
mesh.uv = uvs;
mesh.triangles = triangles;
mesh.RecalculateBounds();
return mesh;
}
void Update()
{
if (TouchReactCamera && SelectedCamera)
{
Vector3 oldCameraPosition = TouchReactCamera.transform.position;
Vector3 tempCameraPosition = GetCameraPosition();
var pos = tempCameraPosition;
pos.x = SnapToPixel(pos.x, TouchReactCamera.targetTexture.width, TouchReactCamera.orthographicSize);
pos.y = 0;
pos.z = SnapToPixel(pos.z, TouchReactCamera.targetTexture.height, TouchReactCamera.orthographicSize);
TouchReactCamera.transform.position = pos;
Vector3 offset = pos - oldCameraPosition;
_uvOffset = new Vector2(offset.x / (OrthographicSize * 2),offset.z/(OrthographicSize*2));
}
PrepareRenderTexture();
DrawColliders();
DrawMeshfilters();
UpdateShaders();
CompleteRenderTexture();
}
void PrepareRenderTexture()
{
RenderTexture tempRenderTexture = _lastFrameTouchRenderTexture;
_lastFrameTouchRenderTexture = _currentTouchRenderTexture;
_currentTouchRenderTexture = tempRenderTexture;
TouchReactCamera.targetTexture = _currentTouchRenderTexture;
_currentCamera = Camera.current;
Camera.SetupCurrent(TouchReactCamera);
Graphics.SetRenderTarget(_currentTouchRenderTexture);
GL.Viewport(new Rect(0, 0, TouchReactCamera.targetTexture.width, TouchReactCamera.targetTexture.height));
GL.Clear(true, true, TouchReactCamera.backgroundColor, 1f);
if (_blendBufferMaterial)
{
_blendBufferMaterial.SetFloat(OffsetUid,_uvOffset.x);
_blendBufferMaterial.SetFloat(OffsetVid,-_uvOffset.y);
_blendBufferMaterial.SetFloat(SpeedID,Speed);
Graphics.Blit(_lastFrameTouchRenderTexture,_currentTouchRenderTexture,_blendBufferMaterial);
}
GL.PushMatrix();
GL.LoadProjectionMatrix(TouchReactCamera.projectionMatrix);
//Matrix4x4 orthoMatrix = Matrix4x4.Ortho(-OrthographicSize, OrthographicSize, -OrthographicSize, OrthographicSize, -10000, 10000);
//var projectionMatrix = GL.GetGPUProjectionMatrix(orthoMatrix, true);
//GL.LoadProjectionMatrix(orthoMatrix);
GL.PushMatrix();
_touchReactMaterial.SetPass(0);
}
void CompleteRenderTexture()
{
GL.PopMatrix();
GL.PopMatrix();
Graphics.ClearRandomWriteTargets();
Camera.SetupCurrent(_currentCamera);
}
private void UpdateShaders()
{
Shader.SetGlobalTexture("_TouchReact_Buffer", TouchReactCamera.targetTexture);
Vector4 pos = TouchReactCamera.transform.position;
pos.z = -pos.z;
pos.w = TouchReactCamera.orthographicSize * 2;
pos.x -= TouchReactCamera.orthographicSize;
pos.z -= TouchReactCamera.orthographicSize;
Shader.SetGlobalVector("_TouchReact_Pos", pos);
}
private float SnapToPixel(float v, int textureSize, float orthoSize)
{
float worldPixel = orthoSize * 2 / textureSize;
v = (int) (v / worldPixel);
v *= worldPixel;
return v;
}
private void DrawColliders()
{
for (int i = 0; i <= ColliderList.Count - 1; i++)
{
Collider tempCollider = ColliderList[i].Collider;
if (tempCollider is MeshCollider)
DrawMeshCollider(tempCollider as MeshCollider);
else if (tempCollider is SphereCollider)
DrawSphereCollider(tempCollider as SphereCollider, ColliderList[i].Scale);
else if (tempCollider is BoxCollider)
DrawBoxCollider(tempCollider as BoxCollider, ColliderList[i].Scale);
else if (tempCollider is CapsuleCollider)
DrawCapsuleCollider(tempCollider as CapsuleCollider, ColliderList[i].Scale);
}
}
private void DrawMeshfilters()
{
for (int i = 0; i <= MeshFilterList.Count - 1; i++)
DrawMeshfilter(MeshFilterList[i]);
}
private void DrawBoxCollider(BoxCollider boxCollider, float scale)
{
Vector3 boxScale = new Vector3(boxCollider.size.x * boxCollider.transform.lossyScale.x,
boxCollider.size.y * boxCollider.transform.lossyScale.y,
boxCollider.size.z * boxCollider.transform.lossyScale.z);
Matrix4x4 positionMatrix = Matrix4x4.TRS(boxCollider.bounds.center, boxCollider.transform.rotation,
boxScale * scale);
if (ShowDebugColliders)
Graphics.DrawMesh(_boxColliderMesh, positionMatrix, _touchReactMaterial, 0, null);
//Graphics.DrawMesh(_boxColliderMesh, positionMatrix, _touchReactMaterial, InvisibleLayer, TouchReactCamera);
Graphics.DrawMeshNow(_boxColliderMesh,positionMatrix,0);
}
private void DrawCapsuleCollider(CapsuleCollider capsuleCollider, float scale)
{
Mesh capsuleMesh = GetCapsuleColliderMesh(capsuleCollider.radius, capsuleCollider.height);
Vector3 axisRotation = Vector3.zero;
if (capsuleCollider.direction == 0) axisRotation = new Vector3(0, 0, 90);
if (capsuleCollider.direction == 2) axisRotation = new Vector3(90, 0, 0);
Matrix4x4 positionMatrix = Matrix4x4.TRS(capsuleCollider.bounds.center,
capsuleCollider.transform.rotation * Quaternion.Euler(axisRotation),
capsuleCollider.transform.lossyScale * scale);
if (ShowDebugColliders)
Graphics.DrawMesh(capsuleMesh, positionMatrix, _touchReactMaterial, 0, null);
//Graphics.DrawMesh(capsuleMesh, positionMatrix, _touchReactMaterial, InvisibleLayer, TouchReactCamera);
Graphics.DrawMeshNow(capsuleMesh,positionMatrix,0);
}
private void DrawSphereCollider(SphereCollider sphereCollider, float scale)
{
float sphereScale = GetMaxValue(sphereCollider.transform.lossyScale);
Vector3 sphereScaleVector = new Vector3(sphereScale, sphereScale, sphereScale);
Matrix4x4 positionMatrix = Matrix4x4.TRS(sphereCollider.bounds.center, sphereCollider.transform.rotation,
sphereScaleVector * sphereCollider.radius * scale);
if (ShowDebugColliders)
Graphics.DrawMesh(_sphereColliderMesh, positionMatrix, _touchReactMaterial, 0, null);
//Graphics.DrawMesh(_sphereColliderMesh, positionMatrix, _touchReactMaterial, InvisibleLayer, TouchReactCamera);
Graphics.DrawMeshNow(_sphereColliderMesh,positionMatrix,0);
}
private void DrawMeshCollider(MeshCollider meshCollider)
{
Matrix4x4 positionMatrix = Matrix4x4.TRS(meshCollider.transform.position, meshCollider.transform.rotation,
meshCollider.transform.lossyScale);
Mesh mesh = meshCollider.sharedMesh;
if (mesh)
{
if (ShowDebugColliders)
Graphics.DrawMesh(mesh, positionMatrix, _touchReactMaterial, 0, null);
//Graphics.DrawMesh(mesh, positionMatrix, _touchReactMaterial, InvisibleLayer, TouchReactCamera);
Graphics.DrawMeshNow(mesh,positionMatrix,0);
}
}
private float GetMaxValue(Vector3 vector)
{
float returnValue = float.MinValue;
if (returnValue < vector.x) returnValue = vector.x;
if (returnValue < vector.y) returnValue = vector.y;
if (returnValue < vector.z) returnValue = vector.z;
return returnValue;
}
private void DrawMeshfilter(MeshFilter meshfilter)
{
Matrix4x4 positionMatrix = Matrix4x4.TRS(meshfilter.transform.position, meshfilter.transform.rotation,
meshfilter.transform.lossyScale);
Mesh mesh = meshfilter.sharedMesh;
if (mesh)
{
if (ShowDebugColliders)
Graphics.DrawMesh(mesh, positionMatrix, _touchReactMaterial, 0, null);
//Graphics.DrawMesh(mesh, positionMatrix, _touchReactMaterial, InvisibleLayer, TouchReactCamera);
Graphics.DrawMeshNow(mesh,positionMatrix,0);
}
}
public void Init()
{
if (TouchReactCamera) TouchReactCamera.enabled = false;
if (!TouchReactCamera) CreateTouchReactCamera();
UpdateTouchReactCamera();
FindCamera();
SetupMaterial();
UpdateCamera();
}
void FindCamera()
{
if (AutoselectCamera) SelectedCamera = Camera.main;
if (SelectedCamera == TouchReactCamera) SelectedCamera = null;
if (SelectedCamera == null)
{
Camera[] cameras = FindObjectsOfType<Camera>();
for (int i = 0; i <= cameras.Length - 1; i++)
{
if (cameras[i].gameObject.name.Contains("Main Camera") ||
cameras[i].gameObject.name.Contains("MainCamera"))
{
SelectedCamera = cameras[i];
break;
}
}
if (SelectedCamera == null)
{
for (int i = 0; i <= cameras.Length - 1; i++)
{
if (cameras[i] != TouchReactCamera)
{
SelectedCamera = cameras[i];
break;
}
}
}
}
}
public void UpdateTouchReactCamera()
{
if (TouchReactCamera && HideTouchReactCamera)
{
TouchReactCamera.gameObject.hideFlags = HideFlags.HideInHierarchy;
}
else
{
TouchReactCamera.gameObject.hideFlags = HideFlags.None;
}
}
private void SetupMaterial()
{
_touchReactMaterial =
new Material(Shader.Find("AwesomeTechnologies/TouchReact/RenderTouchBuffer"))
{
#if UNITY_5_6_OR_NEWER
enableInstancing = true
#endif
};
_touchreactMaterialInstanced =
new Material(Shader.Find("AwesomeTechnologies/TouchReact/RenderTouchBufferInstanced"))
{
#if UNITY_5_6_OR_NEWER
enableInstancing = true
#endif
};
_touchreactMaterialPropertyBlock = new MaterialPropertyBlock();
}
private void CreateTouchReactCamera()
{
Transform tourchBendCameraTransform = transform.Find("TouchReactCamera");
if (!tourchBendCameraTransform)
{
GameObject touchReactCameraObject = new GameObject("TouchReactCamera");
touchReactCameraObject.transform.SetParent(transform, false);
touchReactCameraObject.transform.position = Vector3.zero;
touchReactCameraObject.transform.rotation = Quaternion.LookRotation(Vector3.up);
Camera tempEditorCamera = touchReactCameraObject.AddComponent<Camera>();
tempEditorCamera.farClipPlane = 10000;
tempEditorCamera.nearClipPlane = -10000;
tempEditorCamera.depth = -100;
tempEditorCamera.clearFlags = CameraClearFlags.Color;
tempEditorCamera.backgroundColor = Color.black;
tempEditorCamera.renderingPath = RenderingPath.Forward;
tempEditorCamera.useOcclusionCulling = true;
tempEditorCamera.orthographic = true;
tempEditorCamera.orthographicSize = 50f;
// tempEditorCamera.cullingMask = 1 << InvisibleLayer;
#if UNITY_5_6_OR_NEWER
tempEditorCamera.allowMSAA = false;
tempEditorCamera.allowHDR = false;
#endif
tempEditorCamera.stereoTargetEye = StereoTargetEyeMask.None;
TouchReactCamera = tempEditorCamera;
}
else
{
TouchReactCamera = tourchBendCameraTransform.gameObject.GetComponent<Camera>();
}
TouchReactCamera.enabled = false;
}
public Vector3 GetCameraPosition()
{
if (Application.isPlaying)
if (SelectedCamera)
return SelectedCamera.transform.position;
else
return Vector3.zero;
#if UNITY_EDITOR
if (TrSceneViewDetector.GetCurrentSceneViewCamera())
{
return TrSceneViewDetector.GetCurrentSceneViewCamera().transform.position;
}
//Camera[] sceneviewCameras = SceneView.GetAllSceneCameras();
//if (sceneviewCameras.Length > 0)
// return sceneviewCameras[0].transform.position;
return Vector3.zero;
#else
return Vector3.zero;
#endif
}
public void InstanceAddCollider(TouchColliderInfo touchColliderInfo)
{
if (!ColliderList.Contains(touchColliderInfo)) ColliderList.Add(touchColliderInfo);
}
public void InstanceRemoveCollider(TouchColliderInfo touchColliderInfo)
{
ColliderList.Remove(touchColliderInfo);
}
public void InstanceAddMeshFilter(MeshFilter meshFilter)
{
if (!MeshFilterList.Contains(meshFilter)) MeshFilterList.Add(meshFilter);
}
public void InstanceDrawMeshInstanced(Mesh mesh, List<Matrix4x4> instanceList, int subMeshIndex)
{
if (_touchreactMaterialInstanced)
{
if (ShowDebugColliders)
{
Graphics.DrawMeshInstanced(mesh, subMeshIndex, _touchreactMaterialInstanced, instanceList,
_touchreactMaterialPropertyBlock, ShadowCastingMode.Off, false, 0, null);
}
for (int i = 0; i < instanceList.Count; i++)
{
// Graphics.DrawMeshInstanced(mesh, subMeshIndex, _touchreactMaterialInstanced, instanceList,
// _touchreactMaterialPropertyBlock, ShadowCastingMode.Off, false,InvisibleLayer,TouchReactCamera);
Graphics.DrawMeshNow(mesh,instanceList[i],subMeshIndex);
}
}
}
public void InstanceRemoveMeshFilter(MeshFilter meshFilter)
{
MeshFilterList.Remove(meshFilter);
}
public static void FindInstance()
{
Instance = FindObjectOfType<TouchReactSystem>();
}
public static void AddCollider(TouchColliderInfo touchColliderInfo)
{
if (!Instance) FindInstance();
if (Instance) Instance.InstanceAddCollider(touchColliderInfo);
}
public static void RemoveCollider(TouchColliderInfo touchColliderInfo)
{
if (!Instance) FindInstance();
if (Instance) Instance.InstanceRemoveCollider(touchColliderInfo);
}
public static void AddMeshFilter(MeshFilter mesh)
{
if (!Instance) FindInstance();
if (Instance) Instance.InstanceAddMeshFilter(mesh);
}
public static void RemoveMeshFilter(MeshFilter mesh)
{
if (!Instance) FindInstance();
if (Instance) Instance.InstanceRemoveMeshFilter(mesh);
}
public static bool TouchReactEnabled()
{
if (Instance)
{
if (Instance.isActiveAndEnabled) return true;
}
return false;
}
public static void DrawMeshInstanced(Mesh mesh, List<Matrix4x4> instanceList, int subMeshIndex)
{
if (Instance)
{
if (Instance.isActiveAndEnabled)
{
Instance.InstanceDrawMeshInstanced(mesh, instanceList, subMeshIndex);
}
}
}
}
}