8 Commits
1.4 ... 1.5

Author SHA1 Message Date
max
e81a4ec119 Merged goto01 and reworked some code.
Implemented the texture scaler provided by goto01 (Kiryl Tkachou) and removed the old ones.
Implmented the mesh export bugfixes.
Changed mesh export names.
Changed texture export names.
Updated the the export window.
Updated export functionality.
Updated hotkeys.
Fixed quad duplication bug.
Minor visual changes.

Co-Authored-By: Kiryl Tkachou <goto01@users.noreply.github.com>
2019-08-30 01:11:33 +02:00
26a0f68454 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.)
2019-08-29 18:56:01 +02:00
9f5240967a Added bilinear scaling and mesh replacing export mode 2019-07-26 15:52:40 +03:00
9a13ddb24e Fixed quad title 2019-07-26 15:51:51 +03:00
6ac386c1b5 Fixed quad title 2019-07-23 23:56:38 +03:00
e2abb77afe Fixed quad title 2019-07-23 23:53:53 +03:00
68b3ddaaa1 Fixed importing. 2019-07-23 23:48:36 +03:00
9d53f74c4b Fixed mesh duplication. 2019-07-23 18:51:39 +03:00
9 changed files with 469 additions and 342 deletions

View File

@ -36,7 +36,8 @@ namespace MA_TextureAtlasserPro
editorWorkRect = new Rect(Vector2.zero - zoomCoordsOrigin, textureAtlasSize);
GUI.backgroundColor = new Color(0, 0, 0, 0.1f);
GUI.Box(editorWorkRect, this.name);
GUI.Box(editorWorkRect, "");
GUI.Box(new Rect(editorWorkRect.x, editorWorkRect.y - 25, editorWorkRect.width, 20), this.name);
GUI.backgroundColor = Color.white;
MA_Editor.Grid.Grid.DrawZoomableGrid(editorWorkRect, 64, new Color(0, 0, 0, 0.1f), zoomCoordsOrigin);

View File

@ -25,7 +25,6 @@ namespace MA_TextureAtlasserPro
public Rect dragRectPos;
//Data
public Texture texture; //Replace this with texture groups
public List<MA_TextureGroup> textureGroups;
public List<Mesh> meshes;
@ -43,7 +42,7 @@ namespace MA_TextureAtlasserPro
//Clamp and snap the guiRect
guiRect = new Rect(Mathf.RoundToInt(rect.x / 32) * 32, Mathf.RoundToInt(rect.y / 32) * 32, Mathf.RoundToInt(rect.width / 32) * 32, Mathf.RoundToInt(rect.height / 32) * 32);
//Draw the sqaud background
//Draw the quad background
if(showTexture && textureGroups != null && textureGroups.Count > 0 && textureGroups[0].texture != null)
GUI.DrawTexture(new Rect(guiRect.x - zoomCoordsOrigin.x, guiRect.y - zoomCoordsOrigin.y, guiRect.width, guiRect.height), textureGroups[0].texture, ScaleMode.StretchToFill);
else
@ -53,7 +52,10 @@ namespace MA_TextureAtlasserPro
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
GUILayout.Label(this.name);
var tempColor = GUI.backgroundColor;
GUI.backgroundColor = new Color(1, 1, 1, 0.7f);
GUILayout.Label(" " + this.name + " ", GUI.skin.box);
GUI.backgroundColor = tempColor;
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();

View File

@ -10,18 +10,31 @@ namespace MA_TextureAtlasserPro
[System.Serializable]
public class MA_TextureAtlasserProSettings : ScriptableObject
{
[Header("Selection")]
public bool autoFocus = false;
[Header("Duplication:")]
public bool copySelectedQuadData = false;
public string duplicatedQuadNamePrefix = "new ";
[Header("Hotkeys:")]
public bool useHotkeys = false;
public EventModifiers modifierKey = EventModifiers.Alt;
public KeyCode addQuadHotKey = KeyCode.Q;
public KeyCode removeQuadHotKey = KeyCode.R;
public KeyCode duplicateHotKey = KeyCode.D;
public KeyCode zoomInHotKey = KeyCode.Equals;
public KeyCode zoomOutHotKey = KeyCode.Minus;
[Header("Duplication:")]
public bool copySelectedQuadData = true;
public string duplicatedQuadNamePrefix = "new ";
[Header("Selection")]
public bool autoFocus = true;
public bool GetHotKey(Event e, KeyCode shortKey)
{
if (e.type == EventType.KeyDown && e.modifiers == modifierKey && e.keyCode == shortKey)
{
return true;
}
return false;
}
}
}
#endif

