Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 162 additions & 0 deletions MCPForUnity/Editor/Helpers/TextureOps.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
using System;
using System.Collections.Generic;
using System.IO;
using Newtonsoft.Json.Linq;
using UnityEngine;

namespace MCPForUnity.Editor.Helpers
{
public static class TextureOps
{
public static byte[] EncodeTexture(Texture2D texture, string assetPath)
{
if (texture == null)
return null;

string extension = Path.GetExtension(assetPath);
if (string.IsNullOrEmpty(extension))
{
McpLog.Warn($"[TextureOps] No file extension for '{assetPath}', defaulting to PNG.");
return texture.EncodeToPNG();
}

switch (extension.ToLowerInvariant())
{
case ".png":
return texture.EncodeToPNG();
case ".jpg":
case ".jpeg":
return texture.EncodeToJPG();
default:
McpLog.Warn($"[TextureOps] Unsupported extension '{extension}' for '{assetPath}', defaulting to PNG.");
return texture.EncodeToPNG();
}
}

public static void FillTexture(Texture2D texture, Color32 color)
{
if (texture == null)
return;

Color32[] pixels = new Color32[texture.width * texture.height];
for (int i = 0; i < pixels.Length; i++)
{
pixels[i] = color;
}
texture.SetPixels32(pixels);
}

public static Color32 ParseColor32(JArray colorArray)
{
if (colorArray == null || colorArray.Count < 3)
return new Color32(255, 255, 255, 255);

byte r = (byte)Mathf.Clamp(colorArray[0].ToObject<int>(), 0, 255);
byte g = (byte)Mathf.Clamp(colorArray[1].ToObject<int>(), 0, 255);
byte b = (byte)Mathf.Clamp(colorArray[2].ToObject<int>(), 0, 255);
byte a = colorArray.Count > 3 ? (byte)Mathf.Clamp(colorArray[3].ToObject<int>(), 0, 255) : (byte)255;

return new Color32(r, g, b, a);
}

public static List<Color32> ParsePalette(JArray paletteArray)
{
if (paletteArray == null)
return null;

List<Color32> palette = new List<Color32>();
foreach (var item in paletteArray)
{
if (item is JArray colorArray)
{
palette.Add(ParseColor32(colorArray));
}
}
Comment on lines +68 to +74
Copy link

Copilot AI Jan 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This foreach loop implicitly filters its target sequence - consider filtering the sequence explicitly using '.Where(...)'.

Copilot uses AI. Check for mistakes.
return palette.Count > 0 ? palette : null;
}

public static void ApplyPixelData(Texture2D texture, JToken pixelsToken, int width, int height)
{
ApplyPixelDataToRegion(texture, pixelsToken, 0, 0, width, height);
}

public static void ApplyPixelDataToRegion(Texture2D texture, JToken pixelsToken, int offsetX, int offsetY, int regionWidth, int regionHeight)
{
if (texture == null || pixelsToken == null)
return;

int textureWidth = texture.width;
int textureHeight = texture.height;

if (pixelsToken is JArray pixelArray)
{
int index = 0;
for (int y = 0; y < regionHeight && index < pixelArray.Count; y++)
{
for (int x = 0; x < regionWidth && index < pixelArray.Count; x++)
{
var pixelColor = pixelArray[index] as JArray;
if (pixelColor != null)
{
int px = offsetX + x;
int py = offsetY + y;
if (px >= 0 && px < textureWidth && py >= 0 && py < textureHeight)
{
texture.SetPixel(px, py, ParseColor32(pixelColor));
}
}
index++;
}
}

int expectedCount = regionWidth * regionHeight;
if (pixelArray.Count != expectedCount)
{
McpLog.Warn($"[TextureOps] Pixel array size mismatch: expected {expectedCount} entries, got {pixelArray.Count}");
}
}
else if (pixelsToken.Type == JTokenType.String)
{
string pixelString = pixelsToken.ToString();
string base64 = pixelString.StartsWith("base64:") ? pixelString.Substring(7) : pixelString;
if (!pixelString.StartsWith("base64:"))
{
McpLog.Warn("[TextureOps] Base64 pixel data missing 'base64:' prefix; attempting to decode.");
}

byte[] rawData = Convert.FromBase64String(base64);

// Assume RGBA32 format: 4 bytes per pixel
int expectedBytes = regionWidth * regionHeight * 4;
if (rawData.Length == expectedBytes)
{
int pixelIndex = 0;
for (int y = 0; y < regionHeight; y++)
{
for (int x = 0; x < regionWidth; x++)
{
int px = offsetX + x;
int py = offsetY + y;
if (px >= 0 && px < textureWidth && py >= 0 && py < textureHeight)
{
int byteIndex = pixelIndex * 4;
Color32 color = new Color32(
rawData[byteIndex],
rawData[byteIndex + 1],
rawData[byteIndex + 2],
rawData[byteIndex + 3]
);
texture.SetPixel(px, py, color);
}
pixelIndex++;
}
}
}
else
{
McpLog.Warn($"[TextureOps] Base64 data size mismatch: expected {expectedBytes} bytes, got {rawData.Length}");
}
}
}
}
}
11 changes: 11 additions & 0 deletions MCPForUnity/Editor/Helpers/TextureOps.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion MCPForUnity/Editor/Tools/ManageAsset.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ public static class ManageAsset

public static object HandleCommand(JObject @params)
{
string action = @params["action"]?.ToString().ToLower();
string action = @params["action"]?.ToString()?.ToLowerInvariant();
if (string.IsNullOrEmpty(action))
{
return new ErrorResponse("Action parameter is required.");
Expand Down
2 changes: 1 addition & 1 deletion MCPForUnity/Editor/Tools/ManageEditor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public static class ManageEditor
/// </summary>
public static object HandleCommand(JObject @params)
{
string action = @params["action"]?.ToString().ToLower();
string action = @params["action"]?.ToString()?.ToLowerInvariant();
// Parameters for specific actions
string tagName = @params["tagName"]?.ToString();
string layerName = @params["layerName"]?.ToString();
Expand Down
2 changes: 1 addition & 1 deletion MCPForUnity/Editor/Tools/ManageMaterial.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public static class ManageMaterial
{
public static object HandleCommand(JObject @params)
{
string action = @params["action"]?.ToString();
string action = @params["action"]?.ToString()?.ToLowerInvariant();
if (string.IsNullOrEmpty(action))
{
return new ErrorResponse("Action is required");
Expand Down
2 changes: 1 addition & 1 deletion MCPForUnity/Editor/Tools/ManageShader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public static class ManageShader
public static object HandleCommand(JObject @params)
{
// Extract parameters
string action = @params["action"]?.ToString().ToLower();
string action = @params["action"]?.ToString()?.ToLowerInvariant();
string name = @params["name"]?.ToString();
string path = @params["path"]?.ToString(); // Relative to Assets/
string contents = null;
Expand Down
Loading