mirror of
https://github.com/maxartz15/MA_TextureAtlasser.git
synced 2024-11-24 14:45:38 +01:00
Merge pull request #1 from goto01/master
Adding the scaling and export options. Merging the changes made. Sub-meshes export bug-fix. Export window changes. New texture scaling function. (TODO: some old code cleanup.)
This commit is contained in:
commit
26a0f68454
@ -53,7 +53,10 @@ namespace MA_TextureAtlasserPro
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.Label(this.name);
|
||||
var tempColor = GUI.backgroundColor;
|
||||
GUI.backgroundColor = Color.white;
|
||||
GUILayout.Label(this.name, GUI.skin.box);
|
||||
GUI.backgroundColor = tempColor;
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
|
@ -315,6 +315,25 @@ namespace MA_TextureAtlasserPro
|
||||
}
|
||||
}
|
||||
|
||||
public static void ModifyMeshes(MA_TextureAtlasserProAtlas atlas)
|
||||
{
|
||||
if (atlas == null || atlas.textureQuads == null) return;
|
||||
var quads = atlas.textureQuads;
|
||||
for (var index = 0; index < quads.Count; index++)
|
||||
{
|
||||
var quad = quads[index];
|
||||
if (quad.meshes == null) continue;
|
||||
var meshes = quad.meshes;
|
||||
for (var meshIndex = 0; meshIndex < quad.meshes.Count; meshIndex++)
|
||||
{
|
||||
if (meshes[meshIndex] == null) continue;
|
||||
MA_MeshUtils.MA_UVReMap(meshes[meshIndex], atlas.textureAtlasSize, quad.guiRect);
|
||||
EditorUtility.SetDirty(meshes[meshIndex]);
|
||||
}
|
||||
}
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
|
||||
// public static void ExportAtlasTexturePNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
|
||||
// {
|
||||
// if(atlas != null && atlas.textureQuads != null)
|
||||
@ -363,7 +382,7 @@ namespace MA_TextureAtlasserPro
|
||||
//Create new texture part
|
||||
Texture2D newTexturePart = (Texture2D)MA_Texture.MA_TextureUtils.ConvertToReadableTexture(q.textureGroups[i].texture);
|
||||
//Scale it
|
||||
newTexturePart = newTexturePart.MA_Scale32D((int)q.guiRect.width, (int)q.guiRect.height);
|
||||
newTexturePart = newTexturePart.ScaleTexture((int)q.guiRect.width, (int)q.guiRect.height, true);
|
||||
//Add it
|
||||
newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y);
|
||||
}
|
||||
|
@ -9,6 +9,16 @@ namespace MA_TextureAtlasserPro
|
||||
{
|
||||
public class MA_TextureAtlasserProExportWindow : EditorWindow
|
||||
{
|
||||
private const int WindowHeight = 215;
|
||||
|
||||
private enum ExportMode
|
||||
{
|
||||
None,
|
||||
D3,
|
||||
D2,
|
||||
Meshes,
|
||||
}
|
||||
|
||||
//Editor
|
||||
private static MA_TextureAtlasserProExportWindow thisWindow;
|
||||
public static MA_TextureAtlasserProWindow curWindow;
|
||||
@ -16,7 +26,11 @@ namespace MA_TextureAtlasserPro
|
||||
//Data
|
||||
private static bool isLoaded = false; //Make sure we wait a frame at the start to setup and don't draw.
|
||||
|
||||
private ExportMode _selectedExportMode;
|
||||
private bool _showAdvancedEditor;
|
||||
|
||||
private bool exportObjDefault = false;
|
||||
private bool _replaceMeshes = false;
|
||||
private bool exportPngDefault = false;
|
||||
private bool exportSprite = false;
|
||||
private bool exportSliceSprite = false;
|
||||
@ -26,8 +40,8 @@ namespace MA_TextureAtlasserPro
|
||||
{
|
||||
GetCurrentWindow();
|
||||
|
||||
thisWindow.minSize = new Vector2(420, 200);
|
||||
thisWindow.maxSize = new Vector2(420, 200);
|
||||
thisWindow.minSize = new Vector2(420, WindowHeight);
|
||||
thisWindow.maxSize = new Vector2(420, WindowHeight);
|
||||
|
||||
thisWindow.titleContent.text = "MA_ExportTextureAtlas";
|
||||
|
||||
@ -40,8 +54,8 @@ namespace MA_TextureAtlasserPro
|
||||
|
||||
GetCurrentWindow();
|
||||
|
||||
thisWindow.minSize = new Vector2(420, 200);
|
||||
thisWindow.maxSize = new Vector2(420, 200);
|
||||
thisWindow.minSize = new Vector2(420, WindowHeight);
|
||||
thisWindow.maxSize = new Vector2(420, WindowHeight);
|
||||
|
||||
thisWindow.titleContent.text = "MA_ExportTextureAtlas";
|
||||
|
||||
@ -101,45 +115,13 @@ namespace MA_TextureAtlasserPro
|
||||
{
|
||||
//Export
|
||||
GUILayout.BeginVertical();
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
|
||||
if (GUILayout.Button("3D", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
exportObjDefault = true;
|
||||
exportPngDefault = true;
|
||||
exportSprite = false;
|
||||
exportSliceSprite = false;
|
||||
}
|
||||
|
||||
if (GUILayout.Button("2D", GUILayout.ExpandWidth(false)))
|
||||
{
|
||||
exportObjDefault = false;
|
||||
exportPngDefault = true;
|
||||
exportSprite = true;
|
||||
exportSliceSprite = true;
|
||||
}
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Label("Meshes:");
|
||||
exportObjDefault = GUILayout.Toggle(exportObjDefault, "OBJ default.");
|
||||
|
||||
GUILayout.Label("Textures:");
|
||||
GUILayout.BeginHorizontal();
|
||||
exportPngDefault = GUILayout.Toggle(exportPngDefault, "PNG default.");
|
||||
if(exportPngDefault)
|
||||
{
|
||||
exportSprite = GUILayout.Toggle(exportSprite, "Sprite.");
|
||||
if (exportSprite)
|
||||
{
|
||||
exportSliceSprite = GUILayout.Toggle(exportSliceSprite, "Slice sprites.");
|
||||
}
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
DrawExportModeEditor();
|
||||
DrawAdvancedEditor();
|
||||
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
|
||||
GUI.enabled = _selectedExportMode != ExportMode.None;
|
||||
if (GUILayout.Button("Export", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
|
||||
{
|
||||
if(exportObjDefault)
|
||||
@ -147,6 +129,9 @@ namespace MA_TextureAtlasserPro
|
||||
MA_TextureAtlasserProUtils.ExportAtlasMeshesObj(curWindow.textureAtlas);
|
||||
}
|
||||
|
||||
if (_replaceMeshes)
|
||||
MA_TextureAtlasserProUtils.ModifyMeshes(curWindow.textureAtlas);
|
||||
|
||||
if(exportPngDefault)
|
||||
{
|
||||
if(exportSprite)
|
||||
@ -160,6 +145,8 @@ namespace MA_TextureAtlasserPro
|
||||
}
|
||||
}
|
||||
|
||||
GUI.enabled = true;
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
}
|
||||
@ -187,6 +174,79 @@ namespace MA_TextureAtlasserPro
|
||||
if(e.type == EventType.Repaint)
|
||||
isLoaded = true;
|
||||
}
|
||||
|
||||
private void DrawExportModeEditor()
|
||||
{
|
||||
GUILayout.BeginHorizontal(EditorStyles.helpBox);
|
||||
GUILayout.FlexibleSpace();
|
||||
var value = GUILayout.Toggle(_selectedExportMode == ExportMode.D3, "3D", EditorStyles.miniButtonLeft,
|
||||
GUILayout.ExpandWidth(false));
|
||||
if (value && _selectedExportMode != ExportMode.D3)
|
||||
{
|
||||
_selectedExportMode = ExportMode.D3;
|
||||
exportObjDefault = true;
|
||||
_replaceMeshes = false;
|
||||
exportPngDefault = true;
|
||||
exportSprite = false;
|
||||
exportSliceSprite = false;
|
||||
}
|
||||
value = GUILayout.Toggle(_selectedExportMode == ExportMode.D2, "2D", EditorStyles.miniButtonMid,
|
||||
GUILayout.ExpandWidth(false));
|
||||
if (value && _selectedExportMode != ExportMode.D2)
|
||||
{
|
||||
_selectedExportMode = ExportMode.D2;
|
||||
exportObjDefault = false;
|
||||
_replaceMeshes = false;
|
||||
exportPngDefault = true;
|
||||
exportSprite = true;
|
||||
exportSliceSprite = true;
|
||||
}
|
||||
value = GUILayout.Toggle(_selectedExportMode == ExportMode.Meshes, "Replace source meshes", EditorStyles.miniButtonRight,
|
||||
GUILayout.ExpandWidth(false));
|
||||
if (value && _selectedExportMode != ExportMode.Meshes)
|
||||
{
|
||||
_selectedExportMode = ExportMode.Meshes;
|
||||
exportObjDefault = false;
|
||||
_replaceMeshes = true;
|
||||
exportPngDefault = true;
|
||||
exportSprite = false;
|
||||
exportSliceSprite = false;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void DrawAdvancedEditor()
|
||||
{
|
||||
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
|
||||
_showAdvancedEditor = EditorGUILayout.Foldout(_showAdvancedEditor, "Advanced editor");
|
||||
if (!_showAdvancedEditor)
|
||||
{
|
||||
EditorGUILayout.EndVertical();
|
||||
return;
|
||||
}
|
||||
|
||||
GUILayout.Label("Meshes:", EditorStyles.miniBoldLabel);
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
exportObjDefault = GUILayout.Toggle(exportObjDefault, "OBJ default.");
|
||||
_replaceMeshes = GUILayout.Toggle(_replaceMeshes, "Replace meshes");
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
GUILayout.Label("Textures:", EditorStyles.miniBoldLabel);
|
||||
GUILayout.BeginHorizontal();
|
||||
exportPngDefault = GUILayout.Toggle(exportPngDefault, "PNG default.");
|
||||
if(exportPngDefault)
|
||||
{
|
||||
exportSprite = GUILayout.Toggle(exportSprite, "Sprite.");
|
||||
if (exportSprite)
|
||||
{
|
||||
exportSliceSprite = GUILayout.Toggle(exportSliceSprite, "Slice sprites.");
|
||||
}
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.EndHorizontal();
|
||||
EditorGUILayout.EndVertical();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -9,6 +9,7 @@ using System.IO;
|
||||
using System.Text;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
|
||||
@ -39,12 +40,16 @@ namespace MA_Mesh
|
||||
public static Mesh MA_DuplicateMesh(Mesh mesh)
|
||||
{
|
||||
Mesh newMesh = new Mesh();
|
||||
|
||||
newMesh.name = mesh.name;
|
||||
newMesh.SetVertices(new List<Vector3>(mesh.vertices));
|
||||
newMesh.bounds = mesh.bounds;
|
||||
newMesh.colors = mesh.colors.ToArray();
|
||||
newMesh.subMeshCount = mesh.subMeshCount;
|
||||
for (int i = 0; i < mesh.subMeshCount; i++)
|
||||
{
|
||||
newMesh.SetTriangles(mesh.GetTriangles(i), i);
|
||||
}
|
||||
newMesh.subMeshCount = mesh.subMeshCount;
|
||||
newMesh.SetNormals(new List<Vector3>(mesh.normals));
|
||||
newMesh.SetUVs(0, new List<Vector2>(mesh.uv));
|
||||
newMesh.SetTangents(new List<Vector4>(mesh.tangents));
|
||||
@ -92,14 +97,14 @@ namespace MA_Mesh
|
||||
{
|
||||
if(flipY)
|
||||
{
|
||||
//Debug.Log("01" + uvs[i].x);
|
||||
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x), (uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)));
|
||||
//Debug.Log("02" + uvs[i].x);
|
||||
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x),
|
||||
(uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * (atlasSize.y - textureRect.height - textureRect.y)));
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.Log("01" + uvs[i].x);
|
||||
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x), (uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * textureRect.y));
|
||||
uvs[i] = new Vector2((uvs[i].x / atlasSize.x * textureRect.width) + (1 / atlasSize.x * textureRect.x),
|
||||
(uvs[i].y / atlasSize.y * textureRect.height) + (1 / atlasSize.y * textureRect.y));
|
||||
//Debug.Log("02" + uvs[i].x);
|
||||
}
|
||||
}
|
||||
@ -176,7 +181,6 @@ namespace MA_Mesh
|
||||
using (StreamWriter sw = new StreamWriter(savePath + filename + ".obj"))
|
||||
{
|
||||
sw.Write(MeshToString(mesh));
|
||||
Debug.Log(savePath + filename);
|
||||
}
|
||||
}
|
||||
//End
|
||||
|
@ -44,6 +44,7 @@ namespace MA_Texture
|
||||
// Copy the pixels from the RenderTexture to the new Texture
|
||||
myTexture2D.ReadPixels(new Rect(0, 0, tmp.width, tmp.height), 0, 0);
|
||||
myTexture2D.Apply();
|
||||
myTexture2D.name = texture.name;
|
||||
|
||||
// Reset the active RenderTexture
|
||||
RenderTexture.active = previous;
|
||||
@ -174,11 +175,18 @@ namespace MA_Texture
|
||||
}
|
||||
}
|
||||
|
||||
newTexture.name = texture.name;
|
||||
newTexture.name = texture.name;
|
||||
|
||||
newTexture.Apply();
|
||||
return newTexture;
|
||||
}
|
||||
|
||||
public static Texture2D ScaleTexture(this Texture2D texture, int width, int height, bool bilinear)
|
||||
{
|
||||
TextureScaler.Scale(texture, width, height, bilinear);
|
||||
return texture;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region combine
|
||||
@ -191,7 +199,7 @@ namespace MA_Texture
|
||||
//Y is 'flipped' because textures are made from left to right, bottom to top. We want to draw from left to right and top to bottom.
|
||||
for (int y = combineTexture.height; y > 0; y--)
|
||||
{
|
||||
texture.SetPixel(x + offsetX, texture.height - y - offsetY, combineTexture.GetPixel(x, texture.height - y));
|
||||
texture.SetPixel(x + offsetX, y + (texture.height - offsetY - combineTexture.height), combineTexture.GetPixel(x, y));
|
||||
}
|
||||
}
|
||||
else
|
||||
|
103
MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs
Normal file
103
MA_ToolBox/MA_Utilities/TextureUtils/TextureScaler.cs
Normal file
@ -0,0 +1,103 @@
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MA_Texture
|
||||
{
|
||||
public static class TextureScaler
|
||||
{
|
||||
public class ThreadData
|
||||
{
|
||||
public int start;
|
||||
public int end;
|
||||
public ThreadData (int s, int e) {
|
||||
start = s;
|
||||
end = e;
|
||||
}
|
||||
}
|
||||
|
||||
private static Color[] texColors;
|
||||
private static Color[] newColors;
|
||||
private static int w;
|
||||
private static float ratioX;
|
||||
private static float ratioY;
|
||||
private static int w2;
|
||||
private static int finishCount;
|
||||
|
||||
public static void Scale (Texture2D tex, int newWidth, int newHeight, bool useBilinear)
|
||||
{
|
||||
texColors = tex.GetPixels();
|
||||
newColors = new Color[newWidth * newHeight];
|
||||
if (useBilinear)
|
||||
{
|
||||
ratioX = 1.0f / ((float)newWidth / (tex.width-1));
|
||||
ratioY = 1.0f / ((float)newHeight / (tex.height-1));
|
||||
}
|
||||
else {
|
||||
ratioX = ((float)tex.width) / newWidth;
|
||||
ratioY = ((float)tex.height) / newHeight;
|
||||
}
|
||||
w = tex.width;
|
||||
w2 = newWidth;
|
||||
finishCount = 0;
|
||||
if (useBilinear)
|
||||
{
|
||||
BilinearScale(0, newHeight);
|
||||
}
|
||||
else
|
||||
{
|
||||
PointScale(0, newHeight);
|
||||
}
|
||||
|
||||
|
||||
tex.Resize(newWidth, newHeight);
|
||||
tex.SetPixels(newColors);
|
||||
tex.Apply();
|
||||
|
||||
texColors = null;
|
||||
newColors = null;
|
||||
}
|
||||
|
||||
public static void BilinearScale (int start, int end)
|
||||
{
|
||||
for (var y = start; y < end; y++)
|
||||
{
|
||||
int yFloor = (int)Mathf.Floor(y * ratioY);
|
||||
var y1 = yFloor * w;
|
||||
var y2 = (yFloor+1) * w;
|
||||
var yw = y * w2;
|
||||
|
||||
for (var x = 0; x < w2; x++) {
|
||||
int xFloor = (int)Mathf.Floor(x * ratioX);
|
||||
var xLerp = x * ratioX-xFloor;
|
||||
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(texColors[y1 + xFloor], texColors[y1 + xFloor+1], xLerp),
|
||||
ColorLerpUnclamped(texColors[y2 + xFloor], texColors[y2 + xFloor+1], xLerp),
|
||||
y*ratioY-yFloor);
|
||||
}
|
||||
}
|
||||
|
||||
finishCount++;
|
||||
}
|
||||
|
||||
public static void PointScale (int start, int end)
|
||||
{
|
||||
for (var y = start; y < end; y++)
|
||||
{
|
||||
var thisY = (int)(ratioY * y) * w;
|
||||
var yw = y * w2;
|
||||
for (var x = 0; x < w2; x++) {
|
||||
newColors[yw + x] = texColors[(int)(thisY + ratioX*x)];
|
||||
}
|
||||
}
|
||||
|
||||
finishCount++;
|
||||
}
|
||||
|
||||
private static Color ColorLerpUnclamped (Color c1, Color c2, float value)
|
||||
{
|
||||
return new Color (c1.r + (c2.r - c1.r)*value,
|
||||
c1.g + (c2.g - c1.g)*value,
|
||||
c1.b + (c2.b - c1.b)*value,
|
||||
c1.a + (c2.a - c1.a)*value);
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user