150 lines
5.8 KiB
C#
150 lines
5.8 KiB
C#
|
|
#if UNITY_EDITROR
|
||
|
|
using System.Collections;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.IO;
|
||
|
|
using System.Linq;
|
||
|
|
using NaughtyAttributes;
|
||
|
|
using UnityEditor;
|
||
|
|
#endif
|
||
|
|
using UnityEngine;
|
||
|
|
|
||
|
|
public class SplitByUV : MonoBehaviour
|
||
|
|
{
|
||
|
|
#if UNITY_EDITROR
|
||
|
|
|
||
|
|
public Texture2D texture;
|
||
|
|
public float colorThreshold = 0.1f;
|
||
|
|
public Texture2D newTexture;
|
||
|
|
public float cellSize = 1f / 8f;
|
||
|
|
public int textureHeight = 64;
|
||
|
|
public int textureWidth = 8;
|
||
|
|
|
||
|
|
[Button("UVSave")]
|
||
|
|
public void SaveTextureAsPNG()
|
||
|
|
{
|
||
|
|
byte[] textureBytes = newTexture.EncodeToPNG();
|
||
|
|
string path = Path.Combine(Application.dataPath, "fileName");
|
||
|
|
if (File.Exists(path))
|
||
|
|
{
|
||
|
|
File.Delete(path);
|
||
|
|
}
|
||
|
|
File.WriteAllBytes(path, textureBytes);
|
||
|
|
Debug.Log("Texture saved to: " + path);
|
||
|
|
AssetDatabase.Refresh();
|
||
|
|
}
|
||
|
|
|
||
|
|
[Button("UVGenerate")]
|
||
|
|
public void CopyUVTexture()
|
||
|
|
{
|
||
|
|
MeshFilter meshRenderer = GetComponent<MeshFilter>();
|
||
|
|
if (meshRenderer == null || texture == null) { Debug.LogError("Missing SkinnedMeshRenderer or Texture2D!"); return; }
|
||
|
|
Mesh mesh = meshRenderer.sharedMesh;
|
||
|
|
Vector2[] uv = mesh.uv;
|
||
|
|
Color[] textureColors = texture.GetPixels();
|
||
|
|
int width = texture.width;
|
||
|
|
int height = texture.height;
|
||
|
|
|
||
|
|
Dictionary<Color, List<Vector2>> colorUVMap = new Dictionary<Color, List<Vector2>>();
|
||
|
|
for (int i = 0; i < uv.Length; i++)
|
||
|
|
{
|
||
|
|
int x = Mathf.Clamp((int)(uv[i].x * width), 0, width - 1);
|
||
|
|
int y = Mathf.Clamp((int)(uv[i].y * height), 0, height - 1);
|
||
|
|
Color pixelColor = textureColors[y * width + x];
|
||
|
|
bool found = false;
|
||
|
|
foreach (var key in colorUVMap.Keys)
|
||
|
|
{
|
||
|
|
if (Vector4.Distance(pixelColor, key) < colorThreshold)
|
||
|
|
{
|
||
|
|
colorUVMap[key].Add(uv[i]); found = true; break;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!found) colorUVMap[pixelColor] = new List<Vector2> { uv[i] };
|
||
|
|
}
|
||
|
|
|
||
|
|
List<int[]> colorHeightMap = new List<int[]>() { };
|
||
|
|
foreach (var kvp in colorUVMap)
|
||
|
|
{
|
||
|
|
Color color = kvp.Key;
|
||
|
|
List<Vector2> uvPoints = kvp.Value;
|
||
|
|
float minX = float.MaxValue, minY = float.MaxValue;
|
||
|
|
float maxX = float.MinValue, maxY = float.MinValue;
|
||
|
|
foreach (Vector2 uvCoord in uvPoints)
|
||
|
|
{
|
||
|
|
if (uvCoord.x < minX) minX = uvCoord.x;
|
||
|
|
if (uvCoord.y < minY) minY = uvCoord.y;
|
||
|
|
if (uvCoord.x > maxX) maxX = uvCoord.x;
|
||
|
|
if (uvCoord.y > maxY) maxY = uvCoord.y;
|
||
|
|
}
|
||
|
|
int minPixelX = Mathf.RoundToInt(minX * width);
|
||
|
|
int minPixelY = Mathf.RoundToInt(minY * height);
|
||
|
|
int maxPixelX = Mathf.RoundToInt(maxX * width);
|
||
|
|
int maxPixelY = Mathf.RoundToInt(maxY * height);
|
||
|
|
int boundH = maxPixelY - minPixelY;
|
||
|
|
int boundW = maxPixelX - minPixelX;
|
||
|
|
colorHeightMap.Add(new int[] {minPixelX, minPixelY, maxPixelX, maxPixelY,boundH, boundW });
|
||
|
|
Debug.Log($"Index:{minPixelX}:{minPixelY}-{maxPixelX}:{maxPixelY}..{boundH}:{boundW}");
|
||
|
|
}
|
||
|
|
var colors = colorUVMap.Keys.ToList();
|
||
|
|
var points = colorUVMap.Values.ToList();
|
||
|
|
int indexation = 0;
|
||
|
|
int colorize = 0;
|
||
|
|
|
||
|
|
RenderTexture rt = RenderTexture.GetTemporary(textureWidth*colors.Count, textureHeight, 0);
|
||
|
|
RenderTexture.active = rt;
|
||
|
|
Texture2D textureN = new Texture2D(textureWidth*colors.Count, textureHeight, TextureFormat.RGBA32, false);
|
||
|
|
textureN.ReadPixels(new Rect(0, 0, textureWidth*colors.Count, textureHeight), 0, 0);
|
||
|
|
textureN.Apply();
|
||
|
|
RenderTexture.active = null;
|
||
|
|
RenderTexture.ReleaseTemporary(rt);
|
||
|
|
newTexture = textureN;
|
||
|
|
Dictionary<Color,Vector2> forNewUV = new Dictionary<Color,Vector2>();
|
||
|
|
foreach (var color in colors)
|
||
|
|
{
|
||
|
|
for (int x = 0 + colorize*textureWidth; x < textureWidth + colorize*textureWidth; x++)
|
||
|
|
{
|
||
|
|
for (int y = 0; y < textureHeight; y++)
|
||
|
|
{
|
||
|
|
newTexture.SetPixel(x,y,new Color(color.r, color.g, color.b, color.a));
|
||
|
|
if (!forNewUV.ContainsKey(color))
|
||
|
|
forNewUV.Add(color, new Vector2((float)x/width,(float)y/height ));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
colorize++;
|
||
|
|
}
|
||
|
|
foreach (var colorMap in colorHeightMap)
|
||
|
|
{
|
||
|
|
var pointForIndex = points[indexation];
|
||
|
|
foreach (var listOffer in pointForIndex)
|
||
|
|
{
|
||
|
|
var mz = Mathf.RoundToInt(listOffer.x * width) - colorMap[0];
|
||
|
|
var kz = Mathf.RoundToInt(listOffer.y * height) - colorMap[1];
|
||
|
|
var hn2 = 0;
|
||
|
|
var hn1 = 0;
|
||
|
|
if (colorMap[4] != 0) hn2 = Mathf.RoundToInt((kz / colorMap[4])*textureHeight);
|
||
|
|
if (colorMap[5] != 0) hn1 = Mathf.RoundToInt((mz / colorMap[5])*textureWidth);
|
||
|
|
var y = hn2 + indexation*textureHeight;
|
||
|
|
var x = hn1 + indexation*textureWidth;
|
||
|
|
Debug.Log($"{x}:{y}:{colors[indexation]}");
|
||
|
|
|
||
|
|
}
|
||
|
|
indexation++;
|
||
|
|
}
|
||
|
|
newTexture.Apply(); //forNewUV.Values.ToArray();
|
||
|
|
var listNewUV = new List<Vector2>();
|
||
|
|
foreach (var bound in mesh.uv)
|
||
|
|
{
|
||
|
|
int x = Mathf.Clamp((int)(bound.x * width), 0, width - 1);
|
||
|
|
int y = Mathf.Clamp((int)(bound.y * height), 0, height - 1);
|
||
|
|
Color pixelColor = textureColors[y * width + x];
|
||
|
|
foreach (var key in forNewUV.Keys)
|
||
|
|
{
|
||
|
|
if (Vector4.Distance(pixelColor, key) < colorThreshold)
|
||
|
|
{listNewUV.Add(forNewUV[key]); break;}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
Debug.Log($"{listNewUV.Count} , { mesh.uv.Length}");
|
||
|
|
mesh.uv = listNewUV.ToArray();
|
||
|
|
}
|
||
|
|
#endif
|
||
|
|
}
|