View File

@ -8,6 +8,34 @@ using MA_Texture;
namespace MA_TextureAtlasserPro
{
public enum ExportPreset
{
Custom,
Default,
Sprites,
ReplaceObjMeshes
}
public enum ModelFormat
{
None,
Obj,
ReplaceObj
}
public enum TextureFormat
{
None,
Png
}
public enum TextureType
{
Default,
Sprite,
SpriteSliced
}
public static class MA_TextureAtlasserProUtils
{
public const string SETTINGSASSETPATH = "Assets/MA_ToolBox/MA_TextureAtlasserPro/Settings/";
@ -19,7 +47,7 @@ namespace MA_TextureAtlasserPro
public static MA_TextureAtlasserProSettings CreateSettings()
{
MA_TextureAtlasserProSettings _settings = (MA_TextureAtlasserProSettings)ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>();
MA_TextureAtlasserProSettings _settings = ScriptableObject.CreateInstance<MA_TextureAtlasserProSettings>();
if(_settings != null)
{
@ -49,7 +77,7 @@ namespace MA_TextureAtlasserPro
public static MA_TextureAtlasserProAtlas CreateTextureAtlas(string name, Vector2 size)
{
MA_TextureAtlasserProAtlas _atlas = (MA_TextureAtlasserProAtlas)ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>();
MA_TextureAtlasserProAtlas _atlas = ScriptableObject.CreateInstance<MA_TextureAtlasserProAtlas>();
if(_atlas != null)
{
@ -145,7 +173,7 @@ namespace MA_TextureAtlasserPro
}
}
public static void CreateTextureQuad(MA_TextureAtlasserProAtlas atlas, string name, Rect rect, bool focus = true)
public static MA_TextureAtlasserProQuad CreateTextureQuad(MA_TextureAtlasserProAtlas atlas, string name, Rect rect, bool focus = true)
{
if(atlas != null)
{
@ -156,7 +184,7 @@ namespace MA_TextureAtlasserPro
}
//Create new quad
MA_TextureAtlasserProQuad _quad = (MA_TextureAtlasserProQuad)ScriptableObject.CreateInstance("MA_TextureAtlasserProQuad");
MA_TextureAtlasserProQuad _quad = ScriptableObject.CreateInstance<MA_TextureAtlasserProQuad>();
//Add quad to asset
if(_quad != null)
@ -167,7 +195,7 @@ namespace MA_TextureAtlasserPro
SetTextureGroups(atlas, _quad);
atlas.textureQuads.Add((MA_TextureAtlasserProQuad)_quad);
atlas.textureQuads.Add(_quad);
AssetDatabase.AddObjectToAsset(_quad, atlas);
AssetDatabase.SaveAssets();
@ -177,6 +205,8 @@ namespace MA_TextureAtlasserPro
{
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
}
return _quad;
}
else
{
@ -187,6 +217,8 @@ namespace MA_TextureAtlasserPro
{
Debug.LogError("CreateTextureQuad Failed: textureAtlas");
}
return null;
}
public static void RemoveTextureQuad(MA_TextureAtlasserProAtlas atlas, bool focus = true)
@ -196,7 +228,7 @@ namespace MA_TextureAtlasserPro
int _index = atlas.textureQuads.IndexOf(atlas.selectedTextureQuad);
atlas.textureQuads.RemoveAt(_index);
GameObject.DestroyImmediate(atlas.selectedTextureQuad, true);
Object.DestroyImmediate(atlas.selectedTextureQuad, true);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
@ -212,18 +244,25 @@ namespace MA_TextureAtlasserPro
{
if(atlas != null && atlas.selectedTextureQuad != null)
{
CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false);
MA_TextureAtlasserProQuad q = CreateTextureQuad(atlas, namePrefix + atlas.selectedTextureQuad.name, atlas.selectedTextureQuad.rect, false);
if (copyData)
{
atlas.textureQuads[atlas.textureQuads.Count - 1].meshes = atlas.selectedTextureQuad.meshes;
atlas.textureQuads[atlas.textureQuads.Count - 1].textureGroups = atlas.selectedTextureQuad.textureGroups;
q.meshes = atlas.selectedTextureQuad.meshes;
for (int i = 0; i < atlas.selectedTextureQuad.textureGroups.Count; i++)
{
q.textureGroups[i].texture = atlas.selectedTextureQuad.textureGroups[i].texture;
}
}
if(focus)
{
atlas.selectedTextureQuad = atlas.textureQuads[atlas.textureQuads.Count - 1];
atlas.selectedTextureQuad = q;
}
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
}
}
@ -276,21 +315,40 @@ namespace MA_TextureAtlasserPro
curWindow.Close();
}
public static void ExportAtlas(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
public static bool IsPowerOfTwo(int value)
{
if(atlas != null && atlas.textureQuads != null)
//While x is even and > 1
while (((value % 2) == 0) && value > 1)
{
ExportAtlasMeshesObj(atlas);
ExportAtlasTexturesPNG(atlas);
value /= 2;
}
AssetDatabase.Refresh();
return (value == 1);
}
#region Export
public static void ExportAtlasModels(MA_TextureAtlasserProAtlas atlas, ModelFormat modelFormat, string savePath = EXPORTASSETPATH)
{
switch (modelFormat)
{
case ModelFormat.None:
break;
case ModelFormat.Obj:
ExportAtlasObj(atlas, savePath);
break;
case ModelFormat.ReplaceObj:
ModifyAtlasObj(atlas);
break;
default:
break;
}
}
public static void ExportAtlasMeshesObj(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
{
if(atlas != null && atlas.textureQuads != null)
public static void ExportAtlasObj(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
{
if (atlas == null || atlas.textureQuads == null)
return;
foreach (MA_TextureAtlasserProQuad ta in atlas.textureQuads)
{
//Export Mesh
@ -304,51 +362,67 @@ namespace MA_TextureAtlasserPro
Mesh newMesh = new Mesh();
//Duplicate it from the current one
newMesh = MA_MeshUtils.MA_DuplicateMesh(ta.meshes[m]);
//Remap uvs
//Remap UV's
newMesh = MA_MeshUtils.MA_UVReMap(newMesh, atlas.textureAtlasSize, ta.guiRect);
//Save it
MA_MeshUtils.MeshToFile(newMesh, "MA_" + ta.name, savePath);
}
string modelName = string.IsNullOrEmpty(ta.name) ? "": ta.name + "-";
modelName += ta.meshes[m].name;
int n = m + 1;
modelName += "_" + n.ToString("#000");
MA_MeshUtils.MeshToFile(newMesh, modelName, savePath);
}
}
}
}
}
// public static void ExportAtlasTexturePNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
// {
// if(atlas != null && atlas.textureQuads != null)
// {
// //Create new Texture Atlas
// Texture2D newTexture = new Texture2D((int)atlas.textureAtlasSize.x, (int)atlas.textureAtlasSize.y);
// newTexture.name = atlas.name;
// foreach (MA_TextureAtlasserProQuad ta in atlas.textureQuads)
// {
// //Export Texture Atlas
// //TODO: Replace with texture groups (foreacht ...)
// if(ta.texture != null)
// {
// //Create new texture part
// Texture2D newTexturePart = (Texture2D)MA_Texture.MA_TextureUtils.ConvertToReadableTexture(ta.texture);
// //Scale it
// newTexturePart = newTexturePart.MA_Scale2D((int)ta.guiRect.width, (int)ta.guiRect.height);
// //Add it
// newTexture = newTexture.MA_Combine2D(newTexturePart, (int)ta.guiRect.x, (int)ta.guiRect.y);
// }
// }
// //Save it
// newTexture.MA_Save2D("MA_" + newTexture.name, savePath);
// //Refresh
// AssetDatabase.Refresh();
// }
// }
public static void ExportAtlasTexturesPNG(MA_TextureAtlasserProAtlas atlas, string savePath = EXPORTASSETPATH)
public static void ModifyAtlasObj(MA_TextureAtlasserProAtlas atlas)
{
if(atlas != null && atlas.textureQuads != null && atlas.textureGroupRegistration != null)
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 ExportAtlasTextures(MA_TextureAtlasserProAtlas atlas, TextureFormat textureFormat, TextureType textureType, MA_TextureUtils.TextureScaleMode scaleMode, string savePath = EXPORTASSETPATH)
{
switch (textureFormat)
{
case TextureFormat.None:
break;
case TextureFormat.Png:
ExportAtlasPNG(atlas, textureType, scaleMode, savePath);
break;
default:
break;
}
}
private static void ExportAtlasPNG(MA_TextureAtlasserProAtlas atlas, TextureType textureType, MA_TextureUtils.TextureScaleMode scaleMode, string savePath = EXPORTASSETPATH)
{
if (atlas == null || atlas.textureQuads == null || atlas.textureGroupRegistration == null)
return;
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{
@ -363,42 +437,51 @@ 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.MA_Scale2D((int)q.guiRect.width, (int)q.guiRect.height, scaleMode);
//Add it
newTexture = newTexture.MA_Combine2D(newTexturePart, (int)q.guiRect.x, (int)q.guiRect.y);
}
}
//Save it
newTexture.MA_Save2D("MA_" + newTexture.name, savePath);
newTexture.MA_Save2D(newTexture.name, savePath);
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + "MA_" + newTexture.name + ".png");
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + newTexture.name + ".png");
textureImporter.textureType = TextureImporterType.Default;
textureImporter.SaveAndReimport();
}
switch (textureType)
{
case TextureType.Default:
break;
case TextureType.Sprite:
SetAtlasPNGSpriteSettings(atlas, textureType, savePath);
break;
case TextureType.SpriteSliced:
SetAtlasPNGSpriteSettings(atlas, textureType, savePath);
break;
default:
break;
}
//Refresh
AssetDatabase.Refresh();
}
}
public static void ExportAtlasSpritesPNG(MA_TextureAtlasserProAtlas atlas, bool sliceSprites = true, string savePath = EXPORTASSETPATH)
private static void SetAtlasPNGSpriteSettings(MA_TextureAtlasserProAtlas atlas, TextureType textureType, string savePath = EXPORTASSETPATH)
{
if (atlas != null && atlas.textureQuads != null && atlas.textureGroupRegistration != null)
{
ExportAtlasTexturesPNG(atlas, savePath);
//Foreach texture group
for (int i = 0; i < atlas.textureGroupRegistration.Count; i++)
{
//Convert
string textureName = "MA_" + atlas.name + "_" + atlas.textureGroupRegistration[i].name + ".png";
string textureName = atlas.name + "_" + atlas.textureGroupRegistration[i].name + ".png";
TextureImporter textureImporter = (TextureImporter)AssetImporter.GetAtPath(savePath + textureName);
textureImporter.textureType = TextureImporterType.Sprite;
textureImporter.alphaIsTransparency = true;
//Slice sprites.
if (sliceSprites)
if (textureType == TextureType.SpriteSliced)
{
textureImporter.spriteImportMode = SpriteImportMode.None; //Reset it to update?
textureImporter.spriteImportMode = SpriteImportMode.Multiple;
@ -425,25 +508,10 @@ namespace MA_TextureAtlasserPro
textureImporter.spriteImportMode = SpriteImportMode.Single;
}
textureImporter.SaveAndReimport();
}
//Refresh
AssetDatabase.Refresh();
}
}
public static bool IsPowerOfTwo(int value)
{
//While x is even and > 1
while (((value % 2) == 0) && value > 1)
{
value /= 2;
}
return (value == 1);
}
#endregion
}
}
#endif

