A game about forced loneliness, made by TACStudios
at master 240 lines 9.5 kB view raw
1using System; 2using System.Collections.Generic; 3using System.Diagnostics.Eventing.Reader; 4using System.Linq; 5using System.Reflection; 6using UnityEngine; 7using UnityEditor.Graphing; 8using UnityEditor.Graphing.Util; 9using UnityEditor.ShaderGraph.Internal; 10using Object = UnityEngine.Object; 11 12using UnityEditor.UIElements; 13using UnityEngine.UIElements; 14using UnityEngine.UIElements.StyleSheets; 15using UnityEditor.SearchService; 16 17namespace UnityEditor.ShaderGraph.Drawing.Inspector 18{ 19 class MasterPreviewView : VisualElement 20 { 21 PreviewManager m_PreviewManager; 22 GraphData m_Graph; 23 24 PreviewRenderData m_PreviewRenderHandle; 25 Image m_PreviewTextureView; 26 27 public Image previewTextureView 28 { 29 get { return m_PreviewTextureView; } 30 } 31 32 Vector2 m_PreviewScrollPosition; 33 ObjectField m_PreviewMeshPicker; 34 35 Mesh m_PreviousMesh; 36 37 bool m_RecalculateLayout; 38 39 ResizeBorderFrame m_PreviewResizeBorderFrame; 40 41 public ResizeBorderFrame previewResizeBorderFrame 42 { 43 get { return m_PreviewResizeBorderFrame; } 44 } 45 46 VisualElement m_Preview; 47 Label m_Title; 48 49 public VisualElement preview 50 { 51 get { return m_Preview; } 52 } 53 54 List<string> m_DoNotShowPrimitives = new List<string>(new string[] { PrimitiveType.Plane.ToString() }); 55 static Type s_ContextualMenuManipulator = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypesOrNothing()).FirstOrDefault(t => t.FullName == "UnityEngine.UIElements.ContextualMenuManipulator"); 56 static Type s_ObjectSelector = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypesOrNothing()).FirstOrDefault(t => t.FullName == "UnityEditor.ObjectSelector"); 57 58 59 public string assetName 60 { 61 get { return m_Title.text; } 62 set { m_Title.text = value; } 63 } 64 65 public MasterPreviewView(PreviewManager previewManager, GraphData graph) 66 { 67 style.overflow = Overflow.Hidden; 68 m_PreviewManager = previewManager; 69 m_Graph = graph; 70 71 styleSheets.Add(Resources.Load<StyleSheet>("Styles/MasterPreviewView")); 72 73 m_PreviewRenderHandle = previewManager.masterRenderData; 74 if (m_PreviewRenderHandle != null) 75 { 76 m_PreviewRenderHandle.onPreviewChanged += OnPreviewChanged; 77 } 78 79 var topContainer = new VisualElement() { name = "top" }; 80 { 81 m_Title = new Label() { name = "title" }; 82 m_Title.text = "Main Preview"; 83 84 topContainer.Add(m_Title); 85 } 86 Add(topContainer); 87 88 m_Preview = new VisualElement { name = "middle" }; 89 { 90 m_PreviewTextureView = CreatePreview(Texture2D.blackTexture); 91 m_PreviewScrollPosition = new Vector2(0f, 0f); 92 preview.Add(m_PreviewTextureView); 93 preview.AddManipulator(new Scrollable(OnScroll)); 94 } 95 Add(preview); 96 97 m_PreviewResizeBorderFrame = new ResizeBorderFrame(this, this) { name = "resizeBorderFrame" }; 98 m_PreviewResizeBorderFrame.maintainAspectRatio = true; 99 Add(m_PreviewResizeBorderFrame); 100 101 m_RecalculateLayout = false; 102 this.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged); 103 } 104 105 Image CreatePreview(Texture texture) 106 { 107 if (m_PreviewRenderHandle?.texture != null) 108 { 109 texture = m_PreviewRenderHandle.texture; 110 } 111 112 var image = new Image { name = "preview", image = texture, scaleMode = ScaleMode.ScaleAndCrop }; 113 image.AddManipulator(new Draggable(OnMouseDragPreviewMesh, true)); 114 image.AddManipulator((IManipulator)Activator.CreateInstance(s_ContextualMenuManipulator, (Action<ContextualMenuPopulateEvent>)BuildContextualMenu)); 115 return image; 116 } 117 118 void BuildContextualMenu(ContextualMenuPopulateEvent evt) 119 { 120 foreach (var primitiveTypeName in Enum.GetNames(typeof(PrimitiveType))) 121 { 122 if (m_DoNotShowPrimitives.Contains(primitiveTypeName)) 123 continue; 124 evt.menu.AppendAction(primitiveTypeName, e => ChangePrimitiveMesh(primitiveTypeName), DropdownMenuAction.AlwaysEnabled); 125 } 126 127 evt.menu.AppendAction("Sprite", e => ChangeMeshSprite(), DropdownMenuAction.AlwaysEnabled); 128 evt.menu.AppendAction("Custom Mesh", e => ChangeMeshCustom(), DropdownMenuAction.AlwaysEnabled); 129 } 130 131 void OnPreviewChanged() 132 { 133 m_PreviewTextureView.image = m_PreviewRenderHandle?.texture ?? Texture2D.blackTexture; 134 if (m_PreviewRenderHandle != null && m_PreviewRenderHandle.shaderData.isOutOfDate) 135 m_PreviewTextureView.tintColor = new Color(1.0f, 1.0f, 1.0f, 0.3f); 136 else 137 m_PreviewTextureView.tintColor = Color.white; 138 m_PreviewTextureView.MarkDirtyRepaint(); 139 } 140 141 void ChangePrimitiveMesh(string primitiveName) 142 { 143 Mesh changedPrimitiveMesh = Resources.GetBuiltinResource(typeof(Mesh), string.Format("{0}.fbx", primitiveName)) as Mesh; 144 145 ChangeMesh(changedPrimitiveMesh); 146 } 147 148 void ChangeMesh(Mesh mesh) 149 { 150 Mesh changedMesh = mesh; 151 152 m_PreviewManager.UpdateMasterPreview(ModificationScope.Node); 153 154 if (m_Graph.previewData.serializedMesh.mesh != changedMesh) 155 { 156 m_Graph.previewData.rotation = Quaternion.identity; 157 m_PreviewScrollPosition = Vector2.zero; 158 } 159 160 m_Graph.previewData.preventRotation = false; 161 m_Graph.previewData.serializedMesh.mesh = changedMesh; 162 } 163 164 private static EditorWindow Get() 165 { 166 PropertyInfo P = s_ObjectSelector.GetProperty("get", BindingFlags.Public | BindingFlags.Static); 167 return P.GetValue(null, null) as EditorWindow; 168 } 169 170 void OnMeshChanged(Object obj) 171 { 172 var mesh = obj as Mesh; 173 if (mesh == null) 174 mesh = m_PreviousMesh; 175 ChangeMesh(mesh); 176 } 177 178 void ChangeMeshSprite() 179 { 180 ChangePrimitiveMesh(PrimitiveType.Quad.ToString()); 181 182 m_Graph.previewData.rotation = Quaternion.identity; 183 m_Graph.previewData.preventRotation = true; 184 } 185 186 void ChangeMeshCustom() 187 { 188 var ShowMethod = s_ObjectSelector.GetMethod("Show", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(UnityEngine.Object), typeof(Type), typeof(UnityEngine.Object), typeof(bool), typeof(List<int>), typeof(Action<UnityEngine.Object>), typeof(Action<UnityEngine.Object>), typeof(bool) }, new ParameterModifier[8]); 189 m_PreviousMesh = m_Graph.previewData.serializedMesh.mesh; 190 ShowMethod.Invoke(Get(), new object[] { null, typeof(Mesh), null, false, null, (Action<Object>)OnMeshChanged, (Action<Object>)OnMeshChanged, false }); 191 } 192 193 void OnGeometryChanged(GeometryChangedEvent evt) 194 { 195 if (m_RecalculateLayout) 196 { 197 WindowDockingLayout dockingLayout = new WindowDockingLayout(); 198 dockingLayout.CalculateDockingCornerAndOffset(layout, parent.layout); 199 dockingLayout.ClampToParentWindow(); 200 dockingLayout.ApplyPosition(this); 201 m_RecalculateLayout = false; 202 } 203 204 var currentWidth = m_PreviewRenderHandle?.texture != null ? m_PreviewRenderHandle.texture.width : -1; 205 var currentHeight = m_PreviewRenderHandle?.texture != null ? m_PreviewRenderHandle.texture.height : -1; 206 207 var targetWidth = Mathf.Max(1f, m_PreviewTextureView.contentRect.width); 208 var targetHeight = Mathf.Max(1f, m_PreviewTextureView.contentRect.height); 209 210 if (Mathf.Approximately(currentWidth, targetHeight) && Mathf.Approximately(currentHeight, targetWidth)) 211 return; 212 213 m_PreviewTextureView.style.width = evt.newRect.width; 214 m_PreviewTextureView.style.height = evt.newRect.height - 40.0f; 215 m_PreviewManager.ResizeMasterPreview(new Vector2(evt.newRect.width, evt.newRect.width)); 216 } 217 218 void OnScroll(float scrollValue) 219 { 220 float rescaleAmount = -scrollValue * .03f; 221 m_Graph.previewData.scale = Mathf.Clamp(m_Graph.previewData.scale + rescaleAmount, 0.2f, 5f); 222 223 m_PreviewManager.UpdateMasterPreview(ModificationScope.Node); 224 } 225 226 void OnMouseDragPreviewMesh(Vector2 deltaMouse) 227 { 228 if (m_Graph.previewData.preventRotation) return; 229 230 Vector2 previewSize = m_PreviewTextureView.contentRect.size; 231 232 m_PreviewScrollPosition -= deltaMouse * (Event.current.shift ? 3f : 1f) / Mathf.Min(previewSize.x, previewSize.y) * 140f; 233 m_PreviewScrollPosition.y = Mathf.Clamp(m_PreviewScrollPosition.y, -90f, 90f); 234 Quaternion previewRotation = Quaternion.Euler(m_PreviewScrollPosition.y, 0, 0) * Quaternion.Euler(0, m_PreviewScrollPosition.x, 0); 235 m_Graph.previewData.rotation = previewRotation; 236 237 m_PreviewManager.UpdateMasterPreview(ModificationScope.Node); 238 } 239 } 240}