Files
beyond/Assets/Scripts/Utils/Extensions.cs

251 lines
8.3 KiB
C#

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace Beyond
{
public static class Extensions
{
public static bool IsAncestor(this Transform trans, Transform ancestor)
{
if (trans.parent == null)
return false;
if (trans.parent == ancestor)
return true;
return trans.parent.IsAncestor(ancestor);
}
public static void SetLayer(this Transform trans, int layer)
{
trans.gameObject.layer = layer;
foreach (Transform child in trans)
child.SetLayer(layer);
}
/*
public static List<T> FindComponentsDownHierarchy<T>(this GameObject g) where T : Component
{
List<T> result = new List<T>();
T component;
component = g.GetComponent<T>();
if (component == null)
component = g.GetComponentInChildren<T>();
return component;
}
*/
public static void SetActiveUpHierarchy(this GameObject g, bool active)
{
g.SetActive(active);
if (g.transform.parent)
{
SetActiveUpHierarchy(g.transform.parent.gameObject, active);
}
}
public static T FindComponentDownHierarchy<T>(this GameObject g) where T : Component
{
T component;
component = g.GetComponent<T>();
if (component == null)
component = g.GetComponentInChildren<T>();
return component;
}
public static T FindComponentUpHierarchy<T>(this GameObject g) where T : Component
{
T component;
component = g.GetComponent<T>();
if (component == null && g.transform.parent != null)
{
component = FindComponentUpHierarchy<T>(g.transform.parent.gameObject);
}
return component;
}
public static void EnableRendererRecursivly(this GameObject g, bool enable)
{
g.GetComponent<Renderer>().enabled = enable;
for (int i = 0; i < g.transform.childCount; i++)
{
EnableRendererRecursivly(g.transform.GetChild(i).gameObject, enable);
}
}
public static T[] GetAllObjectsOnlyInScene<T>() where T : MonoBehaviour
{
#if UNITY_EDITOR
List<T> objectsInScene = new List<T>();
foreach (T go in Resources.FindObjectsOfTypeAll(typeof(T)) as T[])
{
if (!EditorUtility.IsPersistent(go.transform.root.gameObject) && !(go.hideFlags == HideFlags.NotEditable || go.hideFlags == HideFlags.HideAndDontSave))
objectsInScene.Add(go);
}
return objectsInScene.ToArray();
#else
return Resources.FindObjectsOfTypeAll(typeof(T)) as T[];
#endif
}
}
public static class Vector2Extension
{
// positive if v2 is on the left side of v1
public static float SignedAngle(this Vector2 v1, Vector2 v2)
{
Vector2 n1 = v1.normalized;
Vector2 n2 = v2.normalized;
float dot = Vector2.Dot(n1, n2);
if (dot > 1.0f)
dot = 1.0f;
if (dot < -1.0f)
dot = -1.0f;
float theta = Mathf.Acos(dot);
float sgn = Vector2.Dot(new Vector2(-n1.y, n1.x), n2);
if (sgn >= 0f)
return theta;
else
return -theta;
}
public static Vector2 Rotate(this Vector2 v, float theta)
{
float cs = Mathf.Cos(theta);
float sn = Mathf.Sin(theta);
float x1 = v.x * cs - v.y * sn;
float y1 = v.x * sn + v.y * cs;
return new Vector2(x1, y1);
}
}
public static class Vector3Extension
{
public static Vector3 WithX(this Vector3 v, float x)
{
return new Vector3(x, v.y, v.z);
}
public static Vector3 WithY(this Vector3 v, float y)
{
return new Vector3(v.x, y, v.z);
}
public static Vector3 WithZ(this Vector3 v, float z)
{
return new Vector3(v.x, v.y, z);
}
}
public static class Matrix4x4Extension
{
public static Matrix4x4 GetPerspectiveProjection(float left, float right, float bottom, float top, float near, float far)
{
float x = (2.0f * near) / (right - left);
float y = (2.0f * near) / (top - bottom);
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float c = -(far + near) / (far - near);
float d = -(2.0f * far * near) / (far - near);
float e = -1.0f;
Matrix4x4 m = new Matrix4x4();
m[0, 0] = x; m[0, 1] = 0; m[0, 2] = a; m[0, 3] = 0;
m[1, 0] = 0; m[1, 1] = y; m[1, 2] = b; m[1, 3] = 0;
m[2, 0] = 0; m[2, 1] = 0; m[2, 2] = c; m[2, 3] = d;
m[3, 0] = 0; m[3, 1] = 0; m[3, 2] = e; m[3, 3] = 0;
return m;
}
}
public static class GameObjectExt
{
public static void SetLayerRecursively(this GameObject obj, int layer)
{
obj.layer = layer;
foreach (Transform t in obj.transform)
{
t.gameObject.SetLayerRecursively(layer);
}
}
}
public static class QuaternionExt
{
public static Quaternion Mul(this Quaternion quat, float a)
{
Quaternion res = quat;
res.x *= a;
res.y *= a;
res.z *= a;
res.w *= a;
return res;
}
public static Quaternion Normalize(this Quaternion quat)
{
float s = Mathf.Sqrt(quat.x * quat.x + quat.y * quat.y + quat.z * quat.z + quat.w * quat.w);
return quat.Mul(1.0f / s);
}
public static Quaternion Add(this Quaternion lhs, Quaternion rhs)
{
Quaternion res = lhs;
res.x += rhs.x;
res.y += rhs.y;
res.z += rhs.z;
res.w += rhs.w;
return res;
}
}
public static class CameraExtension
{
public static Matrix4x4 GetPerspectiveProjection(this Camera camera)
{
return GetPerspectiveProjection(camera, 0f, 0f);
}
public static Matrix4x4 GetPerspectiveProjection(this Camera camera, float texelOffsetX, float texelOffsetY)
{
if (camera == null)
return Matrix4x4.identity;
float oneExtentY = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView);
float oneExtentX = oneExtentY * camera.aspect;
float texelSizeX = oneExtentX / (0.5f * camera.pixelWidth);
float texelSizeY = oneExtentY / (0.5f * camera.pixelHeight);
float oneJitterX = texelSizeX * texelOffsetX;
float oneJitterY = texelSizeY * texelOffsetY;
float cf = camera.farClipPlane;
float cn = camera.nearClipPlane;
float xm = (oneJitterX - oneExtentX) * cn;
float xp = (oneJitterX + oneExtentX) * cn;
float ym = (oneJitterY - oneExtentY) * cn;
float yp = (oneJitterY + oneExtentY) * cn;
return Matrix4x4Extension.GetPerspectiveProjection(xm, xp, ym, yp, cn, cf);
}
public static Vector4 GetPerspectiveProjectionCornerRay(this Camera camera)
{
return GetPerspectiveProjectionCornerRay(camera, 0f, 0f);
}
public static Vector4 GetPerspectiveProjectionCornerRay(this Camera camera, float texelOffsetX, float texelOffsetY)
{
if (camera == null)
return Vector4.zero;
float oneExtentY = Mathf.Tan(0.5f * Mathf.Deg2Rad * camera.fieldOfView);
float oneExtentX = oneExtentY * camera.aspect;
float texelSizeX = oneExtentX / (0.5f * camera.pixelWidth);
float texelSizeY = oneExtentY / (0.5f * camera.pixelHeight);
float oneJitterX = texelSizeX * texelOffsetX;
float oneJitterY = texelSizeY * texelOffsetY;
return new Vector4(oneExtentX, oneExtentY, oneJitterX, oneJitterY);
}
}
}