2017-04-12 01:23:07 +09:00

512 lines
11 KiB
C#

using UnityEngine;
using System.Collections.Generic;
public static partial class D2D_Helper
{
public static int MeshVertexLimit = 65000;
public static void GetPixelsBilinear(Texture2D t, int x, int y)
{
}
public static void Swap<T>(ref T a, ref T b)
{
var c = b;
b = a;
a = c;
}
public static float Atan2(Vector2 xy)
{
return Mathf.Atan2(xy.x, xy.y);
}
public static void ResizeArrayTo<T>(List<T> array, int size, System.Func<int, T> newT, System.Action<T> removeT)
{
if (array != null)
{
while (array.Count < size)
{
array.Add(newT != null ? newT(array.Count) : default(T));
}
while (array.Count > size)
{
if (removeT != null)
{
removeT(array[array.Count - 1]);
}
array.RemoveAt(array.Count - 1);
}
}
}
private static HideFlags oldHideFlags;
public static void BeginStealthSet(Object o)
{
if (o != null)
{
oldHideFlags = o.hideFlags;
o.hideFlags = HideFlags.DontSave;
}
}
public static void EndStealthSet(Object o)
{
if (o != null)
{
o.hideFlags = oldHideFlags;
}
}
public static void StealthSet(MeshFilter mf, Mesh m)
{
if (mf != null && mf.sharedMesh != m)
{
#if UNITY_EDITOR
var hf = mf.hideFlags;
mf.hideFlags = HideFlags.DontSave;
mf.sharedMesh = m;
mf.hideFlags = hf;
#else
mf.sharedMesh = m;
#endif
}
}
public static void StealthSet(MeshRenderer mr, Material m)
{
if (mr != null && mr.sharedMaterial != m)
{
#if UNITY_EDITOR
var hf = mr.hideFlags;
mr.hideFlags = HideFlags.DontSave;
mr.sharedMaterial = m;
mr.hideFlags = hf;
#else
mr.sharedMaterial = m;
#endif
}
}
public static void SetPosition(Transform t, Vector3 v)
{
if (t != null)
{
#if UNITY_EDITOR
if (Application.isPlaying == false && t.position == v) return;
#endif
t.position = v;
}
}
public static void Destroy(Object o)
{
#if UNITY_EDITOR
if (Application.isPlaying == false)
{
Object.DestroyImmediate(o, true); return;
}
#endif
Object.Destroy(o);
}
public static void DestroyManaged(System.Action DestroyAction)
{
if (DestroyAction != null)
{
#if UNITY_EDITOR
var isPlaying = Application.isPlaying;
UnityEditor.EditorApplication.delayCall += () =>
{
if (Application.isPlaying == isPlaying)
{
DestroyAction();
}
};
#else
DestroyAction();
#endif
}
}
public static void SetParent(Transform t, Transform newParent, bool keepLocalTransform = true)
{
if (t != null && t.parent != newParent)
{
if (keepLocalTransform == true)
{
var oldLocalPosition = t.localPosition;
var oldLocalRotation = t.localRotation;
var oldLocalScale = t.localScale;
t.parent = newParent;
t.localPosition = oldLocalPosition;
t.localRotation = oldLocalRotation;
t.localScale = oldLocalScale;
}
else
{
t.parent = newParent;
}
}
}
public static void SetLocalPosition(Transform t, float x, float y, float z)
{
SetLocalPosition(t, new Vector3(x, y, z));
}
public static void SetLocalPosition(Transform t, Vector3 v)
{
if (t != null)
{
#if UNITY_EDITOR
if (Application.isPlaying == false && t.localPosition == v) return;
#endif
t.localPosition = v;
}
}
public static void SetLocalScale(Transform t, float v)
{
SetLocalScale(t, new Vector3(v, v, v));
}
public static void SetLocalScale(Transform t, Vector3 v)
{
if (t != null)
{
#if UNITY_EDITOR
if (Application.isPlaying == false && t.localScale == v) return;
#endif
if (t.localScale == v) return;
t.localScale = v;
}
}
public static T GetComponentUpwards<T>(Transform transform, bool skipFirst = false)
where T : Component
{
if (transform != null)
{
if (skipFirst == true)
{
transform = transform.parent;
}
while (transform != null)
{
var component = transform.GetComponent<T>();
if (component != null) return component;
transform = transform.parent;
}
}
return null;
}
public static T GetOrAddComponent<T>(GameObject gameObject)
where T : Component
{
if (gameObject != null)
{
var component = gameObject.GetComponent<T>();
if (component == null) component = gameObject.AddComponent<T>();
return component;
}
return null;
}
public static GameObject CloneGameObject(GameObject source, Transform parent, bool keepName = false)
{
if (source != null)
{
var clone = (GameObject)GameObject.Instantiate(source); if (clone == null) throw new System.NullReferenceException();
if (parent != null) SetParent(clone.transform, parent, true);
if (keepName == true) clone.name = source.name;
return clone;
}
return source;
}
public static GameObject CloneGameObject(GameObject source, Transform parent, Vector3 xyz, Quaternion rot, bool keepName = false)
{
if (source != null)
{
var clone = (GameObject)GameObject.Instantiate(source, xyz, rot); if (clone == null) throw new System.NullReferenceException();
if (parent != null) SetParent(clone.transform, parent, true);
if (keepName == true) clone.name = source.name;
return clone;
}
return source;
}
public static GameObject CreateGameObject(string name = "", Transform parent = null)
{
return CreateGameObject(name, parent, Vector3.zero, Quaternion.identity, Vector3.one);
}
public static GameObject CreateGameObject(string name, Transform parent, Vector3 position, Quaternion identity, Vector3 scale)
{
var gameObject = new GameObject(name);
gameObject.transform.parent = parent;
gameObject.transform.localPosition = Vector3.zero;
gameObject.transform.localRotation = Quaternion.identity;
gameObject.transform.localScale = Vector3.one;
return gameObject;
}
public static T Clone<T>(T o, bool keepName = true)
where T : Object
{
if (o != null)
{
var c = (T)Object.Instantiate(o);
if (c != null && keepName == true) c.name = o.name;
return c;
}
return null;
}
public static bool Enabled(Behaviour b)
{
return b != null && b.enabled == true && b.gameObject.activeInHierarchy == true;
}
public static float Divide(float a, float b)
{
return Zero(b) == false ? a / b : 0.0f;
}
public static Vector2 Divide(float xA, float yA, float xB, float yB)
{
return new Vector2(Divide(xA, xB), Divide(yA, yB));
}
public static float Reciprocal(float v)
{
return Zero(v) == false ? 1.0f / v : 0.0f;
}
public static Vector2 Reciprocal(Vector2 v)
{
return new Vector2(Reciprocal(v.x), Reciprocal(v.y));
}
public static Vector2 Reciprocal(float x, float y)
{
return new Vector2(Reciprocal(x), Reciprocal(y));
}
public static Vector3 Reciprocal(Vector3 v)
{
return new Vector3(Reciprocal(v.x), Reciprocal(v.y), Reciprocal(v.z));
}
public static Vector3 Reciprocal(float x, float y, float z)
{
return new Vector3(Reciprocal(x), Reciprocal(y), Reciprocal(z));
}
public static bool Zero(float v)
{
return Mathf.Approximately(v, 0.0f);
}
public static Matrix4x4 RotationMatrix(Quaternion q)
{
var matrix = Matrix4x4.TRS(Vector3.zero, q, Vector3.one);
return matrix;
}
public static Matrix4x4 TranslationMatrix(Vector3 xyz)
{
return TranslationMatrix(xyz.x, xyz.y, xyz.z);
}
public static Matrix4x4 TranslationMatrix(float x, float y, float z)
{
var matrix = Matrix4x4.identity;
matrix.m03 = x;
matrix.m13 = y;
matrix.m23 = z;
return matrix;
}
public static Matrix4x4 ScalingMatrix(float xyz)
{
return ScalingMatrix(xyz, xyz, xyz);
}
public static Matrix4x4 ScalingMatrix(Vector3 xyz)
{
return ScalingMatrix(xyz.x, xyz.y, xyz.z);
}
public static Matrix4x4 ScalingMatrix(float x, float y, float z)
{
var matrix = Matrix4x4.identity;
matrix.m00 = x;
matrix.m11 = y;
matrix.m22 = z;
return matrix;
}
public static float DampenFactor(float dampening, float elapsed)
{
return 1.0f - Mathf.Pow((float)System.Math.E, - dampening * elapsed);
}
public static Quaternion Dampen(Quaternion current, Quaternion target, float dampening, float elapsed, float minStep = 0.0f)
{
var factor = DampenFactor(dampening, elapsed);
var maxDelta = Quaternion.Angle(current, target) * factor + minStep * elapsed;
return MoveTowards(current, target, maxDelta);
}
public static float Dampen(float current, float target, float dampening, float elapsed, float minStep = 0.0f)
{
var factor = DampenFactor(dampening, elapsed);
var maxDelta = Mathf.Abs(target - current) * factor + minStep * elapsed;
return MoveTowards(current, target, maxDelta);
}
public static Vector3 Dampen3(Vector3 current, Vector3 target, float dampening, float elapsed, float minStep = 0.0f)
{
var factor = DampenFactor(dampening, elapsed);
var maxDelta = Mathf.Abs((target - current).magnitude) * factor + minStep * elapsed;
return Vector3.MoveTowards(current, target, maxDelta);
}
public static Quaternion MoveTowards(Quaternion current, Quaternion target, float maxDelta)
{
var delta = Quaternion.Angle(current, target);
return Quaternion.Slerp(current, target, Divide(maxDelta, delta));
}
public static float MoveTowards(float current, float target, float maxDelta)
{
if (target > current)
{
current = System.Math.Min(target, current + maxDelta);
}
else
{
current = System.Math.Max(target, current - maxDelta);
}
return current;
}
public static Vector3 ClosestPointToLineSegment(Vector3 a, Vector3 b, Vector3 point)
{
var l = (b - a).magnitude;
var d = (b - a).normalized;
return a + Mathf.Clamp(Vector3.Dot(point - a, d), 0.0f, l) * d;
}
public static Vector3 ClosestPointToTriangle(Vector3 a, Vector3 b, Vector3 c, Vector3 p)
{
var r = Quaternion.Inverse(Quaternion.LookRotation(-Vector3.Cross(a - b, a - c)));
var ra = r * a;
var rb = r * b;
var rc = r * c;
var rp = r * p;
var a2 = D2D_Helper.VectorXY(ra);
var b2 = D2D_Helper.VectorXY(rb);
var c2 = D2D_Helper.VectorXY(rc);
var p2 = D2D_Helper.VectorXY(rp);
if (PointLeftOfLine(a2, b2, p2) == true)
{
return ClosestPointToLineSegment(a, b, p);
}
if (PointLeftOfLine(b2, c2, p2) == true)
{
return ClosestPointToLineSegment(b, c, p);
}
if (PointLeftOfLine(c2, a2, p2) == true)
{
return ClosestPointToLineSegment(c, a, p);
}
var barycentric = GetBarycentric(a2, b2, c2, p2);
return barycentric.x * a + barycentric.y * b + barycentric.z * c;
}
public static Vector3 GetBarycentric(Vector2 a, Vector2 b, Vector2 c, Vector2 p)
{
var barycentric = Vector3.zero;
var v0 = b - a;
var v1 = c - a;
var v2 = p - a;
var d00 = Vector2.Dot(v0, v0);
var d01 = Vector2.Dot(v0, v1);
var d11 = Vector2.Dot(v1, v1);
var d20 = Vector2.Dot(v2, v0);
var d21 = Vector2.Dot(v2, v1);
var denom = D2D_Helper.Reciprocal(d00 * d11 - d01 * d01);
barycentric.y = (d11 * d20 - d01 * d21) * denom;
barycentric.z = (d00 * d21 - d01 * d20) * denom;
barycentric.x = 1.0f - barycentric.y - barycentric.z;
return barycentric;
}
public static bool PointLeftOfLine(Vector2 a, Vector2 b, Vector2 p) // NOTE: CCW
{
return ((b.x - a.x) * (p.y - a.y) - (p.x - a.x) * (b.y - a.y)) >= 0.0f;
}
public static bool PointRightOfLine(Vector2 a, Vector2 b, Vector2 p) // NOTE: CCW
{
return ((b.x - a.x) * (p.y - a.y) - (p.x - a.x) * (b.y - a.y)) <= 0.0f;
}
public static Vector2 VectorXY(Vector3 xyz)
{
return new Vector2(xyz.x, xyz.y);
}
}