View File

@ -19,7 +19,7 @@ namespace MA_TextureAtlasserPro
private const float kZoomMax = 2.0f;
private Rect zoomArea;
private float zoom = 1.0f;
public float Zoom { get { return zoom; } }
public float Zoom { get { return zoom; } set { zoom = Mathf.Clamp(value, kZoomMin, kZoomMax); } }
private Vector2 zoomCoordsOrigin = Vector2.zero;
public override void UpdateView(Event e, Rect editorViewRect)
@ -96,21 +96,32 @@ namespace MA_TextureAtlasserPro
{
if(curWindow.textureAtlas != null)
{
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.addQuadHotKey)
if (curWindow.settings.GetHotKey(e, curWindow.settings.addQuadHotKey))
{
MA_TextureAtlasserProUtils.CreateTextureQuad(curWindow.textureAtlas, "new Quad", new Rect(0, 0, 128, 128), curWindow.settings.autoFocus);
e.Use();
}
if(curWindow.settings.GetHotKey(e, curWindow.settings.zoomInHotKey))
{
Zoom += 0.25f;
e.Use();
}
if(curWindow.settings.GetHotKey(e, curWindow.settings.zoomOutHotKey))
{
Zoom -= 0.25f;
e.Use();
}
if (curWindow.textureAtlas.selectedTextureQuad != null)
{
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.removeQuadHotKey)
if (curWindow.settings.GetHotKey(e, curWindow.settings.removeQuadHotKey))
{
MA_TextureAtlasserProUtils.RemoveTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus);
e.Use();
}
if (e.type == EventType.KeyDown && e.keyCode == curWindow.settings.duplicateHotKey)
if (curWindow.settings.GetHotKey(e, curWindow.settings.duplicateHotKey))
{
MA_TextureAtlasserProUtils.DuplicateTextureQuad(curWindow.textureAtlas, curWindow.settings.autoFocus, curWindow.settings.copySelectedQuadData, curWindow.settings.duplicatedQuadNamePrefix);
e.Use();

View File

@ -4,11 +4,14 @@ using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using MA_Editor;
using MA_Texture;
namespace MA_TextureAtlasserPro
{
public class MA_TextureAtlasserProExportWindow : EditorWindow
{
private const int WindowHeight = 235;
//Editor
private static MA_TextureAtlasserProExportWindow thisWindow;
public static MA_TextureAtlasserProWindow curWindow;
@ -16,18 +19,20 @@ 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 bool exportObjDefault = false;
private bool exportPngDefault = false;
private bool exportSprite = false;
private bool exportSliceSprite = false;
//Export settings.
private ExportPreset exportPreset = ExportPreset.Default;
private ModelFormat modelFormat = ModelFormat.Obj;
private TextureFormat textureFormat = TextureFormat.Png;
private TextureType textureType = TextureType.Default;
private MA_TextureUtils.TextureScaleMode textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
[MenuItem("MA_ToolKit/MA_TextureAtlasserPro/Export Atlas")]
private static void Init()
{
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 +45,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,63 +106,42 @@ 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();
DrawExportPresetMenu();
DrawExportAdvancedOptions();
GUILayout.BeginHorizontal(EditorStyles.helpBox);
switch (exportPreset)
{
case ExportPreset.Custom:
break;
case ExportPreset.Default:
modelFormat = ModelFormat.Obj;
textureFormat = TextureFormat.Png;
textureType = TextureType.Default;
textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
break;
case ExportPreset.Sprites:
modelFormat = ModelFormat.None;
textureFormat = TextureFormat.Png;
textureType = TextureType.SpriteSliced;
textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
break;
case ExportPreset.ReplaceObjMeshes:
modelFormat = ModelFormat.ReplaceObj;
textureFormat = TextureFormat.Png;
textureType = TextureType.Default;
textureScaleMode = MA_TextureUtils.TextureScaleMode.Bilinear;
break;
default:
break;
}
if (GUILayout.Button("Export", GUILayout.ExpandWidth(true), GUILayout.Height(37)))
{
if(exportObjDefault)
{
MA_TextureAtlasserProUtils.ExportAtlasMeshesObj(curWindow.textureAtlas);
}
if(exportPngDefault)
{
if(exportSprite)
{
MA_TextureAtlasserProUtils.ExportAtlasSpritesPNG(curWindow.textureAtlas, exportSliceSprite);
}
else
{
MA_TextureAtlasserProUtils.ExportAtlasTexturesPNG(curWindow.textureAtlas);
}
}
MA_TextureAtlasserProUtils.ExportAtlasModels(curWindow.textureAtlas, modelFormat);
MA_TextureAtlasserProUtils.ExportAtlasTextures(curWindow.textureAtlas, textureFormat, textureType, textureScaleMode);
}
GUILayout.EndHorizontal();
@ -187,6 +171,43 @@ namespace MA_TextureAtlasserPro
if(e.type == EventType.Repaint)
isLoaded = true;
}
private void DrawExportPresetMenu()
{
GUILayout.BeginHorizontal(EditorStyles.helpBox);
exportPreset = (ExportPreset)EditorGUILayout.EnumPopup("ExportPreset:", exportPreset, GUILayout.ExpandWidth(true));
GUILayout.EndHorizontal();
}
private void DrawExportAdvancedOptions()
{
bool wasEnabled = GUI.enabled;
if(exportPreset == ExportPreset.Custom)
{
GUI.enabled = true;
}
else
{
GUI.enabled = false;
}
EditorGUILayout.BeginVertical(EditorStyles.helpBox);
GUILayout.Label("Models:", EditorStyles.miniBoldLabel);
modelFormat = (ModelFormat)EditorGUILayout.EnumPopup("ModelFormat:", modelFormat);
GUILayout.Label("Textures:", EditorStyles.miniBoldLabel);
textureFormat = (TextureFormat)EditorGUILayout.EnumPopup("TextureFormat:", textureFormat);
textureType = (TextureType)EditorGUILayout.EnumPopup("TextureType:", textureType);
textureScaleMode = (MA_TextureUtils.TextureScaleMode)EditorGUILayout.EnumPopup("TextureScaleMode:", textureScaleMode);
EditorGUILayout.EndVertical();
GUI.enabled = wasEnabled;
}
}
}
#endif

View File

@ -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

View File

@ -5,6 +5,7 @@
//https://forum.unity3d.com/threads/contribution-texture2d-blur-in-c.185694/
//http://orbcreation.com/orbcreation/page.orb?1180
//https://support.unity3d.com/hc/en-us/articles/206486626-How-can-I-get-pixels-from-unreadable-textures-
//https://github.com/maxartz15/MA_TextureAtlasser/commit/9f5240967a51692fa2a17a6b3c8d124dd5dc60f9
#if UNITY_EDITOR
using UnityEngine;
@ -12,6 +13,7 @@ using UnityEditor;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System;
namespace MA_Texture
{
@ -44,6 +46,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;
@ -68,8 +71,6 @@ namespace MA_Texture
bw.Close();
fs.Close();
Debug.Log("Saved texture: " + texture.name);
AssetDatabase.Refresh();
return texture;
@ -88,97 +89,103 @@ namespace MA_Texture
#endregion
#region Scale
public static Texture2D MA_Scale2D(this Texture2D texture, int newWidth, int newHeight)
public enum TextureScaleMode
{
Texture2D texture2D = new Texture2D(newWidth, newHeight);
float ratioWidth = texture.width / newWidth;
float ratioHeight = texture.height / newHeight;
for (int x = 0; x < texture.width; x++)
{
for (int y = 0; y < texture.height; y++)
{
Color pixel = texture.GetPixel(x, y);
int posX = Mathf.FloorToInt(x / ratioWidth);
int posY = Mathf.FloorToInt(y / ratioHeight);
texture2D.SetPixel(posX, posY, new Color(pixel.r, pixel.g, pixel.b, pixel.a));
}
}
texture2D.Apply();
return texture2D;
Bilinear,
Point
}
public static Texture MA_Scale(this Texture texture, int newWidth, int newHeight)
public static Texture MA_Scale(this Texture texture, int width, int height, TextureScaleMode scaleMode)
{
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
texture2D.MA_Scale2D(newWidth, newHeight);
texture2D.MA_Scale2D(width, height, scaleMode);
texture = texture2D;
return texture;
}
public static Texture2D MA_Scale22D(this Texture2D texture, float width, float height)
public static Texture2D MA_Scale2D(this Texture2D texture, int newWidth, int newHeight, TextureScaleMode scaleMode)
{
float ratioWidth = width / texture.width;
float ratioHeight = height / texture.height;
Color[] curColors = texture.GetPixels();
Color[] newColors = new Color[newWidth * newHeight];
int newWidth = Mathf.RoundToInt(texture.width * ratioWidth);
int newHeight = Mathf.RoundToInt(texture.height * ratioHeight);
Texture2D newTexture = new Texture2D(newWidth, newHeight);
for (int x = 0; x < texture.width; x++)
switch (scaleMode)
{
for (int y = 0; y < texture.height; y++)
{
Color pixel = texture.GetPixel(x, y);
int posX = Mathf.RoundToInt(x * ratioWidth);
int posY = Mathf.RoundToInt(y * ratioHeight);
newTexture.SetPixel(posX, posY, new Color(pixel.r, pixel.g, pixel.b, pixel.a));
}
case TextureScaleMode.Bilinear:
newColors = MA_BilinearScale(curColors, texture.width, texture.height, newWidth, newHeight);
break;
case TextureScaleMode.Point:
newColors = MA_PointScale(curColors, texture.width, texture.height, newWidth, newHeight);
break;
}
newTexture.name = texture.name;
newTexture.Apply();
return newTexture;
}
public static Texture MA_Scale2(this Texture texture, float newWidth, float newHeight)
{
Texture2D texture2D = (Texture2D)MA_TextureUtils.ConvertToReadableTexture(texture);
texture = texture2D.MA_Scale22D(newWidth, newHeight);
texture.Resize(newWidth, newHeight);
texture.SetPixels(newColors);
texture.Apply();
return texture;
}
public static Texture2D MA_Scale32D(this Texture2D texture, int width, int height)
private static Color[] MA_BilinearScale(Color[] curColors, int curWidth, int curHeight, int newWidth, int newHeight)
{
float ratioWidth = (float)width / texture.width;
float ratioHeight = (float)height / texture.height;
Color[] newColors = new Color[newWidth * newHeight];
Texture2D newTexture = new Texture2D(width, height);
float ratioX = 1.0f / ((float)newWidth / (curWidth - 1));
float ratioY = 1.0f / ((float)newHeight / (curHeight - 1));
for (int x = 0; x < width; x++)
for (int y = 0; y < newHeight; y++)
{
int posX = Mathf.FloorToInt(x / ratioWidth);
for (int y = 0; y < height; y++)
int yFloor = Mathf.FloorToInt(y * ratioY);
var y1 = yFloor * curWidth;
var y2 = (yFloor + 1) * curWidth;
var yw = y * newWidth;
for (int x = 0; x < newWidth; x++)
{
int posY = Mathf.FloorToInt(y / ratioHeight);
Color pixel = texture.GetPixel(posX, posY);
newTexture.SetPixel(x, y, new Color(pixel.r, pixel.g, pixel.b, pixel.a));
int xFloor = Mathf.FloorToInt(x * ratioX);
var xLerp = x * ratioX - xFloor;
newColors[yw + x] = ColorLerpUnclamped(ColorLerpUnclamped(curColors[y1 + xFloor], curColors[y1 + xFloor + 1], xLerp),
ColorLerpUnclamped(curColors[y2 + xFloor], curColors[y2 + xFloor + 1], xLerp),
y * ratioY - yFloor);
}
}
newTexture.name = texture.name;
newTexture.Apply();
return newTexture;
return newColors;
}
private static Color[] MA_PointScale(Color[] curColors, int curWidth, int curHeight, int newWidth, int newHeight)
{
Color[] newColors = new Color[newWidth * newHeight];
float ratioX = ((float)curWidth) / newWidth;
float ratioY = ((float)curHeight) / newHeight;
for (int y = 0; y < newHeight; y++)
{
var thisY = Mathf.RoundToInt((ratioY * y) * curWidth);
var yw = y * newWidth;
for (int x = 0; x < newWidth; x++)
{
newColors[yw + x] = curColors[Mathf.RoundToInt(thisY + ratioX * x)];
}
}
return newColors;
}
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);
}
#endregion
#region combine
@ -191,7 +198,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