public void Apply() { if (paintLayer == null) { paintLayer = layerStack.GetMergedLayer(); } foreach (var pd in paintLayer.paintData) { var vpd = pd.vpaintObject; if (!vpd) { continue; } vpd.SetColors(pd.colors); } }
void PaintObject(VPaintObject vc, VPaintLayer layer, VPaintVertexData data) { if (vc.colorsBuilder == null) { vc.colorsBuilder = new Color[data.colors.Length]; } if (vc.transparencyBuilder == null) { vc.transparencyBuilder = new float[data.colors.Length]; } VPaintUtility.MergeColors( vc.colorsBuilder, vc.transparencyBuilder, data.colors, data.transparency, layer.blendMode, layer.opacity, layer.maskR, layer.maskG, layer.maskB, layer.maskA ); }
void LoadLayer(VPaintLayer layer, List <VPaintObject> affectedColorers) { foreach (var vc in colorers) { if (!vc) { continue; } var paintData = layer.Get(vc); if (paintData != null) { PaintObject(vc, layer, paintData); if (!affectedColorers.Contains(vc)) { affectedColorers.Add(vc); } } } }
void Awake() { if (!Application.isPlaying) { #if UNITY_EDITOR UnityEditor.EditorApplication.delayCall += () => { if (autoLoadInEditor) { Apply(); } }; #endif } else { paintLayer = layerStack.GetMergedLayer(); if (autoApplySchedule == AutoApplySchedule.OnAwake) { Apply(); } } }
void CenterPanel() { GUI.enabled = selectedObjects.Count == 1; if (GUILayout.Button("< Copy")) { VPaintLayer layer = null; if (copyLayer == 0) { layer = currentLayer; } if (copyLayer == 1) { layer = currentLayerStack.GetMergedLayer(); } int selectedObj = -1; foreach (var so in selectedObjects) { selectedObj = so; } var obj = VPaint.Instance.objectInfo[selectedObj].vpaintObject; var pd = layer.Get(obj); if (pd == null) { Debug.LogError("Could not copy VPaint object, it has no paint data!"); } else { AddToClipboard(pd.colors, pd.transparency, obj.name); } } GUI.enabled = true; GUILayout.Space(20); GUI.enabled = selectedObjects.Count != 0 && selectedClipboardItem != -1; if (GUI.enabled) { var clipData = clipboard[selectedClipboardItem]; foreach (var so in selectedObjects) { var obj = VPaint.Instance.objectInfo[so].vpaintObject; GUI.enabled &= obj.GetMeshInstance().vertices.Length == clipData.colors.Length; } } if (GUILayout.Button("Paste >")) { VPaint.Instance.PushUndo("Paste Colors"); var clipData = clipboard[selectedClipboardItem]; if (pasteLayer == 0) { foreach (var so in selectedObjects) { var obj = VPaint.Instance.objectInfo[so].vpaintObject; var pd = currentLayer.GetOrCreate(obj); pd.colors = clipData.colors; pd.transparency = clipData.transparency; } } if (pasteLayer == 1) { var layer = new VPaintLayer(); foreach (var so in selectedObjects) { var obj = VPaint.Instance.objectInfo[so].vpaintObject; layer.paintData.Add( new VPaintVertexData() { colorer = obj, colors = clipData.colors, transparency = clipData.transparency } ); } currentLayerStack.layers.Add(layer); } VPaint.Instance.ReloadLayers(); } GUI.enabled = true; }
public void ImportTexture(bool preview) { try { var objectSizes = new Dictionary <VPaintObject, float>(); float objectMax = 0f; foreach (VPaintObject vc in VPaint.Instance.maskedVPaintObjects()) { if (!vc) { continue; } Bounds b = vc.GetMeshInstance().bounds; float size = (b.max - b.min).magnitude; objectMax = Mathf.Max(objectMax, size); objectSizes.Add(vc, size); } bool overwriteExistingLayer = Settings.targetLayer == 1; VPaintLayer layer = overwriteExistingLayer ? currentLayer.Clone() : new VPaintLayer(); List <VPaintVertexData> paintData = new List <VPaintVertexData>(); foreach (var vc in VPaint.Instance.maskedVPaintObjects()) { if (!vc) { continue; } if (!IsValid(vc)) { continue; } Texture2D tx = GetTexture(vc); string texPath = AssetDatabase.GetAssetPath(tx); TextureImporter importer = TextureImporter.GetAtPath(texPath) as TextureImporter; if (!importer.isReadable) { importer.isReadable = true; AssetDatabase.ImportAsset(texPath, ImportAssetOptions.ForceUpdate); } VPaintVertexData pd = new VPaintVertexData(); Mesh m = vc.GetMeshInstance(); Vector2[] uvs = GetUVs(m); pd.colors = new Color[uvs.Length]; pd.transparency = new float[uvs.Length]; Vector2 txSize = new Vector2(tx.width, tx.height); Func <Vector2, Vector2> uvTransformation = GetUVTransformation(vc); for (int i = 0; i < pd.colors.Length; i++) { if (EditorUtility.DisplayCancelableProgressBar("Sampling...", "Sampling texture onto '" + vc.name + "'", (float)i / pd.colors.Length)) { EditorUtility.ClearProgressBar(); return; } Vector2 uv = uvs[i]; Vector2 normalizedPos = uvTransformation(uv); Vector2 pixelPos = Vector2.Scale(normalizedPos, txSize); var samplePositions = new List <Vector2>(); int sampleRadius = Settings.sampleRadius; sampleRadius = Mathf.RoundToInt(sampleRadius * Mathf.Clamp01(objectSizes[vc] / objectMax)); if (sampleRadius == 0) { samplePositions.Add(pixelPos); } else { for (int r = -sampleRadius; r <= sampleRadius; r++) { float f = Mathf.Cos((((r / sampleRadius) + 1) / 2) * Mathf.PI); int div = Mathf.RoundToInt(f * sampleRadius); for (int y = -div; y <= div; y++) { samplePositions.Add(pixelPos + new Vector2(r, y)); } } } float cr = 0; float cg = 0; float cb = 0; float ca = 0; foreach (Vector2 v in samplePositions) { Color c = tx.GetPixelBilinear((int)v.x / txSize.x, (int)v.y / txSize.y); cr += c.r; cg += c.g; cb += c.b; ca += c.a; } int count = samplePositions.Count; cr /= count; cg /= count; cb /= count; ca /= count; Color col = new Color(); if (Settings.swizzleR != -1) { col[Settings.swizzleR] = cr; } if (Settings.swizzleG != -1) { col[Settings.swizzleG] = cg; } if (Settings.swizzleB != -1) { col[Settings.swizzleB] = cb; } if (Settings.swizzleA != -1) { col[Settings.swizzleA] = ca; } col = PostProcessColor(col); pd.colors[i] = col; pd.transparency[i] = Settings.importOpacity; } pd.vpaintObject = vc; paintData.Add(pd); } if (paintData.Count != 0) { layer.paintData = paintData; } if (Settings.blurRadius != 0) { var colorsToApply = new Dictionary <VPaintVertexData, Color[]>(); foreach (var vc in VPaint.Instance.maskedVPaintObjects()) { var vcrenderer = vc.GetComponent <Renderer>(); if (!vcrenderer) { continue; } var data = layer.Get(vc); if (data == null) { continue; } var colors = new Color[data.colors.Length]; var verts = vc.GetMeshInstance().vertices; var checkBounds = vcrenderer.bounds; checkBounds.Expand(Settings.blurRadius); var checkColorers = new List <VPaintVertexData>(); foreach (var vc2 in VPaint.Instance.maskedVPaintObjects()) { var vc2renderer = vc2.GetComponent <Renderer>(); if (!vc2renderer) { continue; } var b = vc2renderer.bounds; b.Expand(Settings.blurRadius); if (!checkBounds.Intersects(b)) { continue; } var data2 = layer.Get(vc2); if (data2 == null) { continue; } checkColorers.Add(data2); } for (int i = 0; i < colors.Length; i++) { EditorUtility.DisplayProgressBar("Blurring...", "Blurring imported colors on '" + vc.name + "'", (float)i / colors.Length); var color = data.colors[i]; var colorV4 = new Vector4(color.r, color.g, color.b, color.a); Vector4 composite = colorV4; float factor = 1f; var v = verts[i]; foreach (var data2 in checkColorers) { // var vc2 = data2.colorer; // var verts2 = vc2.GetMeshInstance().vertices; var vp = data2.vpaintObject as VPaintObject; if (!vp) { continue; } var verts2 = vp.GetVertices(); var colors2 = data2.colors; for (int d = 0; d < colors2.Length; d++) { var v2 = verts2[d]; var dist = Vector3.Distance(v, v2); if (Settings.blurRadius < dist) { continue; } float fac = 1 - dist / Settings.blurRadius; var col = colors2[d]; var colV4 = new Vector4(col.r, col.g, col.b, col.a); float dot = Vector4.Dot(colorV4, colV4); fac *= 1 - Mathf.Clamp01(Settings.blurThreshhold / dot); composite += colV4 * fac; factor += fac; } } colors[i] = (Color)(composite / factor); } colorsToApply.Add(data, colors); } foreach (var kvp in colorsToApply) { kvp.Key.colors = kvp.Value; } } VPaint.Instance.PushUndo("Import Texture"); layer.blendMode = VPaintBlendMode.Opaque; if (preview) { VPaint.Instance.LoadLayer(layer); } else { if (overwriteExistingLayer) { VPaint.Instance.layerStack.layers[VPaint.Instance._currentPaintLayer] = layer; } else { VPaint.Instance.layerStack.layers.Add(layer); } VPaint.Instance.ReloadLayers(); } } finally { EditorUtility.ClearProgressBar(); } }