void _PickSector(SECTR_Portal myPortal) { HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive)); if (Event.current.type == EventType.MouseMove) { _ComputeCursorVert(); } else if (Event.current.type == EventType.MouseUp && Event.current.button == 0 && !Event.current.alt && !Event.current.control) { SECTR_Sector sector = _GetSectorFromSelection(); if (sector) { SECTR_Undo.Record(myPortal, "Assign Sector to Portal."); if (pickBack) { myPortal.BackSector = sector; } else { myPortal.FrontSector = sector; } EditorUtility.SetDirty(myPortal); pickFront = false; pickBack = false; _EndSelection(); } } else if (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Escape) { pickBack = false; pickFront = false; _EndSelection(); } }
void _SwapSectors(SECTR_Portal myPortal) { SECTR_Undo.Record(myPortal, "Swap Portal Sectors"); SECTR_Sector oldFront = myPortal.FrontSector; SECTR_Sector oldBack = myPortal.BackSector; myPortal.FrontSector = null; myPortal.BackSector = null; myPortal.FrontSector = oldBack; myPortal.BackSector = oldFront; EditorUtility.SetDirty(myPortal); }
private bool _DrawChildControl(SECTR_LOD myLOD, SECTR_LOD.LODSet lodSet, Transform transform, bool hasChildren) { string undoString = "Changed LOD"; bool expanded = false; float labelWidth = Screen.width * 0.3f; float checkWidth = 30; float buffer = 5; Rect propertyRect = EditorGUILayout.BeginHorizontal(GUILayout.Width(labelWidth)); if (hasChildren) { hierarchyFoldouts.TryGetValue(transform, out expanded); hierarchyFoldouts[transform] = EditorGUILayout.Foldout(expanded, transform.name); } else { EditorGUILayout.LabelField(transform.name, GUILayout.Width(labelWidth)); } EditorGUILayout.EndHorizontal(); SECTR_LOD.LODEntry entry = lodSet.GetEntry(transform.gameObject); bool isChecked = entry != null; bool newChecked = GUI.Toggle(new Rect(propertyRect.xMax + buffer, propertyRect.y, checkWidth, propertyRect.height), isChecked, GUIContent.none); if (newChecked != isChecked) { SECTR_Undo.Record(myLOD, undoString); if (newChecked) { entry = lodSet.Add(transform.gameObject, null); } else { lodSet.Remove(transform.gameObject); entry = null; } isChecked = newChecked; myLOD.Reset(); } if (entry != null && transform.GetComponent <Renderer>()) { Renderer newSource = (Renderer)EditorGUI.ObjectField(new Rect(propertyRect.xMax + checkWidth + buffer, propertyRect.y, Screen.width - (propertyRect.xMax + checkWidth + buffer * 2), propertyRect.height), GUIContent.none, entry.lightmapSource, typeof(Renderer), true); if (newSource != entry.lightmapSource) { SECTR_Undo.Record(myLOD, undoString); entry.lightmapSource = newSource; myLOD.Reset(); } } return(expanded); }
void _CompleteHull(SECTR_Hull myHull) { int numNewVerts = newHullVerts.Count; if (numNewVerts >= 3) { Plane hullPlane = new Plane(newHullVerts[0], newHullVerts[1], newHullVerts[2]); Vector3 hullNormal = hullPlane.normal; // For new hulls, set their xform to match the hull geo. if (myHull.ForceEditHull && myHull.CenterOnEdit) { Vector3 newPos = Vector3.zero; for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex) { newPos += newHullVerts[vertIndex]; } newPos /= newHullVerts.Count; myHull.transform.position = newPos; myHull.transform.forward = hullNormal; } // Constructu a new mesh. Mesh newMesh = new Mesh(); newMesh.name = myHull.name; Vector3[] newVerts = new Vector3[numNewVerts]; Vector3[] newNormals = new Vector3[numNewVerts]; Vector2[] newUVs = new Vector2[numNewVerts]; // Compute new positions and normals, which are always in hull local space. Vector3 localNormal = myHull.transform.worldToLocalMatrix.MultiplyVector(hullNormal); Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex) { Vector3 localPosition = myHull.transform.worldToLocalMatrix.MultiplyPoint3x4(newHullVerts[vertIndex]); newVerts[vertIndex] = localPosition; newNormals[vertIndex] = localNormal; min = Vector3.Min(min, localPosition); max = Vector3.Max(max, localPosition); } // Compute a planar projection for the UVs. Vector3 uvScalar = new Vector3(1f / max.x - min.x, 1f / max.y - min.y, 1); for (int vertIndex = 0; vertIndex < numNewVerts; ++vertIndex) { newUVs[vertIndex] = Vector3.Scale(newVerts[vertIndex], uvScalar); } // Triangle indices assume a CW sorting of the verts. int numTriangles = numNewVerts - 2; int[] triangles = new int[numTriangles * 3]; for (int triIndex = 0; triIndex < numTriangles; ++triIndex) { triangles[triIndex * 3] = 0; triangles[triIndex * 3 + 1] = triIndex + 1; triangles[triIndex * 3 + 2] = triIndex + 2; } // Fill out the mesh stuffs. newMesh.vertices = newVerts; newMesh.normals = newNormals; newMesh.uv = newUVs; newMesh.triangles = triangles; // Now create a new, unique mesh asset for the hull. // We use assets instead of storing geometry in the scene to ensure that everything serializes properly. string sceneDir = null; string sceneName = null; string exportDir = SECTR_Asset.MakeExportFolder("Portals", false, out sceneDir, out sceneName); string newAssetName = exportDir + newMesh.name + ".asset"; newAssetName = AssetDatabase.GenerateUniqueAssetPath(newAssetName); AssetDatabase.CreateAsset(newMesh, newAssetName); // Let the hull know that we've modified it in an undo friendly way. SECTR_Undo.Record(myHull, "Created Portal"); myHull.HullMesh = newMesh; } _EndNewHull(myHull, false); }
public override void OnInspectorGUI() { SECTR_LOD myLOD = (SECTR_LOD)target; float lodButtonHeight = 50; float lodGutterSize = 4f; if (lodButtonStyle == null) { lodButtonStyle = new GUIStyle(GUI.skin.button); lodButtonStyle.padding = new RectOffset(); lodButtonStyle.margin = new RectOffset(); } if (Event.current.type == EventType.Repaint) { lodRects.Clear(); } EditorGUILayout.BeginVertical(); Rect lodListRect = EditorGUILayout.BeginVertical(); GUI.enabled = false; GUILayout.Button(GUIContent.none, GUILayout.Height(lodButtonHeight)); GUI.enabled = true; EditorGUILayout.EndVertical(); float addButtonSize = lodListRect.width * 0.1f; int numLODs = myLOD.LODs.Count; float minThreshold = 1; float insertPos = lodListRect.xMin; for (int lodIndex = 0; lodIndex < numLODs; ++lodIndex) { SECTR_LOD.LODSet thisSet = myLOD.LODs[lodIndex]; float buttonScale = 1f - thisSet.Threshold; float percent = 1f; if (lodIndex > 0) { float prevThreshold = myLOD.LODs[lodIndex - 1].Threshold; buttonScale -= 1f - prevThreshold; percent = myLOD.LODs[lodIndex - 1].Threshold; } float buttonWidth = buttonScale * (lodListRect.width - addButtonSize); Rect buttonRect = new Rect(insertPos + lodGutterSize * 0.5f, lodListRect.y, buttonWidth - lodGutterSize, lodListRect.height); if (GUI.Button(buttonRect, "LOD" + lodIndex + "\n" + percent.ToString("P1"), lodButtonStyle)) { selectedLOD = lodIndex; } if (Event.current.type == EventType.Repaint) { lodRects.Add(buttonRect); } insertPos += buttonWidth; minThreshold = Mathf.Min(minThreshold, thisSet.Threshold); } if (minThreshold > 0f && myLOD.LODs.Count > 0) { Rect culledRect = new Rect(insertPos + lodGutterSize * 0.5f, lodListRect.y, lodListRect.xMax - insertPos - addButtonSize - lodGutterSize, lodListRect.height); if (GUI.Button(culledRect, "Culled\n" + minThreshold.ToString("P1"), lodButtonStyle)) { selectedLOD = -1; } if (Event.current.type == EventType.Repaint) { lodRects.Add(culledRect); } } GUI.enabled = minThreshold > 0; Rect addRect = myLOD.LODs.Count > 0 ? new Rect(lodListRect.xMax - addButtonSize, lodListRect.y, addButtonSize, lodListRect.height) : new Rect(lodListRect.xMin, lodListRect.y, lodListRect.width, lodListRect.height); if (GUI.Button(addRect, myLOD.LODs.Count > 0 ? "+" : "+\n(Add LOD)", lodButtonStyle)) { SECTR_Undo.Record(myLOD, "Added LOD"); SECTR_LOD.LODSet newSet = new SECTR_LOD.LODSet(); if (myLOD.LODs.Count == 0) { Transform[] children = myLOD.GetComponentsInChildren <Transform>(); int numChildren = children.Length; for (int childIndex = 0; childIndex < numChildren; ++childIndex) { if (children[childIndex] != myLOD.transform) { newSet.Add(children[childIndex].gameObject, null); } } } else { SECTR_LOD.LODSet prevSet = myLOD.LODs[myLOD.LODs.Count - 1]; int numEntries = prevSet.LODEntries.Count; for (int entryIndex = 0; entryIndex < numEntries; ++entryIndex) { SECTR_LOD.LODEntry prevEntry = prevSet.LODEntries[entryIndex]; newSet.Add(prevEntry.gameObject, prevEntry.lightmapSource); } } newSet.Threshold = minThreshold * 0.5f; selectedLOD = myLOD.LODs.Count; myLOD.LODs.Add(newSet); } GUI.enabled = true; int lodToRemove = -1; if (selectedLOD >= 0 && selectedLOD < myLOD.LODs.Count) { float sliderMin = 0; float sliderMax = 1; if (selectedLOD < myLOD.LODs.Count - 1) { sliderMin = myLOD.LODs[selectedLOD + 1].Threshold; } if (selectedLOD > 0) { sliderMax = myLOD.LODs[selectedLOD - 1].Threshold; } myLOD.LODs[selectedLOD].Threshold = EditorGUILayout.Slider("LOD" + selectedLOD + " Threshold", myLOD.LODs[selectedLOD].Threshold, sliderMin, sliderMax); detailsFoldout = EditorGUILayout.Foldout(detailsFoldout, "LOD" + selectedLOD + " Members"); if (detailsFoldout) { EditorGUILayout.BeginHorizontal(); GUILayout.Label("Name"); GUILayout.Label("Included"); GUILayout.Label("Lightmap Proxy"); EditorGUILayout.EndHorizontal(); _BuildChildControls(myLOD, myLOD.LODs[selectedLOD], myLOD.transform, true); } if (GUILayout.Button("Remove LOD" + selectedLOD)) { if (EditorUtility.DisplayDialog("Confirm LOD Removal", "Are you sure you wish to remove LOD " + selectedLOD + "?", "Yes", "No")) { lodToRemove = selectedLOD; } } } else if (selectedLOD == -1) { serializedObject.Update(); DrawProperty("CullSiblings"); serializedObject.ApplyModifiedProperties(); } EditorGUILayout.EndVertical(); if (lodToRemove >= 0) { SECTR_Undo.Record(myLOD, "Removed LOD"); myLOD.LODs.RemoveAt(lodToRemove); } if (Event.current.type == EventType.Repaint) { lodListRectPerm = lodListRect; } int dragLod = -1; if (lodListRectPerm.Contains(Event.current.mousePosition)) { for (int lodIndex = 0; lodIndex < lodRects.Count - 1; ++lodIndex) { if (Event.current.mousePosition.x > lodRects[lodIndex].xMax && Event.current.mousePosition.x < lodRects[lodIndex + 1].xMin) { dragLod = lodIndex; break; } } } if (dragLod >= 0 && Event.current.type == EventType.MouseDown) { dragging = true; selectedLOD = dragLod; } else if (Event.current.type == EventType.MouseUp) { dragging = false; } if (dragging && lodListRectPerm.Contains(Event.current.mousePosition) && Event.current.type == EventType.MouseDrag) { float newThreshold = 1f - ((Event.current.mousePosition.x - lodListRect.x) / lodListRect.width); newThreshold = Mathf.Clamp01(newThreshold); if (selectedLOD < myLOD.LODs.Count - 1) { newThreshold = Mathf.Max(newThreshold, myLOD.LODs[selectedLOD + 1].Threshold); } if (selectedLOD > 0) { newThreshold = Mathf.Min(newThreshold, myLOD.LODs[selectedLOD - 1].Threshold); } myLOD.LODs[selectedLOD].Threshold = newThreshold; } if (dragging || dragLod >= 0) { EditorGUIUtility.AddCursorRect(new Rect(Event.current.mousePosition.x - 16, Event.current.mousePosition.y - 16, 32, 32), MouseCursor.ResizeHorizontal); } }