#if UNITY_EDITOR || !(UNITY_WP_8_1 || UNITY_WSA || UNITY_WSA_8_1 || UNITY_WSA_10_0 || UNITY_WINRT || UNITY_WINRT_8_1 || UNITY_WINRT_10_0) using UnityEngine; using System.Collections; using System.Collections.Generic; using System; using System.Linq; using System.Reflection; namespace ProGrids { public static class pg_Util { public static Color ColorWithString(string value) { string valid = "01234567890.,"; value = new string(value.Where(c => valid.Contains(c)).ToArray()); string[] rgba = value.Split(','); // BRIGHT pink if(rgba.Length < 4) return new Color(1f, 0f, 1f, 1f); return new Color( float.Parse(rgba[0]), float.Parse(rgba[1]), float.Parse(rgba[2]), float.Parse(rgba[3])); } private static Vector3 VectorToMask(Vector3 vec) { return new Vector3( Mathf.Abs(vec.x) > Mathf.Epsilon ? 1f : 0f, Mathf.Abs(vec.y) > Mathf.Epsilon ? 1f : 0f, Mathf.Abs(vec.z) > Mathf.Epsilon ? 1f : 0f ); } private static Axis MaskToAxis(Vector3 vec) { Axis axis = Axis.None; if( Mathf.Abs(vec.x) > 0 ) axis |= Axis.X; if( Mathf.Abs(vec.y) > 0 ) axis |= Axis.Y; if( Mathf.Abs(vec.z) > 0 ) axis |= Axis.Z; return axis; } private static Axis BestAxis(Vector3 vec) { float x = Mathf.Abs(vec.x); float y = Mathf.Abs(vec.y); float z = Mathf.Abs(vec.z); return (x > y && x > z) ? Axis.X : ((y > x && y > z) ? Axis.Y : Axis.Z); } public static Axis CalcDragAxis(Vector3 movement, Camera cam) { Vector3 mask = VectorToMask(movement); if(mask.x + mask.y + mask.z == 2) { return MaskToAxis(Vector3.one - mask); } else { switch( MaskToAxis(mask) ) { case Axis.X: if( Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.up)) < Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.forward))) return Axis.Z; else return Axis.Y; case Axis.Y: if( Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.right)) < Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.forward))) return Axis.Z; else return Axis.X; case Axis.Z: if( Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.right)) < Mathf.Abs(Vector3.Dot(cam.transform.forward, Vector3.up))) return Axis.Y; else return Axis.X; default: return Axis.None; } } } public static float ValueFromMask(Vector3 val, Vector3 mask) { if(Mathf.Abs(mask.x) > .0001f) return val.x; else if(Mathf.Abs(mask.y) > .0001f) return val.y; else return val.z; } public static Vector3 SnapValue(Vector3 val, float snapValue) { float _x = val.x, _y = val.y, _z = val.z; return new Vector3( Snap(_x, snapValue), Snap(_y, snapValue), Snap(_z, snapValue) ); } /** * Fetch a type with name and optional assembly name. `type` should include namespace. */ private static Type GetType(string type, string assembly = null) { Type t = Type.GetType(type); if(t == null) { IEnumerable assemblies = AppDomain.CurrentDomain.GetAssemblies(); if(assembly != null) assemblies = assemblies.Where(x => x.FullName.Contains(assembly)); foreach(Assembly ass in assemblies) { t = ass.GetType(type); if(t != null) return t; } } return t; } public static void SetUnityGridEnabled(bool isEnabled) { try { Type annotationUtility = GetType("UnityEditor.AnnotationUtility"); PropertyInfo pi = annotationUtility.GetProperty("showGrid", BindingFlags.NonPublic | BindingFlags.Static); pi.SetValue(null, isEnabled, BindingFlags.NonPublic | BindingFlags.Static, null, null, null); } catch {} } public static bool GetUnityGridEnabled() { try { Type annotationUtility = GetType("UnityEditor.AnnotationUtility"); PropertyInfo pi = annotationUtility.GetProperty("showGrid", BindingFlags.NonPublic | BindingFlags.Static); return (bool) pi.GetValue(null, null); } catch {} return false; } const float EPSILON = .0001f; public static Vector3 SnapValue(Vector3 val, Vector3 mask, float snapValue) { float _x = val.x, _y = val.y, _z = val.z; return new Vector3( ( Mathf.Abs(mask.x) < EPSILON ? _x : Snap(_x, snapValue) ), ( Mathf.Abs(mask.y) < EPSILON ? _y : Snap(_y, snapValue) ), ( Mathf.Abs(mask.z) < EPSILON ? _z : Snap(_z, snapValue) ) ); } public static Vector3 SnapToCeil(Vector3 val, Vector3 mask, float snapValue) { float _x = val.x, _y = val.y, _z = val.z; return new Vector3( ( Mathf.Abs(mask.x) < EPSILON ? _x : SnapToCeil(_x, snapValue) ), ( Mathf.Abs(mask.y) < EPSILON ? _y : SnapToCeil(_y, snapValue) ), ( Mathf.Abs(mask.z) < EPSILON ? _z : SnapToCeil(_z, snapValue) ) ); } public static Vector3 SnapToFloor(Vector3 val, float snapValue) { float _x = val.x, _y = val.y, _z = val.z; return new Vector3( SnapToFloor(_x, snapValue), SnapToFloor(_y, snapValue), SnapToFloor(_z, snapValue) ); } public static Vector3 SnapToFloor(Vector3 val, Vector3 mask, float snapValue) { float _x = val.x, _y = val.y, _z = val.z; return new Vector3( ( Mathf.Abs(mask.x) < EPSILON ? _x : SnapToFloor(_x, snapValue) ), ( Mathf.Abs(mask.y) < EPSILON ? _y : SnapToFloor(_y, snapValue) ), ( Mathf.Abs(mask.z) < EPSILON ? _z : SnapToFloor(_z, snapValue) ) ); } public static float Snap(float val, float round) { return round * Mathf.Round(val / round); } public static float SnapToFloor(float val, float snapValue) { return snapValue * Mathf.Floor(val / snapValue); } public static float SnapToCeil(float val, float snapValue) { return snapValue * Mathf.Ceil(val / snapValue); } public static Vector3 CeilFloor(Vector3 v) { v.x = v.x < 0 ? -1 : 1; v.y = v.y < 0 ? -1 : 1; v.z = v.z < 0 ? -1 : 1; return v; } abstract class SnapEnabledOverride { public abstract bool IsEnabled(); } class SnapIsEnabledOverride : SnapEnabledOverride { bool m_SnapIsEnabled; public SnapIsEnabledOverride(bool snapIsEnabled) { m_SnapIsEnabled = snapIsEnabled; } public override bool IsEnabled() { return m_SnapIsEnabled; } } class ConditionalSnapOverride : SnapEnabledOverride { public System.Func m_IsEnabledDelegate; public ConditionalSnapOverride(System.Func d) { m_IsEnabledDelegate = d; } public override bool IsEnabled() { return m_IsEnabledDelegate(); } } private static Dictionary m_SnapOverrideCache = new Dictionary(); private static Dictionary m_NoSnapAttributeTypeCache = new Dictionary(); private static Dictionary m_ConditionalSnapAttributeCache = new Dictionary(); public static void ClearSnapEnabledCache() { m_SnapOverrideCache.Clear(); } public static bool SnapIsEnabled(Transform t) { SnapEnabledOverride so; if(m_SnapOverrideCache.TryGetValue(t, out so)) return so.IsEnabled(); object[] attribs = null; foreach(Component c in t.GetComponents()) { if(c == null) continue; Type type = c.GetType(); bool hasNoSnapAttrib; if(m_NoSnapAttributeTypeCache.TryGetValue(type, out hasNoSnapAttrib)) { if(hasNoSnapAttrib) { m_SnapOverrideCache.Add(t, new SnapIsEnabledOverride(!hasNoSnapAttrib)); return true; } } else { attribs = type.GetCustomAttributes(true); hasNoSnapAttrib = attribs.Any(x => x != null && x.ToString().Contains("ProGridsNoSnap")); m_NoSnapAttributeTypeCache.Add(type, hasNoSnapAttrib); if(hasNoSnapAttrib) { m_SnapOverrideCache.Add(t, new SnapIsEnabledOverride(!hasNoSnapAttrib)); return true; } } MethodInfo mi; if(m_ConditionalSnapAttributeCache.TryGetValue(type, out mi)) { if(mi != null) { m_SnapOverrideCache.Add(t, new ConditionalSnapOverride(() => { return (bool) mi.Invoke(c, null); })); return (bool) mi.Invoke(c, null); } } else { if( attribs.Any(x => x != null && x.ToString().Contains("ProGridsConditionalSnap")) ) { mi = type.GetMethod("IsSnapEnabled", BindingFlags.Instance | BindingFlags.FlattenHierarchy | BindingFlags.NonPublic | BindingFlags.Public); m_ConditionalSnapAttributeCache.Add(type, mi); if(mi != null) { m_SnapOverrideCache.Add(t, new ConditionalSnapOverride(() => { return (bool) mi.Invoke(c, null); })); return (bool) mi.Invoke(c, null); } } else { m_ConditionalSnapAttributeCache.Add(type, null); } } } m_SnapOverrideCache.Add(t, new SnapIsEnabledOverride(true)); return true; } } public static class PGExtensions { public static bool Contains(this Transform[] t_arr, Transform t) { for(int i = 0; i < t_arr.Length; i++) if(t_arr[i] == t) return true; return false; } public static float Sum(this Vector3 v) { return v[0] + v[1] + v[2]; } public static bool InFrustum(this Camera cam, Vector3 point) { Vector3 p = cam.WorldToViewportPoint(point); return (p.x >= 0f && p.x <= 1f) && (p.y >= 0f && p.y <= 1f) && p.z >= 0f; } } } #endif