rabidus-test/Assets/PolyFew/Scripts/NonEditor/DataContainer.cs

501 lines
17 KiB
C#

//////////////////////////////////////////////////////
// Copyright (c) BrainFailProductions
//////////////////////////////////////////////////////
#if UNITY_EDITOR
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
using static BrainFailProductions.PolyFew.CombiningInformation;
namespace BrainFailProductions.PolyFew
{
[System.Serializable]
public class DataContainer
{
[System.Serializable]
public class TempGameObjectWrapper
{
[HideInInspector]
[SerializeField]
private GameObject gameObject;
// This is the unique Id for the current GameObject and it's children hierarchy
[HideInInspector]
[SerializeField]
private int uniqueId;
private TempGameObjectWrapper(GameObject gameObject)
{
this.gameObject = gameObject ?? throw new ArgumentNullException(nameof(gameObject));
uniqueId = gameObject.GetInstanceID();
}
public static implicit operator GameObject(TempGameObjectWrapper gameObjectWrapper) => gameObjectWrapper.gameObject;
public static explicit operator TempGameObjectWrapper(GameObject gameObject) => new TempGameObjectWrapper(gameObject);
public override int GetHashCode()
{
return uniqueId;
}
public override bool Equals(object obj)
{
if ((obj == null) || !GetType().Equals(obj.GetType()))
{
return false;
}
else
{
return (GetHashCode() == obj.GetHashCode());
}
}
}
[System.Serializable]
public class ObjectMeshPair : SerializableDictionary<GameObject, MeshRendererPair> { }
[System.Serializable]
public class MeshRendererPair
{
public bool attachedToMeshFilter;
public Mesh mesh;
public MeshRendererPair(bool attachedToMeshFilter, Mesh mesh)
{
this.attachedToMeshFilter = attachedToMeshFilter;
this.mesh = mesh;
}
public void Destruct()
{
if(mesh != null)
{
UnityEngine.Object.DestroyImmediate(mesh);
}
}
}
[System.Serializable]
public class CustomMeshActionStructure
{
public MeshRendererPair meshRendererPair;
public GameObject gameObject;
public Action action;
public CustomMeshActionStructure(MeshRendererPair meshRendererPair, GameObject gameObject, Action action)
{
this.meshRendererPair = meshRendererPair;
this.gameObject = gameObject;
this.action = action;
}
}
[System.Serializable]
public class ObjectHistory
{
public bool isReduceDeep;
public ObjectMeshPair objectMeshPairs;
public ObjectHistory(bool isReduceDeep, ObjectMeshPair objectMeshPairs)
{
this.isReduceDeep = isReduceDeep;
this.objectMeshPairs = objectMeshPairs;
}
public void Destruct()
{
if (objectMeshPairs == null || objectMeshPairs.Count == 0)
{
return;
}
foreach (var item in objectMeshPairs)
{
item.Value.Destruct();
}
objectMeshPairs = null;
}
}
[System.Serializable]
public class UndoRedoOps
{
private const int OBJECT_HISTORY_LIMIT = 5;
public GameObject gameObject;
public List<ObjectHistory> undoOperations;
public List<ObjectHistory> redoOperations;
public UndoRedoOps(GameObject gameObject, List<ObjectHistory> undoOperations, List<ObjectHistory> redoOperations)
{
this.gameObject = gameObject;
this.undoOperations = undoOperations;
this.redoOperations = redoOperations;
}
public void SaveRecord(bool isReduceDeep, bool isUndo, ObjectMeshPair originalMeshesClones)
{
if (undoOperations == null)
{
undoOperations = new List<ObjectHistory>();
}
if (redoOperations == null)
{
redoOperations = new List<ObjectHistory>();
}
if (isUndo)
{
if (undoOperations.Count == OBJECT_HISTORY_LIMIT)
{
undoOperations[0].Destruct();
undoOperations[0] = null;
undoOperations.RemoveAt(0);
}
ObjectHistory undoOperation = new ObjectHistory(isReduceDeep, originalMeshesClones);
undoOperations.Add(undoOperation);
}
else
{
if (redoOperations.Count == OBJECT_HISTORY_LIMIT)
{
redoOperations[0].Destruct();
redoOperations[0] = null;
redoOperations.RemoveAt(0);
}
ObjectHistory redoOperation = new ObjectHistory(isReduceDeep, originalMeshesClones);
redoOperations.Add(redoOperation);
}
}
public void ApplyUndoRedoOperation(bool isUndo)
{
if (isUndo)
{
if (undoOperations == null || undoOperations.Count == 0)
{
return;
}
}
else
{
if (redoOperations == null || redoOperations.Count == 0)
{
return;
}
}
List<ObjectHistory> operations = isUndo ? undoOperations : redoOperations;
ObjectHistory lastOp = operations[operations.Count - 1];
if (lastOp.isReduceDeep)
{
if (isUndo)
{
//Debug.Log("Last undo operation was reduce deep ObjectMeshPair count " + lastOp.objectMeshPairs.Count);
}
else
{
//Debug.Log("Last redo operation was reduce deep ObjectMeshPair count " + lastOp.objectMeshPairs.Count);
}
}
else
{
if (isUndo)
{
//Debug.Log("Last undo operation was NOT reduce deep ObjectMeshPair count " + lastOp.objectMeshPairs.Count);
}
else
{
//Debug.Log("Last redo operation was NOT reduce deep ObjectMeshPair count " + lastOp.objectMeshPairs.Count);
}
}
ObjectMeshPair originalMeshesClones = new ObjectMeshPair();
int totalOverwrites = lastOp.objectMeshPairs.Count;
int done = 0;
foreach (var kvp in lastOp.objectMeshPairs)
{
EditorUtility.DisplayProgressBar("Performing Undo/Redo", $"Reverting mesh changes to existing files {++done}/{totalOverwrites}", ((float)done / totalOverwrites));
MeshRendererPair meshRendererPair = kvp.Value;
GameObject gameObject = kvp.Key;
if (gameObject == null) { continue; }
if (meshRendererPair == null) { continue; }
if (meshRendererPair.mesh == null) { continue; }
if (meshRendererPair.attachedToMeshFilter)
{
MeshFilter filter = gameObject.GetComponent<MeshFilter>();
if (filter != null)
{
Mesh origMesh = UnityEngine.Object.Instantiate(filter.sharedMesh);
MeshRendererPair originalPair = new MeshRendererPair(true, origMesh);
originalMeshesClones.Add(gameObject, originalPair);
// Overwrites the mesh assets and keeps references intact
if (UtilityServices.OverwriteAssetWith(filter.sharedMesh, meshRendererPair.mesh, true)) { }
else
{
filter.sharedMesh.Clear();
EditorUtility.CopySerialized(meshRendererPair.mesh, filter.sharedMesh);
filter.sharedMesh.vertices = meshRendererPair.mesh.vertices;
}
//meshRendererPair.Destruct();
}
}
else
{
SkinnedMeshRenderer sRenderer = gameObject.GetComponent<SkinnedMeshRenderer>();
if (sRenderer != null)
{
Mesh origMesh = UnityEngine.Object.Instantiate(sRenderer.sharedMesh);
MeshRendererPair originalPair = new MeshRendererPair(false, origMesh);
originalMeshesClones.Add(gameObject, originalPair);
//sRenderer.sharedMesh.MakeSimilarToOtherMesh(meshRendererPair.mesh);
//sRenderer.sharedMesh.Clear();
//EditorUtility.CopySerialized(meshRendererPair.mesh, sRenderer.sharedMesh);
//Overwrites the mesh assets and keeps references intact
if (UtilityServices.OverwriteAssetWith(sRenderer.sharedMesh, meshRendererPair.mesh, true)) { }
else
{
sRenderer.sharedMesh.Clear();
EditorUtility.CopySerialized(meshRendererPair.mesh, sRenderer.sharedMesh);
sRenderer.sharedMesh.vertices = meshRendererPair.mesh.vertices;
}
//meshRendererPair.Destruct();
}
}
}
SaveRecord(lastOp.isReduceDeep, !isUndo, originalMeshesClones);
lastOp.objectMeshPairs = null;
lastOp = null;
operations.RemoveAt(operations.Count - 1);
EditorUtility.ClearProgressBar();
}
public void Destruct()
{
if (undoOperations != null && undoOperations.Count > 0)
{
foreach (var operation in undoOperations)
{
operation.Destruct();
}
}
if (redoOperations != null && redoOperations.Count > 0)
{
foreach (var operation in redoOperations)
{
operation.Destruct();
}
}
}
}
[System.Serializable]
public class LODLevelSettings
{
public float reductionStrength;
public float transitionHeight;
public bool preserveUVFoldover;
public bool preserveUVSeams;
public bool preserveBorders;
public bool useEdgeSort;
public bool recalculateNormals;
public float aggressiveness;
public int maxIterations;
public bool regardCurvature;
public bool regardTolerance;
public bool combineMeshes;
public bool simplificationOptionsFoldout;
public bool intensityFoldout;
public List<float> sphereIntensities;
public LODLevelSettings(float reductionStrength, float transitionHeight, bool preserveUVFoldover, bool preserveUVSeams, bool preserveBorders, bool smartLinking, bool recalculateNormals, float aggressiveness, int maxIterations, bool regardTolerance, bool regardCurvature, bool combineMeshes, List<float> preservationStrengths)
{
this.reductionStrength = reductionStrength;
this.transitionHeight = transitionHeight;
this.preserveUVFoldover = preserveUVFoldover;
this.preserveUVSeams = preserveUVSeams;
this.preserveBorders = preserveBorders;
this.useEdgeSort = smartLinking;
this.recalculateNormals = recalculateNormals;
this.aggressiveness = aggressiveness;
this.maxIterations = maxIterations;
this.regardTolerance = regardTolerance;
this.regardCurvature = regardCurvature;
this.combineMeshes = combineMeshes;
this.sphereIntensities = preservationStrengths;
}
}
[System.Serializable]
public class LODBackup
{
[SerializeField]
private Renderer[] originalRenderers = null;
[SerializeField]
public GameObject lodParentObject;
public Renderer[] OriginalRenderers
{
get { return originalRenderers; }
set { originalRenderers = value; }
}
}
public UndoRedoOps objectsHistory;
public ObjectMeshPair objectMeshPairs;
public List<LODLevelSettings> currentLodLevelSettings;
public List<ToleranceSphere> toleranceSpheres;
public LODBackup lodBackup;
#region BATCH FEW DATA
public TextureArrayGroup textureArraysSettings;
public List<MaterialProperties> materialsToRestore;
public ObjectMaterialLinks lastObjMaterialLinks; // BeforeSerialization
public bool relocateMaterialLinks;
public bool reInitializeTempMatProps;
public int choiceTextureMap = 0;
public int choiceDiffuseColorSpace = 0;
public readonly string[] textureMapsChoices = new[] { "Albedo", "Metallic", "Specular", "Normal", "Height", "Occlusion", "Emission", "Detail Mask", "Detail Albedo", "Detail Normal" };
//public readonly string[] compressionTypesChoices = new[] { "Uncompressed", "DXT1", "ETC2_RGB", "PVRTC_RGB4", "ASTC_RGB", "DXT1_CRUNCHED" };
public readonly string[] compressionTypesChoices = new[] { "Uncompressed", "DXT1", "ETC2_RGB", "PVRTC_RGB4", "ASTC_RGB"};
public readonly string[] resolutionsChoices = new[] { "32", "64", "128", "256", "512", "1024", "2048", "4096" };
public readonly string[] filteringModesChoices = new[] { "Point (no filter)", "Bilinear", "Trilinear" };
public readonly string[] compressionQualitiesChoices = new[] { "Low", "Medium", "High" };
public readonly string[] colorSpaceChoices = new[] { "Non_Linear", "Linear" };
public string batchFewSavePath = "";
#endregion BATCH FEW DATA
#region ALTER TEXTURE ARRAYS
public List<Texture2DArray> existingTextureArrays = new List<Texture2DArray>();
public bool existingTextureArraysFoldout;
public int existingTextureArraysSize;
public bool textureArraysPropsFoldout;
public TextureArrayUserSettings existingArraysProps;
public int choiceColorSpace = 0; //non linear
#endregion ALTER TEXTURE ARRAYS
#region INSPECTOR DRAWER VARS
public bool preserveBorders;
public bool preserveUVSeams;
public bool preserveUVFoldover;
public bool useEdgeSort = false;
public bool recalculateNormals;
public int maxIterations = 100;
public float aggressiveness = 7;
public bool regardCurvature = false;
public bool considerChildren;
public bool isPreservationActive;
public float sphereDiameter = 0.5f;
public Vector3 oldSphereScale;
public float reductionStrength;
public bool reductionPending;
public GameObject prevFeasibleTarget;
public bool runOnThreads;
public int triangleCount;
[SerializeField]
public UnityEngine.Object lastDrawer;
public bool foldoutAutoLOD;
public bool foldoutBatchFew;
public bool foldoutAutoLODMultiple;
public Vector3 objPositionPrevFrame;
public Vector3 objScalePrevFrame;
public bool considerChildrenBatchFew = true;
public string autoLODSavePath = "";
public bool foldoutAdditionalOpts;
public bool generateUV2LODs;
public bool copyParentStaticFlags;
public bool copyParentTag;
public bool copyParentLayer;
public bool createAsChildren;
public bool removeLODBackupComponent;
public bool generateUV2batchfew;
public bool removeMaterialLinksComponent;
public bool clearBlendshapesComplete;
public bool clearBlendshapesNormals;
public bool clearBlendshapesTangents;
public bool isPlainSkin = false;
#endregion INSPECTOR DRAWER VARS
}
}
#endif