[TASK] Initial commit with basic product setup
This commit is contained in:
339
Assets/Mapbox SDK/Mapbox/Unity/Editor/AtlasTemplateGenerator.cs
Normal file
339
Assets/Mapbox SDK/Mapbox/Unity/Editor/AtlasTemplateGenerator.cs
Normal file
@@ -0,0 +1,339 @@
|
||||
using UnityEngine;
|
||||
using UnityEditor;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Mapbox.Unity.MeshGeneration.Data;
|
||||
using System.IO;
|
||||
|
||||
namespace Mapbox.Editor
|
||||
{
|
||||
|
||||
class AtlasTemplateGenerator : EditorWindow
|
||||
{
|
||||
[MenuItem("Mapbox/Atlas Template Generator")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
EditorWindow.GetWindow(typeof(AtlasTemplateGenerator));
|
||||
}
|
||||
|
||||
public class PixelRect
|
||||
{
|
||||
public int x;
|
||||
public int y;
|
||||
|
||||
public int xx;
|
||||
public int yy;
|
||||
}
|
||||
|
||||
public string m_saveFileName = "AtlasTemplate";
|
||||
|
||||
public Texture2D m_texture;
|
||||
|
||||
public AtlasInfo m_atlasInfo;
|
||||
|
||||
public Color[] m_colors;
|
||||
|
||||
public int m_textureResolution = 2048;
|
||||
|
||||
public bool m_generateFacadesTemplate = true;
|
||||
public bool m_generateRoofsTemplate = false;
|
||||
|
||||
private int _drawCount;
|
||||
|
||||
private const int _DEFAULT_TEX_SIZE = 2048;
|
||||
private const int _MIN_TEX_SIZE = 512;
|
||||
private const int _MAX_TEX_SIZE = 2048;
|
||||
|
||||
private const float _cellRatioMargin = 0.01f;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
CreateTexture();
|
||||
}
|
||||
|
||||
private void CreateTexture()
|
||||
{
|
||||
m_texture = new Texture2D(m_textureResolution, m_textureResolution, TextureFormat.ARGB32, false);
|
||||
m_texture.filterMode = FilterMode.Point;
|
||||
}
|
||||
|
||||
void OnGUI()
|
||||
{
|
||||
GUILayout.Space(20);
|
||||
|
||||
GUIStyle titleStyle = new GUIStyle(EditorStyles.label);
|
||||
|
||||
titleStyle.fontSize = 32;
|
||||
titleStyle.normal.textColor = Color.white;
|
||||
titleStyle.fontStyle = FontStyle.Bold;
|
||||
|
||||
titleStyle.stretchWidth = true;
|
||||
titleStyle.stretchHeight = true;
|
||||
|
||||
titleStyle.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
GUILayout.BeginVertical();
|
||||
|
||||
EditorGUILayout.LabelField("Mapbox Atlas Template Generator", titleStyle, GUILayout.Height(100));
|
||||
|
||||
GUILayout.BeginHorizontal();
|
||||
GUILayout.BeginVertical(GUILayout.MinWidth(200), GUILayout.MaxWidth(300));
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
EditorGUI.indentLevel++;
|
||||
|
||||
m_atlasInfo = EditorGUILayout.ObjectField("Atlas info:", m_atlasInfo, typeof(AtlasInfo), true) as Mapbox.Unity.MeshGeneration.Data.AtlasInfo;
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
m_generateFacadesTemplate = EditorGUILayout.Toggle("Create Facades", m_generateFacadesTemplate);
|
||||
m_generateRoofsTemplate = EditorGUILayout.Toggle("Create Roofs", m_generateRoofsTemplate);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (m_atlasInfo != null)
|
||||
{
|
||||
int facadeCount = m_generateFacadesTemplate ? m_atlasInfo.Textures.Count : 0;
|
||||
int roofCount = m_generateRoofsTemplate ? m_atlasInfo.Roofs.Count : 0;
|
||||
|
||||
int textureCount = facadeCount + roofCount;
|
||||
|
||||
m_colors = new Color[textureCount];
|
||||
|
||||
float hueIncrement = (float)1.0f / textureCount;
|
||||
float hue = 0.0f;
|
||||
|
||||
for (int i = 0; i < textureCount; i++)
|
||||
{
|
||||
m_colors[i] = Color.HSVToRGB(hue, 1.0f, 1.0f);
|
||||
hue += hueIncrement;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_colors = new Color[0];
|
||||
CreateTexture();
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUI.BeginChangeCheck();
|
||||
|
||||
m_textureResolution = Mathf.Clamp(EditorGUILayout.IntField("Texture resolution:", m_textureResolution), _MIN_TEX_SIZE, _MAX_TEX_SIZE);
|
||||
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
CreateTexture();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (m_colors != null)
|
||||
{
|
||||
for (int i = 0; i < m_colors.Length; i++)
|
||||
{
|
||||
string colorFieldName = string.Format("Color {0}", i);
|
||||
m_colors[i] = EditorGUILayout.ColorField(colorFieldName, m_colors[i]);
|
||||
}
|
||||
}
|
||||
|
||||
if (GUILayout.Button("Generate Template"))
|
||||
{
|
||||
if (m_atlasInfo == null)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Atlas Template Generator", "Error: No AtlasInfo object selected.", "Ok");
|
||||
return;
|
||||
}
|
||||
if (!m_generateFacadesTemplate && !m_generateRoofsTemplate)
|
||||
{
|
||||
EditorUtility.DisplayDialog("Atlas Template Generator", "Error: Template generation requires Create Facades and/or Create Roofs to be enabled.", "Ok");
|
||||
return;
|
||||
}
|
||||
GenerateTemplate();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
|
||||
if (GUILayout.Button("Save to file"))
|
||||
{
|
||||
SaveTextureAsPNG();
|
||||
}
|
||||
|
||||
EditorGUI.indentLevel--;
|
||||
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUIStyle boxStyle = new GUIStyle();
|
||||
|
||||
boxStyle.alignment = TextAnchor.UpperLeft;
|
||||
|
||||
GUILayout.Box(m_texture, boxStyle, GUILayout.Width(300), GUILayout.Height(300), GUILayout.ExpandWidth(true), GUILayout.ExpandHeight(true));
|
||||
|
||||
GUILayout.EndHorizontal();
|
||||
GUILayout.EndVertical();
|
||||
|
||||
GUILayout.Space(20);
|
||||
}
|
||||
|
||||
private int GetPixelCoorFromAtlasRatio(float ratio)
|
||||
{
|
||||
return (int)(m_textureResolution * ratio);
|
||||
}
|
||||
|
||||
private PixelRect ConvertUVRectToPixelRect(Rect atlasRect)
|
||||
{
|
||||
PixelRect pixelRect = new PixelRect();
|
||||
pixelRect.x = GetPixelCoorFromAtlasRatio(atlasRect.x);
|
||||
pixelRect.y = GetPixelCoorFromAtlasRatio(atlasRect.y);
|
||||
pixelRect.xx = GetPixelCoorFromAtlasRatio(atlasRect.x + atlasRect.width);
|
||||
pixelRect.yy = GetPixelCoorFromAtlasRatio(atlasRect.y + atlasRect.height);
|
||||
return pixelRect;
|
||||
}
|
||||
|
||||
private void DrawRect(PixelRect pr, Color color)
|
||||
{
|
||||
for (int i = pr.x; i < pr.xx; i++)
|
||||
{
|
||||
for (int j = pr.y; j < pr.yy; j++)
|
||||
{
|
||||
m_texture.SetPixel(i, j, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawWatermark(int x, int y)
|
||||
{
|
||||
m_texture.SetPixel(x, y, Color.black);
|
||||
m_texture.SetPixel(x + 3, y, Color.black);
|
||||
m_texture.SetPixel(x, y + 3, Color.black);
|
||||
m_texture.SetPixel(x + 3, y + 3, Color.black);
|
||||
|
||||
m_texture.SetPixel(x + 1, y + 1, Color.black);
|
||||
m_texture.SetPixel(x + 2, y + 1, Color.black);
|
||||
m_texture.SetPixel(x + 1, y + 2, Color.black);
|
||||
m_texture.SetPixel(x + 2, y + 2, Color.black);
|
||||
}
|
||||
|
||||
private void DrawCornerWatermarks(PixelRect pr)
|
||||
{
|
||||
DrawWatermark(pr.x, pr.y);
|
||||
DrawWatermark(pr.xx - 4, pr.y);
|
||||
DrawWatermark(pr.x, pr.yy - 4);
|
||||
DrawWatermark(pr.xx - 4, pr.yy - 4);
|
||||
}
|
||||
|
||||
private void DrawDebugCross(PixelRect pr)
|
||||
{
|
||||
int centerX = (pr.x + pr.xx) / 2;
|
||||
int centerY = (pr.y + pr.yy) / 2;
|
||||
|
||||
m_texture.SetPixel(centerX, centerY, Color.black);
|
||||
|
||||
for (int x = pr.x; x < pr.xx; x++)
|
||||
{
|
||||
m_texture.SetPixel(x, centerY, Color.black);
|
||||
m_texture.SetPixel(x, centerY - 1, Color.black);
|
||||
m_texture.SetPixel(x, centerY + 1, Color.black);
|
||||
}
|
||||
|
||||
for (int y = pr.y; y < pr.yy; y++)
|
||||
{
|
||||
m_texture.SetPixel(centerX, y, Color.black);
|
||||
m_texture.SetPixel(centerX - 1, y, Color.black);
|
||||
m_texture.SetPixel(centerX + 1, y, Color.black);
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawAtlasEntityData(List<AtlasEntity> aeList)
|
||||
{
|
||||
for (int i = 0; i < aeList.Count; i++)
|
||||
{
|
||||
AtlasEntity ae = aeList[i];
|
||||
|
||||
Rect baseRect = ae.TextureRect;
|
||||
|
||||
float topRatio = ae.TopSectionRatio * baseRect.height;
|
||||
float bottomRatio = ae.BottomSectionRatio * baseRect.height;
|
||||
float middleRatio = baseRect.height - (topRatio + bottomRatio);
|
||||
|
||||
Rect groundFloorRect = new Rect(baseRect.x, baseRect.y, baseRect.width, bottomRatio);
|
||||
Rect topFloorRect = new Rect(baseRect.x, baseRect.y + baseRect.height - topRatio, baseRect.width, topRatio);
|
||||
|
||||
PixelRect basePixelRect = ConvertUVRectToPixelRect(baseRect);
|
||||
PixelRect groundFloorPixelRect = ConvertUVRectToPixelRect(groundFloorRect);
|
||||
PixelRect topFloorPixelRect = ConvertUVRectToPixelRect(topFloorRect);
|
||||
|
||||
Color color = m_colors[_drawCount];
|
||||
Color colorLight = (color + Color.white) / 2;
|
||||
Color colorDark = (color + Color.black) / 2;
|
||||
|
||||
DrawRect(basePixelRect, color);
|
||||
DrawRect(groundFloorPixelRect, colorLight);
|
||||
DrawRect(topFloorPixelRect, colorDark);
|
||||
|
||||
DrawDebugCross(groundFloorPixelRect);
|
||||
DrawDebugCross(topFloorPixelRect);
|
||||
|
||||
int numColumns = (int)ae.ColumnCount;
|
||||
int numMidFloors = ae.MidFloorCount;
|
||||
|
||||
float colWidth = baseRect.width / numColumns;
|
||||
float floorHeight = middleRatio / numMidFloors;
|
||||
|
||||
float midFloorBase = baseRect.y + bottomRatio;
|
||||
|
||||
float mrgn = _cellRatioMargin;
|
||||
float halfMrgn = mrgn / 2;
|
||||
|
||||
for (int j = 0; j < numMidFloors; j++)
|
||||
{
|
||||
float floorStart = midFloorBase + (floorHeight * j);
|
||||
|
||||
for (int k = 0; k < numColumns; k++)
|
||||
{
|
||||
float columnStart = baseRect.x + (colWidth * k);
|
||||
|
||||
Rect cellRect = new Rect(columnStart + halfMrgn, floorStart + halfMrgn, colWidth - mrgn, floorHeight - mrgn);
|
||||
PixelRect cellPixelRect = ConvertUVRectToPixelRect(cellRect);
|
||||
|
||||
DrawRect(cellPixelRect, Color.white);
|
||||
DrawDebugCross(cellPixelRect);
|
||||
}
|
||||
}
|
||||
DrawCornerWatermarks(groundFloorPixelRect);
|
||||
DrawCornerWatermarks(topFloorPixelRect);
|
||||
_drawCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public void GenerateTemplate()
|
||||
{
|
||||
_drawCount = 0;
|
||||
if (m_generateFacadesTemplate)
|
||||
{
|
||||
DrawAtlasEntityData(m_atlasInfo.Textures);
|
||||
}
|
||||
if (m_generateRoofsTemplate)
|
||||
{
|
||||
DrawAtlasEntityData(m_atlasInfo.Roofs);
|
||||
}
|
||||
m_texture.Apply();
|
||||
}
|
||||
|
||||
public void SaveTextureAsPNG()
|
||||
{
|
||||
var path = EditorUtility.SaveFilePanel("Save texture as PNG", "Assets", "AtlasTemplate.png", "png");
|
||||
if (path.Length == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
byte[] pngData = m_texture.EncodeToPNG();
|
||||
if (pngData != null)
|
||||
{
|
||||
File.WriteAllBytes(path, pngData);
|
||||
Debug.Log(pngData.Length / 1024 + "Kb was saved as: " + path);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user