You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

159 lines
6.0 KiB

using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
namespace UnityEditor.Experimental.VFX.Utility
{
partial class PointCacheBakeTool : EditorWindow
{
public enum DecimationThresholdMode
{
None,
Alpha,
Luminance,
R,
G,
B
}
Texture2D m_Texture;
bool m_RandomizePixels;
int m_SeedPixels;
DecimationThresholdMode m_DecimationThresholdMode = DecimationThresholdMode.Alpha;
float m_Threshold = 0.33333f;
void OnGUI_Texture()
{
GUILayout.Label("Texture baking", EditorStyles.boldLabel);
m_Texture = (Texture2D)EditorGUILayout.ObjectField("Texture", m_Texture, typeof(Texture2D), false);
m_DecimationThresholdMode = (DecimationThresholdMode)EditorGUILayout.EnumPopup("Decimation Threshold", m_DecimationThresholdMode);
if (m_DecimationThresholdMode != DecimationThresholdMode.None)
m_Threshold = EditorGUILayout.Slider("Threshold", m_Threshold, 0.0f, 1.0f);
m_RandomizePixels = EditorGUILayout.Toggle("Randomize Pixels Order", m_RandomizePixels);
if (m_RandomizePixels)
m_SeedPixels = EditorGUILayout.IntField("Seed", m_SeedPixels);
m_ExportColors = EditorGUILayout.Toggle("Export Colors", m_ExportColors);
m_OutputFormat = (PCache.Format)EditorGUILayout.EnumPopup("File Format", m_OutputFormat);
if (m_Texture != null)
{
if (GUILayout.Button("Save to pCache file..."))
{
var fileName = EditorUtility.SaveFilePanelInProject("pCacheFile", m_Texture.name, "pcache", "Save PCache");
if (!string.IsNullOrEmpty(fileName))
{
PCache file = new PCache();
file.AddVector3Property("position");
if (m_ExportColors) file.AddColorProperty("color");
List<Vector3> positions = new List<Vector3>();
List<Vector4> colors = null;
if (m_ExportColors) colors = new List<Vector4>();
ComputeTextureData(positions, colors);
file.SetVector3Data("position", positions);
if (m_ExportColors)
file.SetColorData("color", colors);
file.SaveToFile(fileName, m_OutputFormat);
}
}
using (new GUILayout.VerticalScope(EditorStyles.helpBox))
{
EditorGUILayout.LabelField("Texture Statistics", EditorStyles.boldLabel);
EditorGUI.indentLevel++;
var saveEnabled = GUI.enabled;
GUI.enabled = false;
EditorGUILayout.IntField("Width", m_Texture.width);
EditorGUILayout.IntField("Height", m_Texture.height);
EditorGUILayout.IntField("Pixels count", m_Texture.width * m_Texture.height);
GUI.enabled = saveEnabled;
EditorGUI.indentLevel--;
}
}
}
private static void Swap<T>(IList<T> list, int a, int b)
{
T tmp = list[a];
list[a] = list[b];
list[b] = tmp;
}
void ComputeTextureData(List<Vector3> positions, List<Vector4> colors)
{
Color[] pixels = null;
if (!m_Texture.isReadable)
{
var path = AssetDatabase.GetAssetPath(m_Texture);
var importer = (TextureImporter)TextureImporter.GetAtPath(path);
var backupReadable = importer.isReadable;
importer.isReadable = true;
importer.SaveAndReimport();
pixels = m_Texture.GetPixels();
importer.isReadable = backupReadable;
importer.SaveAndReimport();
}
else
{
pixels = m_Texture.GetPixels();
}
int width = m_Texture.width;
int height = m_Texture.height;
for (int i = 0; i < pixels.Length; ++i)
{
var color = pixels[i];
if (m_Texture.isDataSRGB)
color = color.linear;
if (m_DecimationThresholdMode != DecimationThresholdMode.None)
{
float value;
switch (m_DecimationThresholdMode)
{
case DecimationThresholdMode.R: value = color.r; break;
case DecimationThresholdMode.G: value = color.g; break;
case DecimationThresholdMode.B: value = color.b; break;
case DecimationThresholdMode.Alpha: value = color.a; break;
case DecimationThresholdMode.Luminance: value = color.grayscale; break;
default: throw new System.NotImplementedException();
}
if (value < m_Threshold)
continue;
}
var fx = (float)(i % width) / width;
var fy = (float)(i / width) / height;
positions.Add(new Vector3(fx - 0.5f, fy - 0.5f, 0.0f));
if (colors != null)
{
colors.Add(color);
}
}
if (m_RandomizePixels && positions.Any())
{
var random = new System.Random((int)m_SeedPixels);
//Fisher-Yates shuffle
for (int i = 0; i < positions.Count; ++i)
{
int newIndex = i + random.Next(positions.Count - i);
Swap(positions, i, newIndex);
if (colors != null)
{
Swap(colors, i, newIndex);
}
}
}
}
}
}