using UnityEngine;
/// <summary>
/// Texture2D 扩展方法
/// </summary>
public static class Texture2DExtension
{
// 克隆
public static Texture2D Clone(this Texture2D texture)
{
if (texture == null)
return null;
if (!texture.isReadable)
{
Debug.LogError("texture isReadable is false.");
return null;
}
int w = texture.width;
int h = texture.height;
Color[] colors = texture.GetPixels(0, 0, w, h);
Texture2D tex = new Texture2D(w, h, texture.format, false);
tex.SetPixels(0, 0, w, h, colors);
tex.Apply();
return tex;
}
/// <summary>
/// 绘制贴花
/// </summary>
/// <param name="texture">必须勾选上Read/Write</param>
/// <param name="uv">贴图的uv坐标</param>
/// <param name="decal">贴花图片</param>
/// <param name="scale">缩放系数</param>
public static void DrawDecal(this Texture2D texture, Vector2 uv, Texture2D decal, float scale=1.0f)
{
if (decal == null)
{
Debug.LogError("decal texture is null.");
return;
}
if (!decal.isReadable)
{
Debug.LogError("decal isReadable is false.");
return;
}
//限制下缩放区间
scale = Mathf.Clamp(scale, 0.001f, 100);
//计算贴花绘制区域
int w = texture.width;
int h = texture.height;
//缩放后的贴花宽高
int dw = (int)(decal.width * scale);
int dh = (int)(decal.height * scale);
//贴花图片的中心点对齐uv坐标
int x = (int)(w * uv.x) - dw / 2;
int y = (int)(h * uv.y) - dh / 2;
x = Mathf.Clamp(x, 0, w);
y = Mathf.Clamp(y, 0, h);
int ex = x + dw;
int ey = y + dh;
ex = Mathf.Clamp(ex, 0, w);
ey = Mathf.Clamp(ey, 0, h);
//绘制贴花
for (int dx=0 ; x < ex; x++, dx++)
{
for (int dy=0, j=y; j < ey; j++, dy++)
{
//采样坐标
int sx = (int)(dx / scale);
int sy = (int)(dy / scale);
Color dp = decal.GetPixel(sx, sy);
if (dp.a == 0)
continue;
texture.SetPixel(x, j, dp);
}
}
texture.Apply();
}
// 绘制贴花
public static void DrawDecal(this Texture2D texture, RaycastHit hit, Texture2D decal, float scale = 1.0f)
{
//模型需使用MeshCollider并且Convex设为false,否则textureCoord始终返回(0,0)
if (!(hit.collider is MeshCollider))
{
Debug.LogError("must use MeshCollider.");
return;
}
if ((hit.collider as MeshCollider).convex)
{
Debug.LogError("do not check 'convex'");
return;
}
Vector2 uv = hit.textureCoord;
DrawDecal(texture, uv, decal, scale);
}
}