void UpdateGradient() { waterGradient = PWUtils.CreateGradient(GradientMode.Fixed, new KeyValuePair <float, Color>(waterLevel / (mapMax - mapMin), Color.blue), new KeyValuePair <float, Color>(1, Color.white)); PWGUI.SetGradientForField(0, waterGradient); }
private T GetGUISettingData <T>(Func <T> newGUISettings) where T : PWGUISettings { if (settingsStorage == null) { settingsStorage = new List <PWGUISettings>(); } if (currentSettingCount == settingsStorage.Count) { var s = newGUISettings(); s.windowPosition = PWUtils.Round(editorWindowRect.size / 2); settingsStorage.Add(s); } if (settingsStorage[currentSettingCount].GetType() != typeof(T)) { //try cast, if fails create a new object T ret = settingsStorage[currentSettingCount] as T; if (ret != null) { return(ret); } Debug.Log("type mismatch and cast fail, creating a new insatnce !"); settingsStorage[currentSettingCount] = newGUISettings(); } return(settingsStorage[currentSettingCount++] as T); }
void SelectAndDrag() { Profiler.BeginSample("[PW] Select and drag"); //rendering the selection rect if (editorEvents.isSelecting) { Rect posiviteSelectionRect = PWUtils.CreateRect(e.mousePosition, editorEvents.selectionStartPoint); Rect decaledSelectionRect = PWUtils.DecalRect(posiviteSelectionRect, -graph.panPosition); //draw selection rect if (e.type == EventType.Repaint) { selectionStyle.Draw(posiviteSelectionRect, false, false, false, false); } //iterate throw all nodes of the graph and check if the selection overlaps graph.nodes.ForEach(n => n.isSelected = decaledSelectionRect.Overlaps(n.rect)); editorEvents.selectedNodeCount = graph.nodes.Count(n => n.isSelected); } //multiple window drag: if (e.type == EventType.MouseDrag && editorEvents.isDraggingSelectedNodes) { graph.nodes.ForEach(n => { if (n.isSelected) { n.rect.position += e.delta; } }); } Profiler.EndSample(); }
public override void OnNodeProcess() { if (inputTerrain != null) { PWUtils.ResizeSamplerIfNeeded(inputTerrain, ref outputTerrain); } if (!needUpdate) { return; } UpdateTerrain(); }
public override void OnNodeCreate() { externalName = "Temperature node"; temperatureGradient = PWUtils.CreateGradient( new KeyValuePair <float, Color>(0f, Color.blue), new KeyValuePair <float, Color>(.25f, Color.cyan), new KeyValuePair <float, Color>(.5f, Color.yellow), new KeyValuePair <float, Color>(.75f, PWColorPalette.orange), new KeyValuePair <float, Color>(1f, Color.red) ); UpdateTemperatureMap(); }
public override object OnChunkCreate(ChunkData cd, Vector3 pos) { if (cd == null) { return(null); } if (rainbow == null) { rainbow = PWUtils.CreateRainbowGradient(); } TopDown2DData chunk = (TopDown2DData)cd; //create the terrain texture: //TODO: bind the blendMap with biome maps to the terrain shader //TODO: bind all vertex datas from the mesh GameObject g = CreateChunkObject(pos * terrainScale); g.transform.rotation = Quaternion.identity; g.transform.localScale = Vector3.one * chunkSize * terrainScale; MeshRenderer mr = g.AddComponent <MeshRenderer>(); MeshFilter mf = g.AddComponent <MeshFilter>(); if (topDownTerrainMesh == null || topDownTerrainMeshSize != chunkSize) { GenerateTopDownTerrainMesh(); } UpdateMeshDatas(chunk.biomeMap); mf.sharedMesh = topDownTerrainMesh; Shader topDown2DBasicTerrainShader = Shader.Find("ProceduralWorlds/Basic terrain"); if (topDown2DBasicTerrainShader == null) { topDown2DBasicTerrainShader = Shader.Find("Standard"); } Material mat = new Material(topDown2DBasicTerrainShader); mat.SetTexture("_AlbedoMaps", chunk.albedoMaps); mr.sharedMaterial = mat; //TODO: vertex painting return(g); }
public override void OnNodeEnable() { UpdateTemperatureMap(); temperatureGradient = PWUtils.CreateGradient( new KeyValuePair <float, Color>(0f, Color.blue), new KeyValuePair <float, Color>(.25f, Color.cyan), new KeyValuePair <float, Color>(.5f, Color.yellow), new KeyValuePair <float, Color>(.75f, PWColor.orange), new KeyValuePair <float, Color>(1f, Color.red) ); delayedChanges.BindCallback(delayedTemperatureKey, (unused) => { NotifyReload(); }); }
public bool Overlaps(BiomeSwitchCellParams cellParams) { int length = cellParams.switchParams.Length; for (int i = 0; i < length; i++) { var c = cellParams.switchParams[i]; var sp = switchParams.switchParams[i]; if (c.enabled && sp.enabled && !PWUtils.Overlap(sp.min, sp.max, c.min, c.max)) { return(false); } } return(true); }
public float GapWidth(BiomeSwitchCell c2) { float gap = 0; int length = c2.switchParams.switchParams.Length; for (int i = 0; i < length; i++) { if (switchParams.switchParams[i].enabled) { var s1 = switchParams.switchParams[i]; var s2 = c2.switchParams.switchParams[i]; gap += PWUtils.GapWidth(s1.min, s1.max, s2.min, s2.max); } } return(gap); }
public float GapWidth(BiomeSurfaceSwitch b2) { float gap = 0; if (heightEnabled) { gap += PWUtils.GapWidth(minHeight, maxHeight, b2.minHeight, b2.maxHeight); } if (slopeEnabled) { gap += PWUtils.GapWidth(minSlope, maxSlope, b2.minSlope, b2.maxSlope); } if (paramEnabled) { gap += PWUtils.GapWidth(minParam, maxParam, b2.minParam, b2.maxParam); } return(gap); }
void RenderDecaledNode(int id, PWNode node) { //node grid snapping when pressing cmd/crtl if (node.isDragged && e.command) { Vector2 pos = node.rect.position; //aproximative grid cell size float snapPixels = 25.6f; pos.x = Mathf.RoundToInt(Mathf.RoundToInt(pos.x / snapPixels) * snapPixels); pos.y = Mathf.RoundToInt(Mathf.RoundToInt(pos.y / snapPixels) * snapPixels); node.rect.position = pos; } //move the node if panPosition changed: node.rect = PWUtils.DecalRect(node.rect, graph.panPosition); Rect decaledRect = GUILayout.Window(id, node.rect, node.OnWindowGUI, node.name, (node.isSelected) ? nodeSelectedStyle : nodeStyle, GUILayout.Height(node.viewHeight)); node.visualRect = decaledRect; node.rect = PWUtils.DecalRect(decaledRect, -graph.panPosition); //draw node header: //Draw the node header using the color scheme: if (e.type == EventType.Repaint) { float h = nodeStyle.border.top; float w = decaledRect.width - nodeStyle.border.right - nodeStyle.border.left; GUI.color = PWColorTheme.GetNodeColor(node.colorSchemeName); // GUI.DrawTexture(new Rect(0, 0, w, h), nodeHeaderStyle.normal.background); nodeHeaderStyle.Draw(new Rect(decaledRect.x, decaledRect.y, w, h), false, false, false, false); GUI.color = Color.white; } if (node.debug) { Rect debugRect = decaledRect; debugRect.y -= 20; EditorGUI.LabelField(debugRect, "id: " + node.id); debugRect.y -= 20; EditorGUI.LabelField(debugRect, "comp order: " + node.computeOrder + " | can work: " + node.canWork); } }
void RenderNode(int id, PWNode node) { RenderDecaledNode(id, node); //check if the mouse is over this node if (node.rect.Contains(e.mousePosition - graph.panPosition)) { graph.editorEvents.mouseOverNode = node; graph.editorEvents.isMouseOverNodeFrame = true; } //display the process time of the window (if > .1ms) if (node.processTime > .1f) { GUIStyle gs = new GUIStyle(); Rect msRect = PWUtils.DecalRect(node.rect, graph.panPosition); msRect.position += new Vector2(msRect.size.x / 2 - 10, msRect.size.y + 5); gs.normal.textColor = greenRedGradient.Evaluate(node.processTime / 20); //20ms ok, after is red GUI.Label(msRect, node.processTime.ToString("F1") + " ms", gs); } }
public override void OnNodeProcess() { if (mergedBiomeTerrain == null) { mergedBiomeTerrain = new FinalTerrain(); } if (inputBlendedTerrain.biomeData == null) { Debug.LogError("[PWBiomeMerger] Can't find BiomeData, did you forgot to specify the BiomeGraph in a Biome node"); return; } var inputTerrain = inputBlendedTerrain.biomeData.GetSampler(BiomeSamplerName.terrainHeight); finalTerrain = inputTerrain.Clone(finalTerrain); if (finalTerrain.type == SamplerType.Sampler2D) { BiomeMap2D biomeMap = inputBlendedTerrain.biomeData.biomeMap; (finalTerrain as Sampler2D).Foreach((x, y, val) => { float ret = 0; var biomeInfo = biomeMap.GetBiomeBlendInfo(x, y); foreach (var biome in inputBlendedTerrain.biomes) { var terrain = biome.modifiedTerrain as Sampler2D; if (terrain == null) { PWUtils.LogErrorMax("[PWNodeMerger] can't access to the terrain of the biome " + biome.id + "(" + biome.name + ")", 100); continue; } //TODO: test this blending ! for (int i = 0; i < biomeInfo.length; i++) { if (biomeInfo.biomeIds[i] == biome.id) { ret += terrain[x, y] * biomeInfo.biomeBlends[i] / biomeInfo.totalBlend; } } } return(ret); }); } else if (finalTerrain.type == SamplerType.Sampler3D) { Debug.Log("TODO: 3D Terrains"); } mergedBiomeTerrain.biomeData = inputBlendedTerrain.biomeData; mergedBiomeTerrain.mergedTerrain = finalTerrain; mergedBiomeTerrain.materializerType = mainGraphRef.materializerType; mergedBiomeTerrain.biomeSurfacesList.Clear(); foreach (var biome in inputBlendedTerrain.biomes) { if (mergedBiomeTerrain.biomeSurfacesList.ContainsKey(biome.id)) { Debug.LogError("[PWBiomeMerger] Duplicate biome in the biome graph: " + biome.name + ", id: " + biome.id); } mergedBiomeTerrain.biomeSurfacesList[biome.id] = biome.biomeSurfaceGraph; } update = true; }
public void Sampler2DPreview(GUIContent prefix, Sampler2D samp, bool update, bool settings = true, FilterMode fm = FilterMode.Bilinear) { int previewSize = (int)currentWindowRect.width - 20 - 20; //padding + texture margin var e = Event.current; if (samp == null) { return; } if (prefix != null && !String.IsNullOrEmpty(prefix.text)) { EditorGUILayout.LabelField(prefix); } var fieldSettings = GetGUISettingData(() => { var state = new PWGUISettings(); state.filterMode = fm; state.debug = false; state.gradient = new SerializableGradient( PWUtils.CreateGradient( new KeyValuePair <float, Color>(0, Color.black), new KeyValuePair <float, Color>(1, Color.white) ) ); return(state); }); //recreated texture if it has been destoryed: if (fieldSettings.texture == null) { fieldSettings.texture = new Texture2D(previewSize, previewSize, TextureFormat.RGBA32, false); fieldSettings.texture.filterMode = fieldSettings.filterMode; } //same for the gradient: if (fieldSettings.gradient == null || fieldSettings.gradient.alphaKeys == null) { fieldSettings.gradient = fieldSettings.serializableGradient; } Texture2D tex = fieldSettings.texture; Gradient gradient = fieldSettings.gradient; if (samp.size != tex.width) { tex.Resize(samp.size, samp.size, TextureFormat.RGBA32, false); } Rect previewRect = EditorGUILayout.GetControlRect(GUILayout.ExpandWidth(true), GUILayout.Height(0)); if (previewRect.width > 2) { fieldSettings.savedRect = previewRect; } TexturePreview(tex, false, false, false); //draw the settings window if (settings && fieldSettings.active) { PWPopup.AddToRender(fieldSettings, "Sampler 2D settings", () => { EditorGUILayout.BeginVertical(); { EditorGUI.BeginChangeCheck(); fieldSettings.filterMode = (FilterMode)EditorGUILayout.EnumPopup(fieldSettings.filterMode); if (EditorGUI.EndChangeCheck()) { tex.filterMode = fieldSettings.filterMode; } gradient = (Gradient)gradientField.Invoke(null, new object[] { "", gradient, null }); if (!gradient.Compare(fieldSettings.serializableGradient)) { fieldSettings.update = true; } fieldSettings.serializableGradient = (SerializableGradient)gradient; } EditorGUILayout.EndVertical(); if (e.type == EventType.KeyDown && fieldSettings.active) { if (e.keyCode == KeyCode.Return || e.keyCode == KeyCode.KeypadEnter || e.keyCode == KeyCode.Escape) { fieldSettings.InActive(); e.Use(); } } EditorGUIUtility.labelWidth = 100; fieldSettings.debug = EditorGUILayout.Toggle("debug", fieldSettings.debug); if (GUILayout.Button("force update")) { fieldSettings.update = true; } }); } if (settings) { //draw the setting icon and manage his events int icSettingsSize = 16; int icSettingsPadding = 4; Rect icSettingsRect = new Rect(previewRect.x + previewRect.width - icSettingsSize - icSettingsPadding, previewRect.y + icSettingsPadding, icSettingsSize, icSettingsSize); GUI.DrawTexture(icSettingsRect, ic_settings); if (e.type == EventType.MouseDown && e.button == 0) { if (icSettingsRect.Contains(e.mousePosition)) { fieldSettings.Invert(null); e.Use(); } else if (fieldSettings.active) { fieldSettings.InActive(); e.Use(); } } } if (!settings && fieldSettings.texture.filterMode != fm) { fieldSettings.texture.filterMode = fm; } //update the texture with the gradient if (update || fieldSettings.update) { samp.Foreach((x, y, val) => { tex.SetPixel(x, y, gradient.Evaluate(Mathf.Clamp01(val))); }, true); tex.Apply(); fieldSettings.update = false; } if (fieldSettings.debug) { Vector2 pixelPos = e.mousePosition - fieldSettings.savedRect.position; pixelPos *= samp.size / fieldSettings.savedRect.width; EditorGUILayout.LabelField("Sampler2D min: " + samp.min + ", max: " + samp.max); if (pixelPos.x >= 0 && pixelPos.y >= 0 && pixelPos.x < samp.size && pixelPos.y < samp.size) { if (e.isMouse) { e.Use(); } EditorGUILayout.LabelField("(" + (int)pixelPos.x + ", " + (int)pixelPos.y + "): " + samp[(int)pixelPos.x, (int)pixelPos.y]); } else { EditorGUILayout.LabelField("(NA, NA): NA"); } } }
public override void OnNodeProcess() { ints = values.GetValues <int>(); floats = values.GetValues <float>(); vec2s = values.GetValues <Vector2>(); vec3s = values.GetValues <Vector3>(); vec4s = values.GetValues <Vector4>(); //check nominal type: fOutput = 0; v2Output = Vector2.zero; v3Output = Vector3.zero; v4Output = Vector4.zero; if (vec4s.Count != 0) { foreach (var vec4 in vec4s) { v4Output += vec4; } foreach (var vec3 in vec3s) { v4Output += (Vector4)vec3; } foreach (var vec2 in vec2s) { v4Output += (Vector4)vec2; } foreach (var flt in floats) { v4Output += new Vector4(flt, flt, flt, flt); } foreach (var integer in ints) { v4Output += new Vector4(integer, integer, integer, integer); } if (intify) { v4Output = PWUtils.Round(v4Output); } } else if (vec3s.Count != 0) { foreach (var vec3 in vec3s) { v3Output += (Vector3)vec3; } foreach (var vec2 in vec2s) { v3Output += (Vector3)vec2; } foreach (var flt in floats) { v3Output += new Vector3(flt, flt, flt); } foreach (var integer in ints) { v3Output += new Vector3(integer, integer, integer); } if (intify) { v3Output = PWUtils.Round(v3Output); } } else if (vec2s.Count != 0) { foreach (var vec2 in vec2s) { v2Output += (Vector2)vec2; } foreach (var flt in floats) { v2Output += new Vector2(flt, flt); } foreach (var integer in ints) { v2Output += new Vector2(integer, integer); } if (intify) { v2Output = PWUtils.Round(v2Output); } } else //int and floats { foreach (var flt in floats) { fOutput += flt; } foreach (var integer in ints) { fOutput += integer; } if (intify) { fOutput = Mathf.Round(fOutput); } } }
public bool Overlaps(BiomeSurfaceSwitch b2) { bool slopeOverlaps = (!slopeEnabled || !b2.slopeEnabled) || (slopeEnabled && b2.slopeEnabled && PWUtils.Overlap(minSlope, maxSlope, b2.minSlope, b2.maxSlope)); bool heightOverlaps = (!heightEnabled || !b2.heightEnabled) || (heightEnabled && b2.heightEnabled && PWUtils.Overlap(minHeight, maxHeight, b2.minHeight, b2.maxHeight)); bool paramOverlaps = (!paramEnabled || !b2.paramEnabled) || (paramEnabled && b2.paramEnabled && PWUtils.Overlap(minParam, maxParam, b2.minParam, b2.maxParam)); return(slopeOverlaps && heightOverlaps && paramOverlaps); }
public void FillBiomeMap(int biomeBlendCount, BiomeData biomeData) { bool is3DBiomes = false; bool is3DTerrain = biomeData.terrain3D != null; Biome[] nearestBiomes = new Biome[biomeBlendCount]; //TODO: biome blend count > 1 management //TODO: biomeData.datas3D null check if (biomeData.air3D != null || biomeData.wind3D != null || biomeData.wetness3D != null || biomeData.temperature3D != null) { is3DBiomes = true; } if (biomeData.terrainRef == null) { return; } int terrainSize = (is3DTerrain) ? biomeData.terrain3D.size : biomeData.terrain.size; float terrainStep = (is3DTerrain) ? biomeData.terrain3D.step : biomeData.terrain.step; if (is3DBiomes) { biomeData.biomeIds3D = new BiomeMap3D(terrainSize, terrainStep); } else { biomeData.biomeIds = new BiomeMap2D(terrainSize, terrainStep); } if (is3DBiomes) { //TODO } else { for (int x = 0; x < terrainSize; x++) { for (int y = 0; y < terrainSize; y++) { bool water = (biomeData.isWaterless) ? false : biomeData.waterHeight[x, y] > 0; float temp = (biomeData.temperature != null) ? biomeData.temperature[x, y] : 0; float wet = (biomeData.wetness != null) ? biomeData.wetness[x, y] : 0; // Debug.Log("map [" + x + "/" + y + "] = " + biomeData.terrain[x, y]); //TODO: 3D terrain management float height = (is3DTerrain) ? 0 : biomeData.terrain[x, y]; BiomeSwitchNode current = root; while (true) { nextChild: if (current.biome != null) { break; } int childCount = current.GetChildCount(); for (int i = 0; i < childCount; i++) { var child = current.GetChildAt(i); switch (child.biomeSwitchMode) { case BiomeSwitchMode.Water: if (child.value == water) { current = child; goto nextChild; } break; case BiomeSwitchMode.Height: if (height > child.min && height <= child.max) { current = child; goto nextChild; } break; case BiomeSwitchMode.Temperature: if (temp > child.min && temp <= child.max) { current = child; goto nextChild; } break; case BiomeSwitchMode.Wetness: if (wet > child.min && wet <= child.max) { current = child; goto nextChild; } break; } } //if flow reach this part, values are missing in the biome graph so biome can't be chosen. break; } //TODO: blending with second biome if (current.biome != null) { biomeData.biomeIds.SetFirstBiomeId(x, y, current.biome.id); } else { //FIXME!!!! biomeData.biomeIds.SetFirstBiomeId(x, y, -1); // PWUtils.LogWarningMax("Can't choose biome with water:" + water + ", temp: " + temp + ", wet: " + wet + ", height: " + height, 200); PWUtils.LogWarningMax("Can't choose biome with water:" + water + ", temp: " + temp + ", wet: " + wet + ", height: " + height, 300); continue; } } } } }
public void Render(PWGraph graph, Vector2 screenSize) { var e = Event.current; Rect screen = new Rect(-graph.panPosition, screenSize); //check if ordering group is not visible if (!orderGroupRect.Overlaps(screen)) { return; } //Start GUI frame PWGUI.StartFrame(screen); if (orderingGroupStyle == null) { LoadStyles(); } Rect orderGroupWorldRect = PWUtils.DecalRect(orderGroupRect, graph.panPosition); callbackId = 0; int controlSize = 8; int cornerSize = 14; CreateAnchorRectCallabck( //left resize anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y + cornerSize, controlSize, orderGroupWorldRect.height - cornerSize * 2), MouseCursor.ResizeHorizontal, () => orderGroupRect.xMin += e.delta.x ); CreateAnchorRectCallabck( //right resize anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - controlSize, orderGroupWorldRect.y + cornerSize, controlSize, orderGroupWorldRect.height - cornerSize * 2), MouseCursor.ResizeHorizontal, () => orderGroupRect.xMax += e.delta.x ); CreateAnchorRectCallabck( //top resize anchor new Rect(orderGroupWorldRect.x + cornerSize, orderGroupWorldRect.y, orderGroupWorldRect.width - cornerSize * 2, controlSize), MouseCursor.ResizeVertical, () => orderGroupRect.yMin += e.delta.y ); CreateAnchorRectCallabck( //down resize anchor new Rect(orderGroupWorldRect.x + cornerSize, orderGroupWorldRect.y + orderGroupWorldRect.height - controlSize, orderGroupWorldRect.width - cornerSize * 2, controlSize), MouseCursor.ResizeVertical, () => orderGroupRect.yMax += e.delta.y ); CreateAnchorRectCallabck( //top left anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y, cornerSize, cornerSize), MouseCursor.ResizeUpLeft, () => { orderGroupRect.yMin += e.delta.y; orderGroupRect.xMin += e.delta.x; } ); CreateAnchorRectCallabck( //top right anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - cornerSize, orderGroupWorldRect.y, cornerSize, cornerSize), MouseCursor.ResizeUpRight, () => { orderGroupRect.yMin += e.delta.y; orderGroupRect.xMax += e.delta.x; } ); CreateAnchorRectCallabck( //down left anchor new Rect(orderGroupWorldRect.x, orderGroupWorldRect.y + orderGroupWorldRect.height - cornerSize, cornerSize, cornerSize), MouseCursor.ResizeUpRight, () => { orderGroupRect.yMax += e.delta.y; orderGroupRect.xMin += e.delta.x; } ); CreateAnchorRectCallabck( //down right anchor new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - cornerSize, orderGroupWorldRect.y + orderGroupWorldRect.height - cornerSize, cornerSize, cornerSize), MouseCursor.ResizeUpLeft, () => { orderGroupRect.yMax += e.delta.y; orderGroupRect.xMax += e.delta.x; } ); if (e.rawType == EventType.MouseUp) { resizing = false; } //draw renamable name field orderingGroupNameStyle.normal.textColor = color; PWGUI.TextField(orderGroupWorldRect.position + new Vector2(10, -22), ref name, true, orderingGroupNameStyle); //draw move pad Rect movePadRect = new Rect(orderGroupWorldRect.position + new Vector2(10, 10), new Vector2(50, 30)); GUI.DrawTextureWithTexCoords(movePadRect, movepadTexture, new Rect(0, 0, 5, 4)); EditorGUIUtility.AddCursorRect(movePadRect, MouseCursor.MoveArrow); if (e.type == EventType.MouseDown && e.button == 0) { if (movePadRect.Contains(e.mousePosition)) { innerNodes = graph.nodes.Where(n => n.rect.Overlaps(orderGroupRect)).ToList(); moving = true; e.Use(); } } if (e.rawType == EventType.MouseUp) { moving = false; } if (moving && e.type == EventType.MouseDrag) { orderGroupRect.position += e.delta; innerNodes.ForEach(n => n.rect.position += e.delta); } //draw ordering group GUI.color = color; GUI.Label(orderGroupWorldRect, (string)null, orderingGroupStyle); GUI.color = Color.white; //draw color picker Rect colorPickerRect = new Rect(orderGroupWorldRect.x + orderGroupWorldRect.width - 30, orderGroupWorldRect.y + 10, 20, 20); PWGUI.ColorPicker(colorPickerRect, ref color, false); if (orderGroupWorldRect.Contains(e.mousePosition)) { graph.editorEvents.mouseOverOrderingGroup = this; graph.editorEvents.isMouseOverOrderingGroupFrame = true; } }