void Paint(RaycastHit hit) { int texIndex = m_SelectedTex; float hardness = m_Hardness; int passIndex = m_SelectedPass; float brushSize = m_BrushSize; USubMesh sm = subMesh; UPass pass = sm[passIndex]; int texW = pass.mixTex.width; int texH = pass.mixTex.height; int centerX = Mathf.FloorToInt(hit.textureCoord.x * texW); int centerY = Mathf.FloorToInt(hit.textureCoord.y * texH); Vector2 bounds = UEditorTools.GetSizeOfMesh(sm.mesh, m_Editor.terrain.transform); int pixelSize = 0; if (texW > texH) { pixelSize = (int)((brushSize / bounds.x) * texW); } else { pixelSize = (int)((brushSize / bounds.y) * texH); } int x = Mathf.Clamp(centerX - pixelSize, 0, texW - 1); int y = Mathf.Clamp(centerY - pixelSize, 0, texH - 1); int width = Mathf.Clamp(2 * pixelSize, 0, texW - x); int height = Mathf.Clamp(2 * pixelSize, 0, texH - y); List <Color[]> srcPixels = new List <Color[]>(); sm.passes.ToList().ForEach(p => srcPixels.Add(p.mixTex.GetPixels(x, y, width, height, 0))); for (int i = 0, max = srcPixels.Count; i < max; i++) { Color[] pixels = srcPixels[i]; for (int h = 0; h < height; h++) { for (int w = 0; w < width; w++) { Color targetColor; if (i == passIndex) { targetColor = GetColor(texIndex); } else { targetColor = Color.clear; } int ix = (int)(w * 64 / width); int iy = (int)(h * 64 / height); int index = (h * width) + w; float blendFactor = m_Brush.GetStrengthInt(ix, iy) * hardness * 0.1f; pixels[index] = Color.Lerp(pixels[index], targetColor, blendFactor); } } sm[i].Paint(x, y, width, height, pixels); } }
UPass PassField(Rect rect, UPass pass, int index) { Event e = Event.current; bool selected = index == m_SelectedPass; if (e.type == EventType.mouseDown && rect.Contains(e.mousePosition)) { m_SelectedPass = index; m_SelectedTex = -1; } Color bgColor = GUI.backgroundColor; GUI.color = new Color(0.5f, 0.8f, 0.5f, 0.5f); Rect newRect = new Rect(rect); newRect.x += 2; newRect.y += 2; newRect.width -= 4; newRect.height -= 4; GUIStyle style = new GUIStyle("ServerUpdateChangesetOn"); if (selected && Event.current.type == EventType.repaint) { style.Draw(newRect, false, false, false, false); } GUI.color = bgColor; GUI.BeginGroup(rect); newRect = new Rect(4, 4, 0, rect.height - 9); newRect.width = 30; style = new GUIStyle("OL Box"); style.normal.textColor = new Color(0.7f, 0.7f, 0.7f); style.fontStyle = FontStyle.Bold; style.fontSize = 14; style.alignment = TextAnchor.MiddleCenter; bgColor = GUI.backgroundColor; GUI.backgroundColor = new Color(1, 1, 1, 0.8f); if (GUI.Button(newRect, index.ToString(), style)) { m_SelectedPass = index; m_SelectedTex = -1; } GUI.backgroundColor = bgColor; newRect.x += newRect.width; GUIStyle btnStyle = new GUIStyle("OL Box"); btnStyle.alignment = TextAnchor.MiddleCenter; btnStyle.onNormal = (new GUIStyle("PR Ping")).active; btnStyle.border = new RectOffset(7, 7, 7, 7); btnStyle.padding = new RectOffset(5, 5, 5, 5); newRect.width = 0; for (int i = 0, max = pass.textures.Length; i < max; i++) { if (pass.textures[i].mainTex == null) { continue; } newRect.x += newRect.width + 4; newRect.width = rect.height; if (selected) { if (GUI.Toggle(newRect, i == m_SelectedTex, pass.textures[i].mainTex, btnStyle)) { m_SelectedTex = i; m_Editor.Repaint(); } } else { GUI.Toggle(newRect, false, pass.textures[i].mainTex, btnStyle); } } newRect.x += newRect.width; newRect.width = rect.width - newRect.x; newRect.height = rect.height; if (GUI.Button(newRect, "", GUIStyle.none)) { m_SelectedPass = index; m_SelectedTex = -1; } GUI.EndGroup(); return(pass); }
void PassesField() { GUILayout.Label("Passes", EditorStyles.boldLabel); List <Rect> passRect = new List <Rect>(); GUILayout.BeginVertical("OL Box"); GUILayout.Space(4); if (subMesh.passes.Length > 0) { for (int i = 0, max = subMesh.passes.Length; i < max; i++) { GUILayout.Box("", EditorStyles.textField, GUILayout.Height(50), GUILayout.MinWidth(235)); passRect.Add(GUILayoutUtility.GetLastRect()); } } else { GUILayout.Label("No Pass Added."); GUILayout.Space(15); } GUILayout.Space(2); GUILayout.EndVertical(); for (int i = 0; i < passRect.Count; i++) { subMesh[i] = PassField(passRect[i], subMesh[i], i); } GUILayout.Space(2); EditorGUILayout.BeginHorizontal(); EditorGUILayout.Space(); if (GUILayout.Button("Edit Passes...", EditorStyles.popup, GUILayout.Width(90))) { GenericMenu menu = new GenericMenu(); if (subMesh.passes.Length > 3) { menu.AddDisabledItem(new GUIContent("Add Pass")); m_Editor.Repaint(); } else { menu.AddItem(new GUIContent("Add Pass"), false, () => { UTextureWizard wizard = UTextureWizard.GetWizard("Add Pass", "Add", m_Editor); wizard.subMeshIndex = m_SelectedSM; int width = 0, height = 0; GetTexSize(ref width, ref height); UPass pass = null; if (subMesh.passes.Length == 0) { pass = new UPass(true, GetClearMix(subMesh.passes.Length)); } else { pass = new UPass(false, GetClearMix(subMesh.passes.Length)); } wizard.pass = pass; }); } if (subMesh.passes.Length == 0) { menu.AddDisabledItem(new GUIContent("Edit Pass")); m_Editor.Repaint(); } else { menu.AddItem(new GUIContent("Edit Pass"), false, () => { UTextureWizard wizard = UTextureWizard.GetWizard("Edit Pass", "Apply", m_Editor); wizard.pass = new UPass(pass); wizard.subMeshIndex = m_SelectedSM; wizard.passIndex = m_SelectedPass; m_Editor.Repaint(); }); } if (m_SelectedPass == 0) { menu.AddDisabledItem(new GUIContent("Remove Pass")); } else { menu.AddItem(new GUIContent("Remove Pass"), false, () => { m_Editor.terrain.data.textureData.subMeshes[m_SelectedSM].RemoveAt(m_SelectedPass); m_SelectedPass = 0; m_Editor.Repaint(); }); } menu.ShowAsContext(); Event.current.Use(); } EditorGUILayout.EndHorizontal(); }